Fluid full width grid in container - css

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;
}

Related

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>

Is it possible to draw vertical separators in the interior gaps of a CSS grid of varying columns?

I want to have a responsive grid of elements of variable length. The grid should fill the available width of the containing element, with the number of columns varying depending on the width of the container. This is straightforward to achieve using CSS grids; however, I don't know how to add a vertical border between columns (i.e., only in the interior column gaps). The below simple demo manages to achieve a vertical border in the event that there are three columns:
https://codepen.io/yowzadave/pen/OYPvLd?editors=1100
html, body {
box-sizing: border-box
}
.container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(24rem, 1fr));
grid-column-gap: 0.5rem;
}
.item {
border-right: 1px solid black;
padding-right: 0.5rem;
}
.item:nth-child(3n) {
border-right: none;
padding-right: 0;
}
.box {
background-color: pink;
height: 2rem;
margin: 0.5rem;
}
<html>
<body>
<div class="container">
<div class="item"><div class="box"></div></div>
<div class="item"><div class="box"></div></div>
<div class="item"><div class="box"></div></div>
<div class="item"><div class="box"></div></div>
<div class="item"><div class="box"></div></div>
<div class="item"><div class="box"></div></div>
</div>
</body>
</html>
...but in the event that the browser is wider or narrower, the borders will be misplaced. Is there a way to correctly place the borders at all browser widths?
You can use pseudo element on all the grid item where you will simply have overlap and be sure to cover all the gaps:
html,
body {
margin: 0;
}
.container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
grid-column-gap: 0.5rem;
overflow:hidden; /* Hide the overflow */
position:relative;
}
.item {
box-sizing: border-box;
position:relative;
}
.item:before {
content:"";
position:absolute;
top:0;
right:-0.25rem; /* Half the gap */
height:100vh; /* Big height*/
width:1px;
background:#000;
}
.box {
background-color: pink;
height: 2rem;
margin: 0.5rem;
}
<div class="container">
<div class="item">
<div class="box"></div>
</div>
<div class="item">
<div class="box"></div>
</div>
<div class="item">
<div class="box"></div>
</div>
<div class="item">
<div class="box"></div>
</div>
<div class="item">
<div class="box"></div>
</div>
<div class="item">
<div class="box"></div>
</div>
</div>

Fixed Row using Flexbox Grid

I am using flexboxgrid css library (www.flexboxgrid.com) and I want to achive my first row to be fixed and stays the full width of the container.
I am currently ending up in the first row being fixed but not full width. Here is what I did so far:
HTML:
<div class="Wrapper">
<div class="row center-xs middle-xs fixedHeader">
<div class="col-xs-12 col-sm-12 col-md-7 col-lg-7">
<div class="box">
<h3>Fixed Header</h3>
</div>
</div>
</div>
<div class="row center-xs middle-xs normalContent">
<div class="col-xs-12 col-sm-12 col-md-7 col-lg-7">
<div class="box">
<h3>normal content</h3>
</div>
</div>
</div>
</div>
CSS:
.Wrapper{
max-width: 1520px;
margin: 0 auto;
padding: 80px 40px;
}
.fixedHeader {
background-color: red;
position: fixed;
}
.normalContent{
min-height: 900px;
background-color:green;
}
I have also done a jsFiddle for this. Any idea what am I doing wrong ?
You need to add a width attribute to your "fixedHeader" class. I use the calc css function to make it 100% minus the padding in your "Wrapper" class.
.Wrapper{
max-width: 1520px;
margin: 0 auto;
padding: 80px 40px;
}
.fixedHeader {
background-color: red;
position: fixed;
width: calc(100% - 80px);
}
.normalContent{
min-height: 900px;
background-color:green;
}
See http://caniuse.com/#search=calc for calc() compatibility
You are using position:fixed that's why you are not getting the 100% width.
Add the width as well to your .fixedHeader
.fixedHeader {
background-color: red;
position: fixed;
width: 100%;
}

Centre 3 columns within container but allow

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>

css header layout width 3 divs

I am trying to create a header with 3 divs: one is aligned left, one is aligned right and the other is in the center.
the page is for example 1200px
the black,red and yellow rectangles are 960px and centered in the page.
elements in the black rectangle are added to the left,
elements in the yellwo rectangle are added to the right,
and the elements in the red tectangle are centered.
This is a good general case study for header of a site
This will solve your issue
<div class="header" style="width:1200px;">
<div style="width:40%;float:left;" class='black-one'>
<div style='float:left;'>Some content</div>
<div style="clear:both"></div>
</div>
<div style="width:20%;float:left;" class='red-one'>
<div style="margin:10px auto;text-align:center">Some content</div>
<div style="clear:both"></div>
</div>
<div style="width:40%;float:left;" class='yellow-one'>
<div style='float:right;text-align:right;'>Some content</div>
<div style="clear:both"></div>
</div>
<div style="clear:both"></div>
</div>
I wrote an article on this a while back here is my code...
<div id="mainContent">
<div id="col1">
Column 1
</div>
<div id="col2">
Column 2
</div>
<div id="col3">
Column 3
</div>
<div id="clearance" style="clear:both;"></div>
</div>
And here is the CSS for it....
#mainContent {
width: 1000px;
margin-right: auto;
margin-left: auto;
text-align: center;
}
#col1 {
margin: 10px;
float: left;
width: 300px;
}
#col2 {
margin: 10px;
float: left;
width: 300px;
}
#col3 {
margin: 10px;
float: left;
width: 300px;
}
Hope this helps... Phillip Dews
Try this..
<style>
.header { margin: 0px auto; width: 1200px; }
.floatt { float: left; margin-right: 5px;}
.black-one { width: 40%;}
.red-one { width: 20%;}
.yellow-one { width: 40%;}
.clear { clear: both;}
</style>
<div class="header">
<div class='black-one floatt'>
Some content
</div>
<div class='red-one floatt'>
Some content
</div>
<div class='yellow-one floatt'>
Some content
</div>
<div class="clear"></div>
</div>

Resources