This question already has answers here:
First-child full-width in Flexbox
(4 answers)
Closed 5 years ago.
I'm trying to create a kind of sub-grid which looks like this:
The first element should be full width and the rest have to be in the same line (same width each one) no matter how many items are present.
My attempt:
HTML
<div class="flex-container">
<div class="flex-item">I'm the biggest!</div>
<div class="flex-item"></div>
<div class="flex-item"></div>
<div class="flex-item"></div>
<div class="flex-item"></div>
<div class="flex-item"></div>
<div class="flex-item"></div>
</div>
CSS
.flex-container {
display: flex;
flex-wrap: wrap;
}
.flex-container .flex-item {
flex: 1;
}
.flex-container .flex-item:first-child {
width: 100%;
}
I'm a newbie in flex, so, in my newbie abstraction, in theory this should work, but it doesn't. It makes all the .flex-item being in the same line with the same width (which I want to happen but only with the :not(:first-child) flex dudes).
This will try to keep all your subordinate items on one row.
See notes in CSS
.flex-container {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
}
.flex-container .flex-item {
background-color: #d94a6a;
flex: 1 1 0; /* for 2nd line to not wrap */
margin: 0 1px;
overflow: hidden; /* for 2nd line to not wrap */
min-height: 75px;
text-align: center;
-webkit-box-shadow: 4px 4px 7px 0px rgba(50, 50, 50, 0.5);
-moz-box-shadow: 4px 4px 7px 0px rgba(50, 50, 50, 0.5);
box-shadow: 4px 4px 7px 0px rgba(50, 50, 50, 0.5);
}
.flex-container .flex-item:nth-child(1) {
background-color: #3b5bb2;
flex-basis: 100%; /* make first take full width */
min-height: 400px;
margin-bottom: 20px;
}
<div class="flex-container">
<div class="flex-item">I'm the biggest!</div>
<div class="flex-item">#2</div>
<div class="flex-item">#3</div>
<div class="flex-item">#4</div>
<div class="flex-item">#5</div>
<div class="flex-item">#6</div>
<div class="flex-item">#7</div>
</div>
Related
This question already has answers here:
How to add 1px margin to a flex item that is flex: 0 0 25%?
(4 answers)
Closed 9 months ago.
I would like to set 3 items per row. I tried something like that but, now I have 2 items per row because of margin and border. How should i implement this to have always 3 items per row
.App {
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.parent {
width: 600px;
display: flex;
flex-wrap: wrap;
}
.item {
display: flex;
justify-content: center;
align-items: center;
border: 1px solid #000;
margin: 5px;
width: 33%;
}
<div className="App">
<div className="parent">
<div className="item">1</div>
<div className="item">2</div>
<div className="item">3</div>
<div className="item">4</div>
<div className="item">5</div>
<div className="item">6</div>
<div className="item">7</div>
<div className="item">8</div>
<div className="item">9</div>
<div className="item">10</div>
</div>
</div>
);
You can use width: calc(100%/3 - 12px); on .item.
The 100%/3 will do 3 in a row. Then the -12px accounts for margin: 5px both sides = 10px. Then the same with border. 1px on either side affecting the width gives you 2px. For a total of 12px.
Note: you can use box-sizing: border-box; on .item to avoid having to use the 1px on either side of the border in the calculation.
.App {
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
}
.parent {
width: 600px;
display: flex;
flex-wrap: wrap;
}
.item {
display: flex;
justify-content: center;
align-items: center;
border: 1px solid #000;
margin: 5px;
width: calc(100%/3 - 12px);
/*box-sizing: border-box; - would make the calc -10px instead of -12px*/
}
<div class="App">
<div class="parent">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
</div>
</div>
You can try setting flex-basis:33% on the item element instead of width
.item {
display: flex;
justify-content: center;
align-items: center;
border: 1px solid #000;
margin: 5px;
flex-basis: 33%;
}
You have to keep in mind that a margin and border expands the size of the div. In your scenario, you have set the div to be 33%, which means the 3 divs in total occupy 99% of the parents width. The remaining 1% is not enough for all the margins and borders.
What I suggest is put the div size to around 30% , or use padding instead of margin .
This question already has answers here:
How to disable equal height columns in Flexbox?
(4 answers)
Closed 2 years ago.
I've been trying to find the correct answer for a while but didn't really know the right words to look for.
Example
Expected Example
I'm currently having trouble where the children containers are being set to the height of the parent (which is currently defined by a child).
Code
<div class='wrapper'>
<div class='container'>
Line 1<br>Line 2
</div>
<div class='container'>
Line 1
</div>
</div>
.wrapper {
display: flex;
}
.container {
color: white;
padding: 8px;
background: black;
border: 1px solid red;
display: inline-flex;
border-radius: 12px;
width: 100%;
}
JSFiddle
You could do either:
Add align-items: flex-start to the parent .wrapper definition
Add align-self: flex-start to the child .container definition
.wrapper {
display: flex;
align-items: flex-start;
}
.container {
color: white;
padding: 8px;
background: black;
border: 1px solid red;
display: inline-flex;
border-radius: 12px;
width: 100%;
}
<div class='wrapper'>
<div class='container'>
Line 1<br>Line 2
</div>
<div class='container'>
Line 1
</div>
</div>
From CSS tricks, align-items:
The align-items property defines the default behavior for how items are laid out along the cross axis (perpendicular to the main axis).
Also from CSS tricks, align-self:
align-self will affect the specific child of a flex element
use height:max-content; so u can achieve your aim, try snippet
.wrapper {
display: flex;
}
.container {
color: white;
padding: 8px;
background: black;
border: 1px solid red;
display: inline-flex;
border-radius: 12px;
width: 100%;
height: max-content;
}
<div class='wrapper'>
<div class='container'>
Line 1<br>Line 2
</div>
<div class='container'>
Line 1
</div>
</div>
I want to grow a container, but only when there is enough space to add a new element. Say my elements are 100px, this would mean the acceptable widths for my container would be 120, 230, 340, and so on.
Although I am demoing flex and margin-right: auto, I do not want the margins between the objects to be variable. I want only about 10 pixels between objects. I'm ok with there being a variable horizontal buffer for the container, if that is a solution.
I'm not certain I can do this using flex, so if there's a better way, I'd be grateful.
.container {
display: flex;
flex-wrap: wrap;
border: 3px solid rgb(0, 0, 0);
}
.panel {
height: 100px;
width: 100px;
border: 3px solid rgb(255, 0, 0);
margin: 10px 0px 0px 10px;
}
<div class="container">
<div class="panel"></div>
<div class="panel"></div>
<div class="panel"></div>
<div class="panel"></div>
</div>
There is the CSS code for the container element :
(added width: fit-content with a padding.)
.container {
display: flex;
flex-wrap: wrap;
width: fit-content;
border: 3px solid rgb(0, 0, 0);
padding : .5rem .5rem;
}
Trying to setup a css grid layout for my app navigation bar, but I am having trouble getting the justify-content property to work. Here I am trying to set it to center, but what I really want is a layout where the gutter space expands according to the space available.
Fiddle of the problem:
https://jsfiddle.net/epch33vx/
My html:
<div class='test'>
<div class='item'>
1
</div>
<div class='item'>
2
</div>
<div class='item'>
3
</div>
<div class='item'>
4
</div>
</div>
My stylesheet:
.test {
display: grid;
grid-template-columns: repeat(4, minmax(56px, 80px));
position: fixed;
bottom: 0;
left: 0;
width: 100%;
box-shadow: 0 0 2px rgba(0, 0, 0, 0.12), 0 2px 4px rgba(0, 0, 0, 0.24);
justify-items: center;
}
.item {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
min-height: 56px;
font-size: 14px;
text-decoration: none;
}
Just replace justify-items: center; with justify-content: space-between;
From the spec (bold mine):
Note that certain values of justify-content and align-content can
cause the tracks to be spaced apart (space-around, space-between,
space-evenly)
.test {
display: grid;
grid-template-columns: repeat(4, minmax(56px, 80px));
position: fixed;
bottom: 0;
left: 0;
width: 100%;
box-shadow: 0 0 2px rgba(0, 0, 0, 0.12), 0 2px 4px rgba(0, 0, 0, 0.24);
justify-content: space-between;
}
.item {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
min-height: 56px;
font-size: 14px;
text-decoration: none;
}
<div class='test'>
<div class='item'>
1
</div>
<div class='item'>
2
</div>
<div class='item'>
3
</div>
<div class='item'>
4
</div>
</div>
Updated fiddle
I would say that display: flex;
justify-content: center;
align-items: center;
flex-direction: column; should go into test class.
I would like a column of divs, of any number, each with width 100% and height 100% of their parent div, so one is visible initially, and the others overflow the parent downwards. I've set the divs to have flex: 0 0 100%;, inside a parent div with display: flex and flex-direction: column to achieve this.
The parent div is itself of unknown height, so it is also a child of a display: flex and flex-direction: column, set to flex: 1 0 0 to take remaining space in its container.
In Firefox the output is as I would like it:
However, not in Chrome:
How can I achieve the Firefox style in Chrome, without Javascript?
You can see this in action at http://plnkr.co/edit/WnAcmwAPnFaAhqqtwhLL?p=preview, as well as the corresponding version with flex-direction: row, which works consistently in both Firefox and Chrome.
For reference, the full CSS
.wrapper {
display: flex;
flex-direction: column;
height: 150px;
width: 200px;
border: 4px solid green;
margin-bottom: 20px;
}
.column-parent {
flex: 1 0 0;
display: flex;
flex-direction: column;
border: 2px solid blue;
}
.column-child {
flex: 0 0 100%;
border: 2px solid red;
}
and HTML
<div class="wrapper">
<p>Some content of unknown size</p>
<div class="column-parent">
<div class="column-child">
Should be inside green
</div>
<div class="column-child">
Should be outside green
</div>
</div>
</div>
This seems to be a bug with Chrome. Similar to the ones reported here (issue 428049) and perhaps related to (issue 346275).
This says:
- Browsers are supposed to resolve percentages on the flex item's child, *if* its flex-basis is definite.
- Gecko is *always* resolving percentages regardless of the flex-basis.
- Chrome is *never* resolving percentages, regardless of the flex-basis.
Summarily, Chrome is not resolving percent heights on flex-item's child (even if the child itself is a flex-item), while all other browsers do.
This can be demonstrated in the below snippet: (Fiddle here)
* { box-sizing: border-box; margin: 0; padding: 0; }
div.wrap {
height: 120px; width: 240px; margin: 0px 12px;
border: 1px solid blue; float: left;
display: flex; flex-direction: column;
}
div.parent {
flex: 0 0 100%;
border: 1px solid green;
display: flex; flex-direction: column;
}
div.item {
flex: 0 0 100%;
border: 1px solid red;
}
<div class="wrap">
<div class="item">a</div>
<div class="item">b</div>
<div class="item">c</div>
</div>
<div class="wrap">
<div class="parent">
<div class="item">a</div>
<div class="item">b</div>
<div class="item">c</div>
</div>
</div>
The second div should show the same behaviour as the first one. Other browsers (IE11, Edge, FF39) show it correctly. Chrome fails here and does not resolve div.item correctly. It needs a fixed height on its parent, without which it uses min-content as its height and thus does not overflow.
Whereas, in the first div, the div.items are correctly resolved and overflow accordingly. This is because there is a fixed height on the parent (i.e. div.wrap)
Possible Solution:
As a workaround, if you are sure to have only two elements (p and div) inside your wrapper, then you could give them a 50% height. You have to provide a height:50% to your .column-parent. Chrome needs a fixed height on parent as demonstrated above.
Then everything will work as you need to.
Demo Fiddle: http://jsfiddle.net/abhitalks/kqncm65n/
Relevant CSS:
.wrapper > p { flex: 0 0 50%; } /* this can be on flex-basis */
.column-parent {
flex: 1 0 auto; height: 50%; /* but, this needs to be fixed height */
display: flex; flex-direction: column;
border: 2px solid blue;
}
.column-child {
flex: 0 0 100%; /* this flex-basis is then enough */
border: 2px solid red;
}
PS: There also seem to be differences in the way jsfiddle and plnkr render. I don't know why, but sometimes I get different results!
As stated in Abhitalks response, there is a bug (or a different interpretation of the standard) in the way Chrome handles the height attribute here.
I have found a hack that is working both in Chrome FF and IE
The only issue is that you ned to have as many rules as posible children there are.
The trick is to set the flex-direction to row, set the flex-basis (that is now the width) to 100%, and then translate the elements
.container {
border: solid 2px blue;
height: 200px;
width: 200px;
display: flex;
flex-direction: column;
position: relative;
}
.filler {
border: solid 1px black;
flex: 0 0 80px;
background-color: lightgreen;
transition: flex 1s;
}
.container:hover .filler {
flex: 0 0 40px;
}
.test {
border: solid 1px red;
flex: 1 0 25px;
display: flex;
flex-direction: row;
position: relative;
}
.child {
background-color: rgba(200, 0, 0, 0.26);
flex: 0 0 100%;
}
.child:nth-child(2) {
background-color: rgba(255, 255, 0, 0.48);
transform: translateX(-100%) translateY(100%);
}
.child:nth-child(3) {
background-color: rgba(173, 216, 230, 0.28);
transform: translateX(-200%) translateY(200%);
}
<div class="container">
<div class="filler"></div>
<div class="filler"></div>
<div class="test">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
</div>
</div>
If there could be another child, you would need a nth-child(4) rule, and so on
I have added an hover effect to check how the size adapts
My previous answer is a hack that exploits a particular setup of the layout wanted.
An alternate way, more general, of getting around this Chrome bug is to use an intermediate element in the layout, and set this element size using top: 0px and bottom: 0px. (instead of height: 100%) There is still a bug in the way Chrome handles the calculus, that needs a fake animation to make it adjust properly
.container {
border: solid 2px blue;
height: 200px;
width: 200px;
display: flex;
flex-direction: column;
position: relative;
}
.filler {
border: solid 1px black;
flex: 0 0 94px;
background-color: lightgreen;
transition: 1s;
}
.container:hover .filler {
flex: 0 0 50px;
}
.test {
border: solid 1px red;
flex: 1 0 25px;
display: flex;
flex-direction: row;
position: relative;
}
#-webkit-keyframes adjust2 {
0% {flex-basis: 100%;}
100% {flex-basis: 100.1%;}
}
.child {
background-color: rgba(200, 0, 0, 0.26);
width: 100%;
height: 100%;
flex: 1 0 100%;
-webkit-animation: adjust2 1s infinite; /* only needed for webkit bug */
}
.intermediate {
width: 100%;
position: absolute;
top: 0px;
bottom: 0px;
display: flex;
flex-direction: column;
}
.child:nth-child(n+2) {
background-color: rgba(255, 255, 0, 0.48);
}
.child:nth-child(n+3) {
background-color: rgba(173, 216, 230, 0.28);
}
<div class="container">
<div class="filler"></div>
<div class="test">
<div class="intermediate">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</div>
</div>
What about adding 100% to the container:
.column-parent {
flex: 1 0 100%;
}
And flex-grow to 1 in the contained element without adjusting the flex basis:
.column-child {
flex: 1 0 0;
}
Here's how it would look: http://plnkr.co/edit/H25NQxLtbi65oaltNVax?p=preview