Styling layout with flexbox - css

How should I style using flexbox to get a layout like this? I'm hesitant to use grid as it has limited support on IE11. I'd love to make it possible to add more or less small divs and not to add more containers for small divs
HTML for the layout is looking like this:Desired Layout image
.container {
display: flex;
}
.large {
height: 200px width: 150px;
border: 1px solid black;
}
.small {
height: 100px;
width: 150px;
border: 1px solid black;
}
<div class="container">
<div class="large">1</div>
<div class="small">2</div>
<div class="small">3</div>
<div class="small">4</div>
<div class="small">5</div>
</div>

I would use css-grid over flexbox, here is an example:
tutorial here, current specifications here
.container {
display: grid;
grid-template-columns: 60px 60px 60px 60px 60px;
grid-template-rows: 30px 30px;
grid-auto-flow: column;
}
.container div {
border:1px solid gold;
}
.item-a {
grid-column: 1;
grid-row: 1 / 3;
}
<section class="container">
<div class="item-a">item-a</div>
<div class="item-b">item-b</div>
<div class="item-c">item-c</div>
<div class="item-d">item-d</div>
<div class="item-e">item-e</div>
</section>

I added a parent div for .small divs and I used margin and flex-wrap. But I suggest use grid for you.
.container {
display: flex;
}
.large {
height: 220px;
width: 150px;
border: 1px solid black;
box-sizing:border-box;
margin:10px;
}
.small_cont {
width:340px;
display:flex;
height:200px;
flex-wrap:wrap;
}
.small {
height: 100px;
width: 150px;
border: 1px solid black;
box-sizing:border-box;
margin:10px;
}
<div class="container">
<div class="large">1</div>
<div class="small_cont">
<div class="small">2</div>
<div class="small">3</div>
<div class="small">4</div>
<div class="small">5</div>
</div>
</div>

Related

Padding still causes width of container to change with border box box sizing

I have a flex div container with three child divs. For some reason adding padding left to the first container - #testcont causes the other containers to move. Unless I'm not looking carefully, why is this happening when the box-sizing is border box?
Here is my code: https://jsfiddle.net/templar9901/2g3whovc/2/
<div id = "three">
<div id = "testcont">
blahh1
</div>
<div>
blahh2
</div>
<div>
blahh3
</div>
</div>
//CSS
*{
box-sizing: border-box;
}
#three{
border: solid;
display: flex;
justify-content: space-around;
}
#three div{
border: 2px solid red;
/* flex-grow: 1; */
}
#testcont{
padding-left: 20%;
}
Because they all share the same parent container.
You should put each group with a different style separately like this.
<div id = "main-container">
<div class="container1">
<div class="btn" id = "testcont">
blahh1
</div>
</div>
<div class="container2">
<div class="btn">
blahh2
</div>
<div class="btn">
blahh3
</div>
</div>
</div>
CSS
*{
box-sizing: border-box;
}
#main-container{
border: 1px solid;
display: flex;
justify-content: space-around;
}
.container1 {
width: 40%;
border: 1px solid blue;
}
.container2 {
width: 60%;
border: 1px solid green;
display: flex;
}
.btn{
border: 2px solid red;
padding: 0 5px;
/* flex-grow: 1; */
}
#testcont{
padding-left: 30%;
}
hope this help.

how can I make a grid using flexbox with a fixed spacing between child divs?

the idea is not to use any framework.
Basically I am using a .row class that will contain my grid and it will be flexbox. Each child will have a class that will say how much width it will occupy (something like the bootstrap grid), so for example:
.col1: {width: 25%};
.col2: {width: 50%};
.col3: {width: 75%};
.col4: {width: 100%};
if I put 4 divs with the class .col1 they should be in the same line because they would occupy 25% of the container (.row), but if I put one more div it would go down to another line because it exceeded 100% of the container.
|| col1 | col1 | col1 | col1 || //4 divs each div with 25% in the same .row.
|| col1 | col1 | col1 | col1 || //5 divs each div with 25% in the same .row.
|| col1 | |
|| col3 | col1 || //2 divs 1 of 75% other of 25% .row.
The problem is that my grid should always contain a space of 20px between each element, something like the following image:
I don't know how to put a space between each div and still comply with the above rules, if I have 4 divs with class .col1 they must be in the same line (including the space).
If I have a div with .col3 and another with .col1 it should be:
how can I do it?
I tried this: (gap between the divs exceeds the percentages of the div's width,this is the reason why the divs in this example are not in the same line even though there are 4 divs that should occupy 100% of the .row since each one would have 25% of the width.
)
html,body{
padding:0px;
margin:0px;
box-sizing: border-box
}
.row{
display:flex;
flex-wrap:wrap;
border:1px solid red;
width:100%;
gap: 20px;
}
.row div{
border:1px solid blue;
background:yellow;
font-size:24px;
text-align:center;
height:100px;
}
.col1{
width:25%;
}
.col2{
width:50%;
}
.col3{
width:75%;
}
.col4{
width:100%;
}
<div class="row">
<div class="col1">col1</div>
<div class="col1">col1</div>
<div class="col1">col1</div>
<div class="col1">col1</div>
</div>
how can fix it? or is there any better way to achieve this?
NOTE: I need no spaces at the beginning of the first div of the .row, nor at the end of the last div of the .row
Add some CSS variables to make the calculation you want:
body {
padding: 0px;
}
.row {
--g:20px;
display: flex;
flex-wrap: wrap;
border: 1px solid red;
gap: var(--g);
}
.col1 {width:calc((100% - 3*var(--g))*1/4 + 0*var(--g))}
.col2 {width:calc((100% - 3*var(--g))*2/4 + 1*var(--g))}
.col3 {width:calc((100% - 3*var(--g))*3/4 + 2*var(--g))}
.col4 {width:calc((100% - 3*var(--g))*4/4 + 3*var(--g))}
.row div {
border: 1px solid blue;
box-sizing: border-box;
background: yellow;
font-size: 24px;
text-align: center;
height: 100px;
}
<div class="row">
<div class="col1">col1</div>
<div class="col1">col1</div>
<div class="col1">col1</div>
<div class="col1">col1</div>
<div class="col1">col1</div>
<div class="col2">col2</div>
<div class="col1">col1</div>
<div class="col3">col3</div>
<div class="col1">col1</div>
<div class="col2">col2</div>
<div class="col2">col2</div>
<div class="col4">col4</div>
</div>
You might use calc():
* {
padding: 0px;
margin: 0px;
box-sizing: border-box
}
section {
width: 100%;
overflow: hidden;
border: 1px solid red
}
.row {
display: flex;
flex-wrap: wrap;
width: calc(100% + 20px);
margin-left: -10px;
}
.row div {
border: 1px solid blue;
background: yellow;
font-size: 24px;
text-align: center;
height: 50px;
margin: 0 auto;
}
.col1 {
min-width: calc(25% - 20px);
}
.col2 {
min-width: calc(50% - 20px);
}
.col3 {
min-width: calc(75% - 20px);
}
.col4 {
min-width: calc(100% - 20px);
}
<section>
<div class="row">
<div class="col1">col1</div>
<div class="col1">col1</div>
<div class="col1">col1</div>
<div class="col1">col1</div>
<div class="col1">col1</div>
<div class="col2">col2</div>
<div class="col1">col1</div>
<div class="col1">col1</div>
<div class="col3">col3</div>
<div class="col4">col4</div>
</div>
</section>
I think you should add one more child tag to contain the content of a col.
html,
body {
padding: 0px;
margin: 0px;
box-sizing: border-box
}
.row {
display: flex;
flex-wrap: wrap;
border: 1px solid red;
width: 100%;
/* gap: 20px; */
}
.row div {
/* border: 1px solid blue; */
font-size: 24px;
text-align: center;
height: 100px;
}
.col1 {
width: 25%;
}
.col2 {
width: 50%;
}
.col3 {
width: 75%;
}
.col4 {
width: 100%;
}
.col1>* {
background: yellow;
margin: 0 20px;
}
.col3>* {
background: yellow;
margin: 0 20px;
}
<body>
<div class="row">
<div class="col1">
<div>col1</div>
</div>
<div class="col1">
<div>col1</div>
</div>
<div class="col1">
<div>col1</div>
</div>
<div class="col1">
<div>col1</div>
</div>
<div class="col3">
<div>col3</div>
</div>
<div class="col1">
<div>col1</div>
</div>
</div>
</body>
the pixels that you are using to separate each div are part of the % of the all that div, as you say, exceeds the percentages of the div's width.
I mean, if that space between cols is mandatory, you need to do 25% - 20px, and so on for each col

Using flex i need to create a horizontal div and underneath div in vertical [duplicate]

This question already has an answer here:
How to exclude the first item in a flexbox wrap?
(1 answer)
Closed 2 years ago.
Using Flex how can i create a layout , that has main parent div (container , display:flex) set.
The div1 to be in horizontal
div 2 and div 3 to be vertical as seen in the image.
I am new to flex and still learning
You can Achieve this even without flex, But if you need to do all the 3 div with flex then you can use this.
Here we put all the div in one contaner called main. And then we use flex property to make it a row. and then use flex-wrap to break apart. and then we give 100% to the first div as you wanted that in full width
HTML
<div id="main">
<div style="background-color:coral;" id="one">RED</div>
<div style="background-color:lightblue;">BLUE</div>
<div style="background-color:lightgreen;">Green div with more content.</div>
</div>
CSS
#main {
width: 100%;
height: 300px;
border: 1px solid black;
display: flex;
flex-wrap:wrap;
}
div{
width:200px;
}
#one{
flex:100%;
}
You can do something like this:
#MainDiv {
border: 1px solid black;
display: flex;
flex-direction: column;
height: 500px;
width: 700px;
}
.Column {
border: 1px solid red;
height: 30px;
margin: 10px;
}
.Rows {
display: flex;
flex-direction: row;
height: 450px;
width: 650px;
border: 1px solid teal;
margin: 10px;
}
.row {
height: 400px;
width: 300px;
border: 1px solid red;
margin: 10px;
}
<div id="MainDiv">
<div class="Column">Horizontal </div>
<div class="Rows">
<div class="row">Vertical Left</div>
<div class="row">Vertical Right</div>
</div>
</div>
You can use flex: 1 without specifying size in pixel for each box
.row {
display: flex;
flex-direction: row;
width: 100%;
}
.col {
border: 1px solid red;
flex: 1;
}
<div class="row">
<div class="col">One</div>
</div>
<div class="row">
<div class="col">Two</div>
<div class="col">Three</div>
</div>

Flex to wrap with fixed size

The title doesn't describe my problem but did'nt find a better one.
So, I have one div containing 3 divs, I wan't two columns with div A in the first one and div B and C in the second, on large screens and one only column on small screens. I could use #media but I think flex can do it without.
This is what I tried:
<div id="container">
<div>
</div>
<div>
</div>
<div>
</div>
</div>
#container
{
border:1px solid #aaa;
height:300px;
width:500px;
max-width:100%;
display:flex;
flex-flow:column;
flex-wrap:wrap;
}
#container > div
{
border:1px solid #aaa;
margin:2px;
flex-grow:1;
min-width:200px;
height:10px;
}
#container > div:first-of-type
{
height:300px;
flex-grow:1;
}
Demo
I fixed the height to force the content to go to 2 columns but then it never goes to onel colum.
Just remove the last css element:
https://jsfiddle.net/j2brc3t3/1/
Live example:
#container
{
border:1px solid #aaa;
height:300px;
width:500px;
max-width:100%;
display:flex;
flex-flow:column;
flex-wrap:wrap;
}
#container > div
{
border:1px solid #aaa;
margin:2px;
flex-grow:1;
min-width:200px;
height:10px;
}
<div id="container">
<div>
</div>
<div>
</div>
<div>
</div>
</div>
#container {
border: 1px solid #aaa;
width: 600px;
max-width: 100%;
display: flex;
text-align: center;
flex-wrap: wrap;
}
#in1 {
background: #a1d;
margin: 5px;
height: 200px;
flex-grow: 1;
min-width: 200px;
}
#in2 {
flex-grow: 1;
display: flex;
flex-flow: column;
min-width: 200px;
}
#in2>div {
background: #e25;
flex-grow: 1;
}
/*
#in2 div:first-child {
margin-bottom: 5px;
}
*/
<div id="container">
<div id="in1">div1</div>
<div id="in2">
<div>div2</div>
<div>div3</div>
</div>
</div>
I found a near solution:
Demo
It answer my question but show a new issue with margins, I need no margin around the container, just 5px between the inner divs, if someone has the perfect solution...

Wrap container around inline divs

Here is my problem. I have inline-block divs inside another div.
.timeEvents {
width: 100%;
overflow: hidden;
text-align: center;
}
.timeline {
border: 1px solid;
}
.events1, .events2 {
border: 1px solid;
}
.ev1, .ev3 {
border: 1px solid red;
}
.ev2 {
margin: 0 auto;
border: 1px solid red;
display: inline-block;
}
.mDiv {
display: inline-block;
padding-left: 12px;
padding-right: 12px;
border: 1px solid blue;
}
<div class="timeEvents">
<div class="events1">
<div class="ev1">Data Field 1</div>
</div>
<div class="timeline">
<div class="ev2">
<div class="mDiv">5</div>
<div class="mDiv">10</div>
<div class="mDiv">15</div>
<div class="mDiv">20</div>
<div class="mDiv">25</div>
</div>
</div>
<div class="events2">
<div class="ev3">Data Field 2</div>
</div>
</div>
I want the .ev2 to be wrapped around its children which are inline. Then, the two data fields, respectively .ev1 and .ev3 placed above and below, should have the same width as .ev2. Which means that all divs with a red border (in my JSFiddle) should have the same width (dynamic, I don't know it) and that width should not be 100% as it's in the jsFiddle example: https://jsfiddle.net/mzjqw2wx/17/.
EDIT - I updated my fiddle. I don't want to lose the outside 100% divs, I want to align the three red sections to have the same width, the page and the outside divs all remain 100%. The tip to use inline-block on the wrapper was great, it did what I wanted with the middle one. I wanted to align all red containers and I did it with jQuery.
You need to also set display: inline-block; for the common wrapper (and give text-align: center to its parent)
body { text-align: center; }
.timeEvents {
display: inline-block;
margin: 0 auto;
}
JSFiddle
Result:
That's pretty easy to implement using Flexbox.
Just assign display: flex; to .ev2 and flex-grow: 1; to the the .myDiv class.
You can see it in the following code:
.timeEvents {
width: 100%;
overflow: hidden;
text-align: center;
}
.timeline {
border: 1px solid;
}
.events1, .events2 {
border: 1px solid;
}
.ev1, .ev3 {
border: 1px solid red;
}
.ev2 {
margin: 0 auto;
border: 1px solid red;
display: flex;
}
.mDiv {
display: inline-block;
padding-left: 12px;
padding-right: 12px;
border: 1px solid blue;
flex-grow: 1;
}
<div class="timeEvents">
<div class="events1">
<div class="ev1">Data Field 1</div>
</div>
<div class="timeline">
<div class="ev2">
<div class="mDiv">5</div>
<div class="mDiv">10</div>
<div class="mDiv">15</div>
<div class="mDiv">20</div>
<div class="mDiv">25</div>
</div>
</div>
<div class="events2">
<div class="ev3">Data Field 2</div>
</div>
</div>
Check out CSS-Trick's Complete guide to Flexbox for more information.
Use display:table to timeEvents and remove width:100% will make as per your expected.
.timeEvents {
display: table;
overflow: hidden;
text-align: center;
}
Fiddle

Resources