I want the children of the div fill its width.
now am using a code like this:
.parent {
width: 100%;
display: inline-block;
height: 120px;
background: #000;
padding: 10px;
box-sizing: border-box;
}
.child {
display: inline-block;
margin-left: 1%;
width: 31.4%;
height: 100px;
background: #ddd;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
and it's working for 3 boxes, but what I want is that - Even if the box count is one or two i want them to fill the parent width. I want to achieve this using only CSS.
You can achieve this using flexbox properties.
Here is a demo:
.parent {
display: flex;
height: 120px;
background: #000;
padding: 10px;
box-sizing: border-box;
}
.child {
height: 100px;
background: #ddd;
flex: 1;
margin: 0 10px;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
<div class="parent">
<div class="child"></div>
<div class="child"></div>
</div>
<div class="parent">
<div class="child"></div>
</div>
You can make the parent a flexbox and define for the children to grow when there is space available. I removed the width for .child.
.parent {
width: 100%;
display: inline-flex;
height: 120px;
background: #000;
padding: 10px;
box-sizing: border-box;
}
.child {
display: inline-block;
margin-left: 1%;
height: 100px;
background: #ddd;
flex-grow: 1;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
<div class="parent">
<div class="child"></div>
<div class="child"></div>
</div>
<div class="parent">
<div class="child"></div>
</div>
Use flexbox:
.parent {
width: 100%;
display: flex;
background: #000;
padding: 10px;
box-sizing: border-box;
margin-bottom: 15px;
}
.child {
flex: 1;
margin: 0 10px;
height: 100px;
background: #ddd;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
<div class="parent">
<div class="child"></div>
<div class="child"></div>
</div>
<div class="parent">
<div class="child"></div>
</div>
You are using width like 30% which is fixed for every element, so every time you create other element
its size is fixed and added at the end of residing elements and after total width is more than that of parent container it overflows.
Instead use flex-box.
.parent {
width: 100%;
display:flex;
height: 120px;
background: #000;
padding: 10px;
box-sizing: border-box;
}
.child {
flex:1;
margin-left: 1%;
width: 31.4%;
height: 100px;
background: #ddd;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
You can use flexbox to achieve this.
The demo below shows how it works with more child nodes and also with nodes with zero height.
I have also changed the margin property for the child items to work properly with flexbox.
.parent {
width: 100%;
display: inline-flex; /*used inline-flex here, to mirrior your inline-block setting, but you can use flex*/
height: 120px;
background: #000;
padding: 10px;
box-sizing: border-box;
}
.child {
display: inline-flex;
flex-grow: 1;
margin: 0 1%;
height: 100px;
background: #ddd;
}
/*demontration for zero-height child elements*/
.child:nth-child(2) {
height: 0;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<!-- remove these to test with different child count --->
<div class="child"></div>
<div class="child"></div>
</div>
here is the code below , i think this may help for you
.parent {
display: -webkit-flex; /* Safari */
display: flex;
height: 120px;
background: #000;
padding: 10px;
box-sizing: border-box;
}
.child {
-webkit-flex: 1; /* Safari 6.1+ */
-ms-flex: 1; /* IE 10 */
flex: 1;
margin-left: 1%;
background: #ddd;
}
<div class="parent">
<div class="child"></div>
</div><br>
<div class="parent">
<div class="child"></div>
<div class="child"></div>
</div><br>
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
If its for a fixed number of child then you can always calculate the width of child by (parent-width / No. of child) and fix that width to child. But if your code has dynamic child the you can use flex property of display.
Just add display:flex to your .parent and flex:1 to your .child.
However this has few issues with browser compatibility and is not advisable if you are targeting old browsers. Even there are few cases of elements which does not support flex property.Refer to this link for information. I would suggest write a javascript code for calculating the width of child and add the property.Else its good to go with flex!
Hope this helped you! You can study more about flexbox here.
Related
This question already has answers here:
Make container shrink-to-fit child elements as they wrap
(4 answers)
Closed last year.
Is there a responsive way (not using min-width) to minimise a width of a parent when children do not take the entire space that parent has, given that the width of the children is hard set?
Problem
Solution
.parent {
display: flex;
flex-wrap: wrap;
border: 1px solid grey;
}
.child {
background: lightgrey;
height: 50px;
width: 40vw;
margin: 10px;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
Try to add width: fit-content; to your .parent
UPD: try this approach (using grid system)
.parent {
display: grid;
border: 1px solid grey;
grid-template-columns: repeat(2, minmax(min-content, max-content));
width: fit-content;
}
.child {
background: lightgrey;
height: 50px;
width: 40vw;
margin: 10px;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
</div>
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
<div class="parent">
<div class="child" style="width: 30vw"></div>
<div class="child" style="width: 33vw"></div>
<div class="child" style="width: 27vw"></div>
<div class="child" style="width: 35vw"></div>
</div>
I've got two columns in a parent container of 600px width. The children’s character length dictates the column width (weighted split). However, as both columns become increasingly similar in their width, a balanced (50/50 split) layout should be preferred, illustrated below.
Is it possible to achieve this kind of layout in flexbox or grid, without javascript? I imagine determining string length and switching css properties according to a threshold would be an option that I don't want to go down.
My intention isn't to create a single type of split but rather to make the layout respect both splits conditionally.
.container {
outline: 1px solid red;
width: 100%;
height: 60px;
display: flex;
}
.child {
padding: 0.5px;
outline: 1px solid black;
display: grid;
place-content: center;
}
.grow {
flex-grow: 1; /* flexible split */
}
.balanced {
width: 100%; /* 50-50 split */
}
<div class="container">
<div class="child grow">
asdasdasdasd
</div>
<div class="child grow">
asdaassdasdasdsdasdasd
</div>
</div>
<div class="container">
<div class="child balanced">
asdasdasdasd
</div>
<div class="child balanced">
asdaassdasdasdsdasdasd
</div>
</div>
Just add a maximum width?
.container {
outline: 1px solid red;
width: 100%;
height: 60px;
display: flex;
}
.child {
padding: 0.5px;
outline: 1px solid black;
display: grid;
place-content: center;
}
.grow {
flex-grow: 1;
max-width:50%;
}
.balanced {
width: 100%;
/* 50-50 split */
}
<div class="container">
<div class="child grow">
asdasdasdasd
</div>
<div class="child grow">
asdaassdasdasdsdasdasd
</div>
</div>
<div class="container">
<div class="child balanced">
asdasdasdasd
</div>
<div class="child balanced">
asdaassdasdasdsdasdasd
</div>
</div>
Isn't flex-grow alone solving directly your problem?
See the snippet:
.container {
outline: 1px solid red;
width: 100%;
height: 60px;
display: flex;
}
.child {
padding: 0.5px;
outline: 1px solid black;
display: grid;
flex-grow: 1; /* flexible split */
place-content: center;
}
<div class="container">
<div class="child">
asdasd
</div>
<div class="child">
asdaassdasdasdsdasdasd
</div>
</div>
<div class="container">
<div class="child">
asdasdasdasd
</div>
<div class="child">
asdaassdasdasdsdasdasd
</div>
</div>
<div class="container">
<div class="child">
asdaassdasdasdsdasdasd
</div>
<div class="child">
asdaassdasdasdsdasdasd
</div>
</div>
In the meantime I found the answer.
Setting flex-basis enforces a 50/50 split when column width is similar. The unequal split is respected by setting flex-grow and flex-shrink.
.parent {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 50%;
padding-right: 1em;
padding-left: 1em;
}
I am attempting to divide a set of icons by the year they were created, but I only want the divider line to extend to the edges of the content (the blue squares).
The issue here is that I want this to work regardless of viewport size, as to keep it responsive. How can I make this divider element act the way I am describing?
#parent{
position: relative;
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.child{
height: 250px;
width: 250px;
margin: 10px;
background-color: blue;
}
.divider{
width: 100%;
border-bottom: 2px solid red;
text-align: center;
}
<div id="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="divider">2020</div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
You could try wrapping a year into a container and assigning a border-bottom to that container. Due to the containers being direct children of the parent, and not the child anymore, I made changed the main axis of the flex-flow to compensate.
Edit: Included an :after selector to include the year at each border.
#parent {
position: relative;
display: flex;
flex-flow: column nowrap;
align-items: center;
}
.child {
height: 250px;
width: 250px;
margin: 10px;
background-color: blue;
justify-content: space-between;
}
.child-container {
border-bottom: 1px solid red;
}
.child-container:after {
content: '2020';
}
<div id="parent">
<div class="child-container">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
<div class="child-container">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</div>
When scrolling down the .parent div you should see its red background at the bottom due to the padding-bottom. This works in Chrome, but not in Safari and Firefox.
.container {
display: flex;
width: 200px;
height: 500px;
}
.parent {
display: flex;
flex-direction: column;
background: red;
padding-top: 20px;
padding-bottom: 20px;
overflow: auto;
flex: 1;
}
.child {
flex: 1 0 100px;
background: green;
border: 1px solid blue;
}
<div class="container">
<div class="parent">
<div class="child">
child
</div>
<div class="child">
child
</div>
<div class="child">
child
</div>
<div class="child">
child
</div>
<div class="child">
child
</div>
<div class="child">
child
</div>
<div class="child">
child
</div>
</div>
</div>
codepen: http://codepen.io/anon/pen/NpvJPY
Edit: This question is different from the proposed duplicate because it regards a problem with a fixed padding in pixels, as opposed to the percentage padding in the duplicate.
I'm not exactly sure why the padding-bottom fails in Firefox and Safari. It may have something to do with the container being over-constrained. But that's just a guess.
What I am more certain about, however, is a reliable, cross-browser solution. Pseudo-elements on a flex container are rendered as flex items. So instead of padding use ::before and ::after.
.container {
display: flex;
width: 200px;
height: 500px;
}
.parent {
display: flex;
flex-direction: column;
background: red;
/* padding-top: 20px; */
/* padding-bottom: 20px; */
overflow: auto;
flex: 1;
}
/* NEW */
.parent::before,
.parent::after {
flex: 0 0 20px;
content: '';
}
.child {
flex: 1 0 100px;
background: green;
border: 1px solid blue;
}
<div class="container">
<div class="parent">
<div class="child">child</div>
<div class="child">child</div>
<div class="child">child</div>
<div class="child">child</div>
<div class="child">child</div>
<div class="child">child</div>
<div class="child">child</div>
</div>
</div>
revised codepen
I know when using display: flex you can use margin-left: auto on a child and that pushes it all the way to the right but if you do that with multiple children you end up with evenly distributed margins instead of them all sitting to the far left.
Assuming HTML is uneditable
I know you could create a class like so: http://jsfiddle.net/L943ckr5/
.flex {
display: flex;
}
.child {
height: 30px;
width: 50px;
background-color: red;
}
.child:nth-child(even) {
background-color: blue;
}
.end {
margin-left: auto;
}
<div class="flex">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child end"></div>
<div class="child"></div>
<div class="child"></div>
</div>
But is there a way to individually target the last 3 children and 'float' them right but with Flex obviously. Something along the lines of justify-self: flex-end;
In case of you're being OK with using jQuery to tackle this problem, I got solution to wrap every group of 3 child divs into a parent div, and spread them as a column.
This might get helpful if you don't know the exact number of child divs in your markup.
JSFiddle
HTML:
<div class="flex">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
CSS:
.flex {
display: flex;
justify-content:space-between;
}
.flex-container {
display:flex;
}
.child {
height: 30px;
width: 50px;
background-color: red;
}
.child:nth-child(even) {
background-color: blue;
}
jQuery:
var arr = $(".child"),
templ = '<div class="flex-container"></div>';
for(var i = 0; i < arr.length; i+=3) {
arr.slice(i, i+3).wrapAll(templ);
}
Do you mean like this:
.child:nth-last-child(3) {
margin-left: auto;
}
.flex {
display: flex;
}
.child {
height: 30px;
width: 50px;
background-color: red;
}
.child:nth-child(even) {
background-color: blue;
}
.child:nth-last-child(3) {
margin-left: auto;
}
<div class="flex">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
As far as I know there is no property to add to each of the elements that would achieve the same effect.