Can this be achieved with a flexbox or grid? - css

I am trying to achieve this effect using flexbox and without media query. Can i get this effect with the grid?
desktop -> tablet -> mobile:

Sure, You can achieve something like this using flexbox. I believe the easiest way to do this would be having a main container for all three blocks, and a sub-container for the first two blocks that'll move. Here's a working example:
.container, .subcontainer {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.container {
width: 100%;
}
.subcontainer {
width: 50%;
min-width: 125px;
}
#block1, #block2, #block3 {
margin-bottom: 50px;
width: 100px;
height: 100px;
}
#block1 {
background-color: peru;
margin-right: 25px;
}
#block2 {
background-color: darkorange;
margin-right: -50px;
}
#block3 {
background-color: orange;
height: unset;
min-height: 100px;
display: flex;
align-items: stretch;
}
<div class="container">
<div class="subcontainer">
<div id="block1"></div>
<div id="block2"></div>
</div>
<div id="block3"></div>
</div>

Here's an alternate solution, using flexbox, grid, and #media queries. Easier to use flexbox on the 1st and 3rd picture because they have one dimension/direction. With the 2nd picture it's easier to use grid as it's more of a 2D layout that requires you to mind the horizontal and vertical of elements to set up properly.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
display: flex;
justify-content: space-evenly;
height: 80vh;
margin: 3rem;
}
.container>div {
border: 1px solid black;
display: grid;
width: 10rem;
place-content: center;
}
#media screen and (max-width: 992px) {
.container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
gap: 1rem;
}
.b {
grid-column: 1/2;
grid-row: 2/3;
}
.c {
grid-column: 2/3;
grid-row: span 2;
}
}
#media screen and (max-width: 600px) {
.container {
display: flex;
flex-direction: column;
}
.container>div {
flex: 1;
}
}
<div class="container">
<div class="a">A</div>
<div class="b">B</div>
<div class="c">C</div>
</div>

Related

How to create a 4 section flex layout which collapses only on screen resize

I am attempting to create a flex layout as illustrated in the screenshots below.
This is what the page will look like on normal screen size (before resize).
Page resize will look like this, with sidebar over main content.
The code I have written appears to work. However, how can I make the sidebar fall under the main content when screen size is reduced?
CSS:
div#container{
display: flex;
flex-direction: column;
}
main{
display: flex;
background-color: #ccc;
flex-wrap: wrap;
height: 80vh;
}
header {
background-color: #F2F2F2;
height: 100px;
}
footer {
background-color: #F2F2F2;
height: 100px;
}
section#content {
background-color: #D62121;
width: auto;
flex-grow: 1;
}
section#sidebar {
background-color: green;
width: 350px;
}
/* For demo purposes */
#media (max-width: 815px) {
section#sidebar {
width: 100%;
}
main{
flex-wrap: wrap;
}
}
HTML
<div id="container">
<header>
<p>HEADER</p>
</header>
<main>
<section id="content">
<div>
<!-- Add long text here and main content falls below sidebar.-->
</div>
</section>
<section id="sidebar">
<h1>Sidebar</h1>
</section>
</main>
<footer>
<p>FOOTER</p>
</footer>
</div>
div#container{
display: flex;
flex-wrap: wrap;
}
main{
display: flex;
flex-wrap: wrap;
height: 80vh;
margin-bottom: 30px;
}
header {
background-color: coral;
height: 100px;
flex: 0 0 100%;
max-width: 100%;
margin-bottom: 30px;
}
footer {
background-color: coral;
height: 100px;
}
main {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
width: 100%;
}
section#content {
background-color: #D62121;
flex: 0 0 calc(100% - 380px);
max-width: calc(100% - 380px);
}
section#sidebar {
background-color: green;
width: 350px;
flex: 0 0 350px;
}
footer {
flex: 0 0 100%;
max-width: 100%;
}
/* For demo purposes */
#media (max-width: 815px) {
section#content,
section#sidebar{
flex: 0 0 100%;
max-width: 100%;
width: 100%;
}
section#content {
order: 2;
}
section#sidebar{
order: 1;
margin-bottom: 30px;
}
}
The layout breakage was because of the flex-grow:1. After setting its flex-grow to the initial value and setting its maximum width flex: 0 0 calc(100% - 380px) in it. The layout will stop expanding to its max-width and text will break accordingly.
I hope this will help. Please review in js fiddle.
https://jsfiddle.net/chhiring90/8xmvy4ur/

Grid template with an inner overflow-x element break layout in chrome but not in firefox [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I’m having issues tracking the problem of a div that contains a big table (a green div in the fiddle). I want this div to have a working overflow-x: auto.
On firefox I don’t see any issues, the table container when the windows is too little adds a scrollbar, with chrome or opera the browser scrollbar is shown alongside the block scrollbar, and the page content extends over the window length.
If I don’t use Grid, all browsers show the same behavior, with a scrollbar only in the parent block of the table.
Here's a fiddle and snippet:
.content {
grid-area: content;
display: block;
max-width: 1200px;
margin: 0 auto;
width: 100%;
box-sizing: border-box;
min-height: calc(100vh - 6em);
overflow: hidden;
}
.footer {
grid-area: footer;
height: 3em;
background-color: grey;
}
.sidemenu {
height: 3em;
grid-area: sidemenu;
background-color: grey;
}
.wrapper {
display: grid;
grid-template-areas:
"sidemenu"
"content"
"footer";
}
.big {
background-color: green;
width: 2980px;
height: 20px;
}
.blockWrapper { overflow-x: auto; }
#media (min-width: 500px) {
.wrapper {
grid-template-columns: 3em 1fr;
grid-template-areas:
"sidemenu content"
"sidemenu footer";
}
.sidemenu { height: 100%; }
}
<div class="wrapper">
<div class="sidemenu"></div>
<div class="content">
<div class="blockWrapper">
<div class="big"></div>
</div>
</div>
<div class="footer"></div>
</div>
You can remove width: 100% and margin: 0 auto on .content to get the same behavior in Chrome & Firefox - see demo below:
.content {
grid-area: content;
display: block;
max-width: 1200px;
/*margin: 0 auto;
width: 100%;*/
box-sizing: border-box;
min-height: calc(100vh - 6em);
overflow: hidden;
}
.footer {
grid-area: footer;
height: 3em;
background-color: grey;
}
.sidemenu {
height: 3em;
grid-area: sidemenu;
background-color: grey;
}
.wrapper {
display: grid;
grid-template-areas: "sidemenu" "content" "footer";
}
.big {
background-color: green;
width: 2980px;
height: 20px;
}
.blockWrapper {
overflow-x: auto;
}
#media (min-width: 500px) {
.wrapper {
grid-template-columns: 3em 1fr;
grid-template-areas: "sidemenu content" "sidemenu footer";
}
.sidemenu {
height: 100%;
}
}
<div class="wrapper">
<div class="sidemenu"></div>
<div class="content">
<div class="blockWrapper">
<div class="big"></div>
</div>
</div>
<div class="footer"></div>
</div>
Another fix can be to specify grid-template-columns: 100% and grid-template-columns: 3em calc(100% - 3em) for the media query above 500px - see demo below:
.content {
grid-area: content;
display: block;
max-width: 1200px;
margin: 0 auto;
width: 100%;
box-sizing: border-box;
min-height: calc(100vh - 6em);
overflow: hidden;
}
.footer {
grid-area: footer;
height: 3em;
background-color: grey;
}
.sidemenu {
height: 3em;
grid-area: sidemenu;
background-color: grey;
}
.wrapper {
display: grid;
grid-template-areas: "sidemenu" "content" "footer";
grid-template-columns: 100%; /* added */
}
.big {
background-color: green;
width: 2980px;
height: 20px;
}
.blockWrapper {
overflow-x: auto;
}
#media (min-width: 500px) {
.wrapper {
grid-template-columns: 3em 1fr;
grid-template-areas: "sidemenu content" "sidemenu footer";
grid-template-columns: 3em calc(100% - 3em); /* added */
}
.sidemenu {
height: 100%;
}
}
<div class="wrapper">
<div class="sidemenu"></div>
<div class="content">
<div class="blockWrapper">
<div class="big"></div>
</div>
</div>
<div class="footer"></div>
</div>

Responsive flexbox layout: reordering elements

I'm trying to achieve a responsive layout as outlined in the image, left side would be mobile, right side desktop. This would be relatively easy using flexbox if I could set a fixed height for the wrapper, but because the content is dynamic this is not possible.
Another solution would be to use position absolute on element C, but this seems very hacky, I'm hoping to find a more elegant solution.
Here is a framework for the code:
.wrapper {
display: flex;
flex-direction: column;
}
#media(min-width: 800px) {
.wrapper {
flex-direction: row;
flex-wrap: wrap;
}
}
.section {
display: flex;
justify-content: center;
align-items: center;
font-size: 36px;
}
.section-a {
background: green;
height: 200px;
}
#media(min-width: 800px) {
.section-a {
flex-basis: 33%;
}
}
.section-b {
background: yellow;
height: 400px;
}
#media(min-width: 800px) {
.section-b {
flex-basis: 66%;
}
}
.section-c {
background: blue;
height: 200px;
}
#media(min-width: 800px) {
.section-c {
flex-basis: 33%;
}
}
<div class="wrapper">
<div class="section section-a">A</div>
<div class="section section-b">B</div>
<div class="section section-c">C</div>
</div>
Thanks for the help!
You can achieve this by using grid. I have simplified your code and removed unwanted css
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: 1fr 1fr;
grid-template-rows: [row1-start] auto [row2-start] auto [row2-end];
}
.section {
padding: 20px;
display: flex;
align-items: center;
}
.section-a {
height: 50px;
background-color: green;
}
.section-b {
grid-row: row1-start / row2-end;
grid-column: 2/-1;
background-color: yellow;
}
.section-c {
background-color: blue;
height: 180px;
}
<div class="wrapper">
<div class="section section-a">A</div>
<div class="section section-b">B</div>
<div class="section section-c">C</div>
</div>
Working fiddle here
Edit: it's an attempt, as I misunderstood OP's question. My answer has a given .wrapper height.
A solution using flex with the following properties:
order
flex-basis
This code applies for your desktop layout:
.wrapper {
width: 100%;
height: 100vh;
display: flex;
flex-flow: column wrap;
}
.section {
width: 50%;
border: 1px solid black;
box-sizing: border-box;
}
.section-a {
height: 25vh; // for example
}
.section-b {
order: 3;
flex-basis: 100%;
}
.section-c {
flex-grow: 1;
}
<div class="wrapper">
<div class="section section-a">A</div>
<div class="section section-b">B</div>
<div class="section section-c">C</div>
</div>

What's the best way to achieve this layout with flexbox?

I have 4 columns and three rows. The last tile is two rows high.
I'm working on a code that looks like this:
.gridContainer {
display: flex;
flex-wrap: wrap;
}
.gridItems {
width: 290px;
height: 350px;
margin: 0 5px 10px;
border-radius: 4px;
}
.gridItemsTall {
width: 290px;
height: 710px;
margin: 0 5px 10px;
border-radius: 4px;
}
A good way to achieve this with flexbox it's by using a combinaison of flex-direction: column, flex-wrap: wrap and max-height.
He is an update of your CSS :
.gridContainer {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-content: flex-start;
max-height: 1080px; // box height *3 + margin-bottom*3 -> 350*3 + 10*3
}
.gridItems {
width: 290px;
height: 350px;
margin: 0 5px 10px;
border-radius: 4px;
background-color: #ccc;
}
.gridItemsTall {
height: 710px;
}
And on the following link, you can find a live example : https://jsfiddle.net/julienvanderkluft/dkdfy7gb/
Note that the height of .gridContainer can be manipulate by JavaScript for more flexibility.
You can use CSS Grid layout instead of flexbox in this case. You just need to set grid-row: span 2 on element you want to take two rows.
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 50px;
grid-gap: 10px;
width: 200px;
}
.box {
background: #aaa;
}
.large {
grid-row: span 2;
}
<div class="grid">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box large"></div>
<div class="box"></div>
<div class="box"></div>
</div>

Writing flexbox code for 2-column and 3-column on desktop and mobile (wrap)

I'm having a real hard time figuring out this CSS flexbox solution. Basically there are 2 issues, one with a 2-column and another with a 3-column layout.
2-Column:
This, I think, may be pretty straightforward:
3-Column:
This is probably a bit more advanced:
The container class is, well, .container, and the children are just .left, .right, and .middle. Not sure if it's relevant, but the width of .container is 100% of viewport. I should probably add that using Bootstrap is not possible, due to reasons out of my control.
Here's how you do it for the three columns. I'm only adding that, because it's a bit more tricky:
.container {
display: flex;
flex-wrap: wrap;
flex-direction: row;
justify-content: flex-start;
align-items: stretch;
}
.left {
order: 1;
background: red;
flex-basis: 100%;
height: 300px
}
.middle {
order: 3;
background: green;
flex-basis: 100%;
height: 300px;
}
.right {
order: 2;
background: yellow;
flex-basis: 100%;
height: 300px;
}
#media screen and (min-width:600px) {
.container {
flex-wrap: nowrap;
}
.left {
flex-basis: 200px;
order: 1;
}
.middle {
flex-basis: 1;
order: 2;
}
.right {
flex-basis: 200px;
order: 3;
}
}
<div class="container">
<div class="left"></div>
<div class="middle"></div>
<div class="right"></div>
</div>
And the fiddle http://jsfiddle.net/2touox81/
As you can see, you can set column order for flex items.
Hope this helps.
I will assume desktop means screen wider than 600px, mobile less.
The 2-column layout is very simple:
body {
display: flex; /* Magic begins */
flex-wrap: wrap; /* Allow multiple lines */
}
#left, #right {
flex: 1 300px; /* Initial width of 600px/2
Grow to fill remaining space */
min-width: 0; /* No minimal width */
}
body {
display: flex;
flex-wrap: wrap;
text-align: center;
font-weight: bold;
}
#left, #right {
flex: 1 300px;
min-width: 0;
background: #f55;
padding: 15px 0;
}
#right {
background: #57f;
}
<div id="left">Left</div>
<div id="right">Right</div>
The 3-column is only a bit more complex:
body {
display: flex; /* Magic begins */
}
#left, #right, #middle {
min-width: 0; /* No minimal width */
}
#left, #right {
flex-basis: 200px; /* Initial width */
}
#middle {
flex: 1; /* Take up remaining space */
}
#media screen and (max-width: 600px) { /* Mobile */
body {
flex-direction: column; /* Column layout */
}
#left, #right {
flex-basis: auto; /* Unset previous 200px */
}
#middle {
order: 1; /* Move to the end */
}
}
body {
display: flex;
text-align: center;
font-weight: bold;
}
#left, #right, #middle {
min-width: 0;
padding: 15px 0;
}
#left, #right {
flex-basis: 200px;
background: #f55;
}
#right {
background: #57f;
}
#middle {
flex: 1;
background: #5f6;
}
#media screen and (max-width: 600px) {
body {
flex-direction: column;
}
#left, #right {
flex-basis: auto;
}
#middle {
order: 1;
}
}
<div id="left">Left</div>
<div id="middle">Middle</div>
<div id="right">Right</div>

Resources