Rearrange divs in certain way when resizing - html

I have created flexbox to rearrange the boxes. Here is the demo code
The problem is that when I resize for smaller screen, I want to insert B between A and C.
How can I achieve that ? Thanks in advance.

grid is the grid-system you may need for this kind of layout.
here is a short example
/* let make a grid of 2 columns */
.main {
display: grid;
grid-template-columns: 1fr 1fr;
margin: 20px;
}
/* b should span through 2 rows */
.b {
grid-row: span 2;
}
/* clear the grid system on small screen */
#media (max-width: 639px) {
.main {
display: block;
}
}
/* original styling for bg */
.a {
background-color: red;
}
.b {
background-color: green;
}
.c {
background-color: blue;
}
<div class="main">
<div class="a">A - I have some content</div>
<div class="b">B - I have some content</div>
<div class="c">C - I have some content</div>
</div>
As you can see, you may need little HTML and CSS to get this organized. Mind to set your media query in last position so it is not overridden ;)
see https://css-tricks.com/snippets/css/complete-guide-grid/ to dig further into grid

Here a solution that gather all classes a b and c in one container:
html code :
<div class="main">
<div class="container-1">
<div class="a">A - I have some content</div>
<div class="b">B - I have some content</div>
<div class="c">C - I have some content</div>
</div>
</div>
CSS code :
.a {
background-color: red;
height: 20px;
}
.b {
background-color: green;
height: 30px;
}
.c {
background-color: blue;
height: 20px;
}
.container-1 div{
width: 45%;
display: inline-block;
}
#media (max-width: 639px) {
.container-1 div {
width: 100%;
display: block;
}
}

I think it would be easier using grid instead flex:
HTML
<div class="main">
<div class="a">a</div>
<div class="b">b</div>
<div class="c">c</div>
</div>
CSS
.main {
display: grid; /* If you don't wanna add a gap between blocks, put this attribute into the media query */
gap: 1rem; /* To add a gap between blocks */
}
.a {
background: red;
}
.b {
background: green;
}
.c {
background: blue;
}
#media (min-width: 768px) {
.main {
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
}
.a {
grid-area: 1 / 1 / 2 / 2;
}
.b {
grid-area: 1 / 2 / 3 / 3;
}
.c {
grid-area: 2 / 1 / 3 / 2;
}
}

Related

How can I make a div span 2 rows [duplicate]

This question already has answers here:
Make a div span two rows in a grid
(2 answers)
Closed 6 months ago.
I am trying to do exactly this:
Where my mark up is:
<div>
<div>A</div>
<div>B</div>
<div>C</div>
</div>
Is this possible with grid, bootstrap or flex? Without changing the order of elements?
I think it has a lot of way to do.
And one of that way is using grid. then use grid-template for solve this question
.container {
display: grid;
grid-template:
"a b"
"c b";
}
.a {
grid-area: a;
background: red;
}
.b {
grid-area: b;
background: blue;
}
.c {
grid-area: c;
background: green;
}
or using grid-area
.container {
display: grid;
}
.a {
background: red;
}
.b {
grid-area: 1 / 2 / 3;
background: blue;
}
.c {
background: green;
}
.wrapper {
height: 300px;
display: grid;
grid-template-columns: repeat(2, 50%);
}
.wrapper div {
color: white;
display: flex;
align-items: center;
justify-content: center;
}
.wrapper div:nth-child(1) {
background-color: green;
}
.wrapper div:nth-child(2) {
grid-row: 2 span;
background-color: blue;
}
.wrapper div:nth-child(3) {
background-color: red;
}
<div class="wrapper">
<div>A</div>
<div>B</div>
<div>C</div>
</div>
Is that something you wanted to achive ? "Grid" is kind of made for this kind of situations.
As for bootstrap - last version uses "flex" as default.
Using one more div will be the solution, do the following.
Hope it is useful.
https://codepen.io/Olmedo12/pen/WNdGOMB
HTML
<div class="container">
<div class="subcontainer">
<div class="box blue">BOX 1</div>
<div class="box red">BOX 3</div>
</div>
<div class="box green">
Box 2
</div>
<div>
CSS
.container {
display: flex;
}
.box {
width: 60px;
height: auto;
}
.red {
background: red;
}
.blue {
background: blue;
}
.green {
background: green;
}

CSS 2 column layout with variable heights and different mobile/desktop layout

Is there a way to build a 2 column layout so that each item can be of dynamic height and has a different order on mobile as can be seen here?
I've been able to partially achieve this by wrapping the left and right elements in their own div however, there doesn't seem to be a way to re-order elements outside of their column div for the mobile view:
.parent {
display: grid;
grid-template: auto / 1fr;
}
.column-left {
align-self: start;
grid-row: 1;
}
.column-right {
align-self: start;
grid-row: 2;
}
#media screen and (min-width: 600px) {
.parent {
grid-template: auto / repeat(8, 1fr);
}
.column-left {
grid-column: 1 / 4;
grid-row: auto;
}
.column-right {
grid-column: 4 / 9;
grid-row: auto;
}
}
.item {
border: 1px solid black;
text-align: center;
font-size: 2rem;
}
#item-a {
height: 140px;
background-color: red;
}
#item-b {
height: 180px;
background-color: blue;
}
#item-c {
height: 220px;
background-color: green;
}
#item-d {
height: 300px;
background-color: yellow;
}
<div class="parent">
<div class="column-left">
<div id="item-a" class="item">A</div>
<div id="item-b" class="item">B</div>
</div>
<div class="column-right">
<div id="item-c" class="item">C</div>
<div id="item-d" class="item">D</div>
</div>
</div>
I don't think you can in css since you want to move an item from a column to an other one. It may not be what you want but this is the solution I found :
.container{
width:100px;
display:flex;
flex-wrap: wrap;
border:1px solid black;
}
#a{
background-color:red;
}
#b{
background-color:blue;
}
#c{
background-color:green;
}
#d{
background-color:yellow;
}
.item{
width:100%;
text-align:center;
}
.order-1{
order: 1;
}
.order-2{
order: 2;
}
.order-3{
order: 3;
}
.order-4{
order: 4;
}
#media screen and (min-width: 992px) {
.item{
width:50%;
}
.order-lg-1{
order: 1;
}
.order-lg-2{
order: 2;
}
.order-lg-3{
order: 3;
}
.order-lg-4{
order: 4;
}
}
<div class="container">
<div id="a" class="item order-2 order-lg-1">A <br> A</div>
<div id="b" class="item order-3 order-lg-3">B</div>
<div id="c" class="item order-1 order-lg-2">C <br> C <br> C</div>
<div id="d" class="item order-4 order-lg-4">D <br> D </div>
</div>
Check Full Page to see the difference in larger screen

Making grid responsive

Any idea of how to make this grid responsive?
This is my CSS:
body {
margin: 40px;
}
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: 100px 100px 100px;
background-color: #fff;
color: #444;
}
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 20px;
font-size: 150%;
}
.a {
grid-column: 1 / 3;
grid-row: 1;
}
.b {
grid-column: 3 ;
grid-row: 1 / 3;
}
.c {
grid-column: 1 ;
grid-row: 2 ;
}
.d {
grid-column: 2;
grid-row: 2;
}
HTML
<div class="wrapper">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box c">C</div>
<div class="box d">D</div>
</div>
I tried this code:
#media only screen and (max-width:500px) {
.box {
width: 100%;
margin-right: 0;
float: none;
margin-bottom: 20px !important;
}
What's the best way to accomplish this?
I agree with #Petra that you need to use fr, but use a media query if you want to display them stacked on a mobile device. You could also just change the display to block. Make sure you add these after the initial CSS so that it isn't overridden.
#media screen and (max-width: 512px) {
.wrapper {
grid-template-columns: 1fr;
}
}
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: 1fr 1fr 1fr;
background-color: #fff;
color: #444;
}
ith CSS Grid Layout, we get a new flexible unit: the Fr unit. Fr is a fractional unit and 1fr is for 1 part of the available space.

CSS grid and responsive view

I just started learning the CSS grid today, and I can start seeing the point to use this awesome css classes. But one thing that really is confusing me, is how to reorganize the grid on mobile devices.
I made an example below here. That is working how it should on a desktop view. When the screen size is going below 991px. I would like the grid was looking like this:
But how should I control that using the CSS grid?
.wrapper {
display:grid;
grid-template-columns:1fr 2fr 1fr;
grid-auto-rows:minmax(100px,auto);
grid-gap:1em;
}
.wrapper > div {
background-color: #eee;
padding: 1em;
}
.wrapper > div:nth-child(odd) {
background-color: #ddd;
}
.box1 {
grid-column:1/3;
grid-row:1/3;
}
.box2 {
grid-column:3;
}
.box3 {
grid-column:3;
}
<div class="wrapper">
<div class="box box1">Box 1</div>
<div class="box box2">Box 2</div>
<div class="box box3">Box 3</div>
</div>
You should use #media and you need to make again adjustments for 991px.
.wrapper {
display:grid;
grid-template-columns:1fr 2fr 1fr;
grid-auto-rows:minmax(100px,auto);
grid-gap:1em;
}
.wrapper > div {
background-color: #eee;
padding: 1em;
}
.wrapper > div:nth-child(odd) {
background-color: #ddd;
}
.box1 {
grid-column:1/3;
grid-row:1/3;
}
.box2 {
grid-column:3;
}
.box3 {
grid-column:3;
}
#media screen and (max-width:991px){
.wrapper {
grid-template-columns:1fr 1fr;
}
.box1 {
grid-column:1/4;
grid-row:1/3;
}
.box2 {
grid-column:1/2;
}
.box3 {
grid-column:2/4;
}
}
<div class="wrapper">
<div class="box box1">Box 1</div>
<div class="box box2">Box 2</div>
<div class="box box3">Box 3</div>
</div>
You can use media queries with #media only screen and (max-width: 990px) -
you can use a two-column grid using grid-template-columns: 1fr 1fr for this view - see demo below:
.wrapper {
display: grid;
grid-template-columns: 1fr 2fr 1fr;
grid-auto-rows: minmax(100px, auto);
grid-gap: 1em;
}
.wrapper>div {
background-color: #eee;
padding: 1em;
}
.wrapper>div:nth-child(odd) {
background-color: #ddd;
}
.box1 {
grid-column: 1/3;
grid-row: 1/3;
}
.box2 {
grid-column: 3;
}
.box3 {
grid-column: 3;
}
#media only screen and (max-width: 990px) {
.wrapper {
grid-template-columns: 1fr 1fr;
}
.box1 {
grid-column: span 2; /* span the first row */
grid-row: 1; /* first row */
}
.box2 {
grid-column: 1; /* first column */
}
.box3 {
grid-column: 2; /* second column */
}
}
<div class="wrapper">
<div class="box box1">Box 1</div>
<div class="box box2">Box 2</div>
<div class="box box3">Box 3</div>
</div>

Equal height different aspect ratio boxes with CSS grid

I'm trying to create layout like this:
Orange blocks on the right side all have the same aspect ratio and thus height.
Blue block has different aspect ratio.
Height of blue block and summ of orange blocks should be equal, as shown on the image.
Is there a way to create such layout via CSS grid? I know that I can wrap orange items in a separate column element, but I'd like to avoid this. I also managed to create this layout when aspect ratio of each item is square, but no luck with this one...
Example on jsfiddle http://jsfiddle.net/fq974gov/
.grid {
display: grid;
grid-gap: 10px;
width: 200px;
}
.item-left {
background: lightblue;
padding-bottom: 120%;
}
.item-right {
background: tomato;
padding-bottom: 60%;
}
<div class="grid">
<div class="item-left"></div>
<div class="item-right"></div>
<div class="item-right"></div>
<div class="item-right"></div>
</div>
You can define template areas and control the ratio using grid-template-columns
.grid {
display: grid;
grid-template-areas:
"l1 r1"
"l1 r2"
"l1 r3";
grid-template-columns:3fr 2fr; /*adjust this as you like*/
grid-gap: 10px;
width: 200px;
animation:change 2s infinite alternate linear;
}
.item-left {
grid-area:l1;
background: lightblue;
/*padding-bottom: 120%; no more needed*/
}
.item-right {
background: tomato;
padding-bottom: 60%;
}
.item-right:nth-child(2) {
grid-area:r1;
}
.item-right:nth-child(3) {
grid-area:r2;
}
.item-right:nth-child(4) {
grid-area:r3;
}
#keyframes change{
to{width:300px;}
}
<div class="grid">
<div class="item-left"></div>
<div class="item-right"></div>
<div class="item-right"></div>
<div class="item-right"></div>
</div>
The code can be simplified like this:
.grid {
display: grid;
grid-template-areas:
"l r"
"l r"
"l r";
grid-template-columns:3fr 2fr; /*adjust this as you like*/
grid-gap: 10px;
width: 200px;
animation:change 2s infinite alternate linear;
}
.item-left {
grid-area:l;
background: lightblue;
}
.item-right {
background: tomato;
padding-bottom: 60%;
}
#keyframes change{
to{width:300px;}
}
<div class="grid">
<div class="item-left"></div>
<div class="item-right"></div>
<div class="item-right"></div>
<div class="item-right"></div>
</div>
This is working code for it.
Check it out on JSFiddle
<html>
<head>
<title>Grid View</title>
</head>
<style>
.grid {
display: grid;
grid-gap: 10px;
width: 500px;
grid-template-areas:
"a a b b"
"a a c c"
"a a d d"
;
}
.item-left {
background: lightblue;
padding-bottom: 120%;
grid-area: a;
}
.item-right {
background: tomato;
padding-bottom: 40%;
}
#grid_b {
grid-area: b;
}
#grid_c {
grid-area: c;
}
#grid_d {
grid-area: d;
}
</style>
<body>
<div class="grid">
<div id="grid_a" class="item-left"></div>
<div id="grid_b" class="item-right"></div>
<div id="grid_c" class="item-right"></div>
<div id="grid_d" class="item-right"></div>
</div>
</body>
</html>
At first, I suggest you to read more about grid layout. This link may help you.
And let's solve your problem. Every div item in your case is a grid item. So you should give them different styles. At first You should set grid-template-columns and grid-template-rows for container. After that for items, you should set grid-column-start, grid-column-end, grid-row-start, grid-row-end. Look at the above link about grid layout and try to solve it, This is my solution that may help you.
https://jsfiddle.net/sghgh1996/0cf39bm1/
HTML:
<div class="grid">
<div class="item-left">
</div>
<div class="item-right row1">
</div>
<div class="item-right row2">
</div>
<div class="item-right row3">
</div>
</div>
CSS:
.grid {
display: grid;
grid-gap: 10px;
width: 200px;
grid-template-columns: 50% 50%;
grid-template-rows: 33.333% 33.333% 33.333%;
}
.item-left {
background: lightblue;
padding-bottom: 120%;
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 1;
grid-row-end: 6;
}
.item-right {
background: tomato;
padding-bottom: 60%;
}
.row1{
grid-row-start: 1;
grid-row-end: 2;
}
.row2{
grid-row-start: 3;
grid-row-end: 4;
}
.row3{
grid-row-start: 5;
grid-row-end: 6;
}