Centre 3 columns within container but allow - css

I have a container that holds multiple divs, around 20. I want to put 3 divs on each line so it kind of looks something like this (with the divs just continuing to flow).
What's the best way to centre these columns without having them in some sort of parent div? I can center them if I used a div which held 3 columns each but with the system I'm using I cannot. Any ideas?

A simple example will be:
pure css you can use this one to control row:
.child:nth-child(3n+1) {
clear: both;
}
with width: calc((100% - 60px)/3); to get width dynamically.
.child {
background: white;
height: 40vh;
float: left;
margin: 0px 10px 10px 0px;
width: calc((100% - 60px)/3);
border: 5px solid black;
}
.child:nth-child(3n+1) {
clear: both;
}
.wrapper {
background: white;
border: 5px solid black;
display: inline-block;
width: calc(100% - 30px);
margin: 10px;
padding: 10px 0px 0px 10px;
}
<div class="wrapper">
<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 class="child"></div>
<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 class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>

The 'best' way IMO is to use flexbox. You say with no parent div but it has to have some kind of parent container div.
* {
box-sizing: border-box;
}
.container {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
max-width: 400px;
margin: 0 auto;
padding: 25px;
border: 2px solid black;
}
.box {
display: block;
height: 160px;
width: 100px;
margin-bottom: 25px;
border: 2px solid black;
}
<div class="container">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>

Related

Minimize flex wrap parent width [duplicate]

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>

Causing a flex-item to fill the entire practical width of a center-justified flexbox

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>

Flexbox space-between but center if one element

I've the following HTML and CSS.
<div class="container-box">
<div class="box"></div>
<div class="box"></div>
</div>
<div class="container-box">
<div class="box"></div>
</div>
.container-box {
width: 200px;
display: flex;
flex-direction: row;
justify-content: space-between;
background-color: red;
margin:50px;
}
.box {
background-color: #9009A0;
height: 50px;
width: 50px;
}
Which gives this layout:
The first layout for multiple items does what I expect, but how can I change the second to position the element in center as it only has one element?
See this codepen: https://codepen.io/dennismadsen/pen/oNvqjjV
For cases where you have one item in the container, you can use the :only-child pseudo-class.
Add this to your code:
.box:only-child {
margin: 0 auto;
}
.container-box {
width: 200px;
display: flex;
flex-direction: row;
justify-content: space-between;
background-color: red;
margin: 50px;
}
.box {
background-color: #9009A0;
height: 50px;
width: 50px;
}
.box:only-child {
margin: 0 auto;
}
<div class="container-box">
<div class="box"></div>
<div class="box"></div>
</div>
<div class="container-box">
<div class="box"></div>
</div>
In such cases, flex auto margins will override justify-content because:
§ 8.1. Aligning with auto
margins
Prior to alignment via justify-content and align-self, any
positive free space is distributed to auto margins in that dimension.
More about :only-child:
§ 6.6.5.10. :only-child
pseudo-class
The :only-child pseudo-class represents an element that has no
siblings. Same as :first-child:last-child or
:nth-child(1):nth-last-child(1), but with a lower specificity.
More about flex auto margins:
In CSS Flexbox, why are there no "justify-items" and "justify-self" properties?
Also, to spotlight some interesting flex behavior, if you were using space-around instead of space-between, you wouldn't need auto margins.
Flex item should align left, not center, when it wraps
For info, You could also use together :first-child and :last-child if you wanted to mind about very old browsers ;)
.container-box {
width: 200px;
display: flex;
flex-direction: row;
justify-content: space-between;
background-color: red;
margin: 50px;
}
.box {
background-color: #9009A0;
height: 50px;
width: 50px;
}
.container-box .box:first-child:last-child {
margin: 0 auto;
}
<div class="container-box">
<div class="box"></div>
<div class="box"></div>
</div>
<div class="container-box">
<div class="box"></div>
</div>
Here is a different idea with only margin:
.container-box {
width: 400px;
display: flex;
background-color: red;
margin: 30px;
}
.box {
background-color: #9009A0;
height: 50px;
width: 50px;
}
.box:first-child {
margin-right: auto;
}
.box:last-child {
margin-left: auto;
}
<div class="container-box">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
<div class="container-box">
<div class="box"></div>
<div class="box"></div>
</div>
<div class="container-box">
<div class="box"></div>
</div>
If you will have more than 3 elements you can add an extra rule
.container-box {
width: 400px;
display: flex;
background-color: red;
margin: 30px;
}
.box {
background-color: #9009A0;
height: 50px;
width: 50px;
}
.box:not(:last-child):not(:first-child) {
margin:auto;
}
.box:first-child {
margin-right: auto;
}
.box:last-child {
margin-left: auto;
}
<div class="container-box">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
<div class="container-box">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
<div class="container-box">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
<div class="container-box">
<div class="box"></div>
<div class="box"></div>
</div>
<div class="container-box">
<div class="box"></div>
</div>

Set the width of children to fill the parent

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.

Fluid full width grid in container

What is a simple, preferrably css-only, solution to achieve the following:
Have a grid of divs with fluid widths that always matches the with of the container, without having some space on one side due to the margin of the divs.
All boxes should be in one container.
Here is what i have: https://jsfiddle.net/5g0uwxtx/
<div id="container">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
#container{
width:100%;}
.box{
width: 32%;
height: 0;
padding-bottom: 32%;
float:left;
margin:0 1% 1% 0;
background-color:#CCC;}
I want each row of boxes to stretch exactly to the right side, without left over space.
Thanks!
There are a number of ways, but one of the more commonly seen is using a row based layout with first-child or last-child to control the margins, e.g.
http://codepen.io/anon/pen/MajyaG
<div id="container">
<div class="row cf">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
<div class="row cf">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
</div>
#container{
}
.box{
width: 32.5%;
height: 0;
padding-bottom: 32%;
float:left;
margin:0 1% 1% 0;
background-color:#CCC;
}
.cf:before,
.cf:after {
content: " "; /* 1 */
display: table; /* 2 */
}
.cf:after {
clear: both;
}
.row .box:last-child{
margin-right: 0;
}

Resources