Gutter between DIVs using negative margin breaks - css

I have the below code, which works fine. As you can see, it creates a gutter between the 3 green elements, which are children of the second out of three blue elements.
.container{
font-size: 0;
}
[class|="col"] {
display:inline-block;
vertical-align: top;
position:relative;
font-size:20px;
}
.col-1-3{
width:calc(100%/(3/1));
}
.col-2-3{
width:calc(100%/(3/2));
}
.col-1{
width:100%;
}
.children-has-gutters{
margin-left:-15px;
margin-right:-15px;
width: calc((100% / (3/1)) + 30px);
}
.children-has-gutters > div{
padding-left:15px;
padding-right:15px;
box-sizing: border-box;
}
.bg-blue{
background-color:#42a5f5;
color:#ffffff;
}
.bg-green{
background-color:#66bb6a;
color:#ffffff;
}
<div class="container">
<div class="col-1-3 bg-blue">blue left</div>
<div class="col-1-3 children-has-gutters" style="font-size:0px;">
<div class="col-1-3">
<div class="bg-green">green 1</div>
</div>
<div class="col-1-3">
<div class="bg-green">green 2</div>
</div>
<div class="col-1-3">
<div class="bg-green">green 3</div>
</div>
</div>
<div class="col-1-3 bg-blue">blue right</div>
</div>
In the below example, there is only one blue element, not three. And suddenly, the gutter between its green child elements doesnt work as expected. Sure, it has space in between, but it creates a horizontal scroller on the page, and the left most and right most side get the gutter as well, somehow seem like the negative margin doesnt work.
I would be grateful if someone could point out what breaks compared to the above code.
.container{
font-size: 0;
}
[class|="col"] {
display:inline-block;
vertical-align: top;
position:relative;
font-size:20px;
}
.col-1-3{
width:calc(100%/(3/1));
}
.col-2-3{
width:calc(100%/(3/2));
}
.col-1{
width:100%;
}
.children-has-gutters{
margin-left:-15px;
margin-right:-15px;
width: calc(100% + 30px);
}
.children-has-gutters > div{
padding-left:15px;
padding-right:15px;
box-sizing: border-box;
}
.bg-blue{
background-color:#42a5f5;
color:#ffffff;
}
.bg-green{
background-color:#66bb6a;
color:#ffffff;
}
<div class="container">
<div class="col-1 bg-blue children-has-gutters" style="font-size:0px;">
<div class="col-1-3">
<div class="bg-green">green 1</div>
</div>
<div class="col-1-3">
<div class="bg-green">green 2</div>
</div>
<div class="col-1-3">
<div class="bg-green">green 3</div>
</div>
</div>
</div>
So, color wise it should go: left edge of screen, green 1, blue gap, green 2, blue gap, green 3, right edge of screen.
This is just an example, the number of children can change, so its not always 3.
This question is a follow up question to an old question of mine, as I now found this bug and cant figure out the problem:
old question here >>
Requirements: I dont want to add new div elements, and I dont want to change to flexbox.

It's an ugly hack, but you could put overflow hidden on your container to get rid of the blue on the edges:
.container{
font-size: 0;
overflow: hidden;
}

I just don't see any reason for the negative margins and the calc width for the class ...has-gutters what you can do is just add a padding-right except for the last-child
.container {
font-size: 0;
}
[class|="col"] {
display: inline-block;
vertical-align: top;
position: relative;
font-size: 20px;
}
.col-1-3 {
width: calc(100%/(3/1));
}
.col-2-3 {
width: calc(100%/(3/2));
}
.col-1 {
width: 100%;
}
.children-has-gutters>div {
padding-right: 30px;
box-sizing: border-box;
}
.children-has-gutters>div:last-child {
padding-right:0;
}
.bg-blue {
background-color: #42a5f5;
color: #ffffff;
}
.bg-green {
background-color: #66bb6a;
color: #ffffff;
}
<div class="container">
<div class="col-1 bg-blue children-has-gutters" style="font-size:0px;">
<div class="col-1-3">
<div class="bg-green">green 1</div>
</div>
<div class="col-1-3">
<div class="bg-green">green 2</div>
</div>
<div class="col-1-3">
<div class="bg-green">green 3</div>
</div>
</div>
</div>

Related

floating a list of divs of variable height in 3 column format

I have a list of product divs containing two more divs each displayed vertically within - top one containing an image and bottom one text. The text is variable in size so the outer divs size also is variable. These outer divs float left and go 3 to a row until a div with long text happens then the next row starts immediately after that column, leaving a gap.
So if I have a row where the 2nd div has 3 lines of text to the other two's 1, the 4th div will start not in the first position on the next line but in the 3rd.
Here is an image demonstrating what I see now vs a second what I would like to do:
And what I'm aiming to do
Do not use float. Take a look at this fiddle:
JSFiddle Demo
CSS:
.block {
width: 33.33%;
display: inline-block;
vertical-align: top;
margin-right: -3px;
}
.inner {
min-height: 100px;
margin-bottom: 10px;
background: #000;
}
You can create a row for the div elements, this will produce the layout you need! I have also provided a CSS only solution where the class clearfix will do the same thing as row class!
CSS3:
.row{
display:flex;
}
.box{
background-color:grey;
float:left;
margin:3px;
width:100px;
height:100px;
}
<div class="row">
<div class="box">1</div>
<div class="box" style="height:200px;">2</div>
<div class="box">3</div>
</div>
<div class="row">
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
</div>
CSS:
.clearfix:after {
visibility: hidden;
display: block;
font-size: 0;
content: " ";
clear: both;
height: 0;
}
* html .clearfix { zoom: 1; } /* IE6 */
*:first-child+html .clearfix { zoom: 1; } /* IE7 */
.box{
background-color:grey;
float:left;
margin:3px;
width:100px;
height:100px;
}
<div class="clearfix">
<div class="box">1</div>
<div class="box" style="height:200px;">2</div>
<div class="box">3</div>
</div>
<div class="clearfix">
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
</div>
HTML
<div class="flex-container">
<div class="box">img</div>
<div class="box">img</div>
<div class="box">img</div>
</div>
<div class="flex-container">
<div class="box">txt</div>
<div class="box">txt</div>
<div class="box">txt</div>
</div>
CSS
.flex-container{
background:red;
display:flex;
width:100%;
height:auto;
margin:0% auto;
padding:1% 0;
}
.box{
min-width:100px;
height:auto;
padding:1%;
margin:0 1%;
flex-grow:1;
background:green;
}
Also, Please chech whether you have cleared all floats
Please see Using CSS Flexible Boxes MDNweb docs

CSS Rule for the 8th and on element in a div

Is it possible to create a CSS rule that applies to the every element except for the first 8 elements? Ie, the 8th plus elements should have a margin top of 65px.
My below less code applies margins to every odd and even button within a menu. Now I want to add a specific margin to the 8th plus buttons. And then ideally apply a specific margin to the 16th plus buttons and so on.
.foo-menu {
.foo-menu-btn {
float: left;
margin: 1px;
}
// Apply specific margin to every second(even) button
.foo-menu-btn:nth-child(even) {
margin-left: -23px;
margin-top: 46px;
}
// Apply specific margin to every odd button
.foo-menu-btn:nth-child(odd) {
margin-left: -23px;
}
// For every button after the 8th one; apply a specific margin
.foo-menu-btn:nth-child( ??? ) {
margin-top: 65px;
}
}
<div class="foo-menu">
<div class="foo-menu-btn"></div>
<div class="foo-menu-btn"></div>
<div class="foo-menu-btn"></div>
<div class="foo-menu-btn"></div>
<div class="foo-menu-btn"></div>
<div class="foo-menu-btn"></div>
<div class="foo-menu-btn"></div>
<div class="foo-menu-btn"></div>
<!-- Now every foo-menu-btn should have a top margin of 65px -->
<div class="foo-menu-btn"></div>
<div class="foo-menu-btn"></div>
<div class="foo-menu-btn"></div>
<div class="foo-menu-btn"></div>
<div class="foo-menu-btn"></div>
<div class="foo-menu-btn"></div>
<div class="foo-menu-btn"></div>
<div class="foo-menu-btn"></div>
</div>
Try below code, i think help full to you.
hr {
display: block; float: left;
width: 50px; height: 50px;
border: solid 2px #aaa; margin: 10px;
}
hr:nth-child(n+9):not(:nth-last-child(-n)) {
background-color: #ddd;
}
<div id=t>
<hr>
<hr>
<hr>
<hr>
<hr>
<hr>
<hr>
<hr>
<hr>
<hr>
<hr>
<hr>
<hr>
<hr>
<hr>
<hr>
<hr>
</div>
You can use the native CSS :nth-child pseudo-class to specify a range. According to the case you specified it might look like this:
div.foo-menu div.foo-menu-btn:nth-child(n+8):nth-child(-n+15) {
margin-left: 50px
}
The downside is that you still have to manually define each range.
To select everything other than the first 8 divs you can use .foo-menu-btn:nth-child(n+9). See it applied to your HTML below (I took out the negative margins so that the divs would be visible for this example):
.foo-menu-btn {
float: left;
margin: 1px;
background-color: #ccc;
height: 1rem;
}
.foo-menu-btn:nth-child(even) {
margin-top: 46px;
}
.foo-menu-btn:nth-child(n+9) {
margin-top: 65px;
}
<div class="foo-menu">
<div class="foo-menu-btn">1</div>
<div class="foo-menu-btn">2</div>
<div class="foo-menu-btn">3</div>
<div class="foo-menu-btn">4</div>
<div class="foo-menu-btn">5</div>
<div class="foo-menu-btn">6</div>
<div class="foo-menu-btn">7</div>
<div class="foo-menu-btn">8</div>
<!-- Now every foo-menu-btn should have a top margin of 65px -->
<div class="foo-menu-btn">9</div>
<div class="foo-menu-btn">10</div>
<div class="foo-menu-btn">11</div>
<div class="foo-menu-btn">12</div>
<div class="foo-menu-btn">13</div>
<div class="foo-menu-btn">14</div>
<div class="foo-menu-btn">15</div>
<div class="foo-menu-btn">16</div>
</div>
Use :
.foo-menu .foo-menu-btn:nth-child(n+9){
color: blue;
}
.foo-menu .foo-menu-btn:nth-child(odd){
color: red;
}
.foo-menu .foo-menu-btn:nth-child(even){
color: green;
}
.foo-menu .foo-menu-btn:nth-child(n+9){
color: blue;
}
<div class="foo-menu">
<div class="foo-menu-btn">1</div>
<div class="foo-menu-btn">2</div>
<div class="foo-menu-btn">3</div>
<div class="foo-menu-btn">4</div>
<div class="foo-menu-btn">5</div>
<div class="foo-menu-btn">6</div>
<div class="foo-menu-btn">7</div>
<div class="foo-menu-btn">8</div>
<!-- Now every foo-menu-btn should have a top margin of 65px -->
<div class="foo-menu-btn">9</div>
<div class="foo-menu-btn">10</div>
<div class="foo-menu-btn">11</div>
<div class="foo-menu-btn">12</div>
<div class="foo-menu-btn">13</div>
<div class="foo-menu-btn">14</div>
<div class="foo-menu-btn">15</div>
<div class="foo-menu-btn">16</div>
</div>

percentage + px width of DIVS wrapping when resizing browser

In the following SO question (Gutter between divs), I got a great answer from Paweł Janicki. That was almost 4 months ago and I just revisited the code where I used it, and realized that in IE 11, when you resize the window, it doesn't stay on one line, it seem while! resizing the IE window, it goes from one line, and then wraps, goes back to one line, and then wraps.....
Here are two pictures of how it looks. In the first picture it looks perfect, then I minimize the window and it breaks:
https://i.imgur.com/ueEPzJc.png
https://i.imgur.com/pXP9leB.png
and here is the codepen with the sample:
https://codepen.io/anon/pen/xgZMwq
I would be ever so grateful if someone could help me fix this behavior in IE as it works as I want it in FF and Chrome.
thanks in advance!
Below is the final code I got from the old SO question:
.container{
font-size: 0;
}
[class|="col"] {
display:inline-block;
vertical-align: top;
position:relative;
font-size:20px;
}
.col-1-3{
width:calc(100%/(3/1));
}
.col-2-3{
width:calc(100%/(3/2));
}
.col-1{
width:100%;
}
.children-has-gutters{
margin-left:-15px;
margin-right:-15px;
width: calc((100% / (3/1)) + 30px);
}
.children-has-gutters > div{
padding-left:15px;
padding-right:15px;
box-sizing: border-box;
}
.bg-blue{
background-color:#42a5f5;
color:#ffffff;
}
.bg-green{
background-color:#66bb6a;
color:#ffffff;
}
<div class="container">
<div class="col-1-3 bg-blue">blue left</div>
<div class="col-1-3 children-has-gutters" style="font-size:0px;">
<div class="col-1-3">
<div class="bg-green">green 1</div>
</div>
<div class="col-1-3">
<div class="bg-green">green 2</div>
</div>
<div class="col-1-3">
<div class="bg-green">green 3</div>
</div>
</div>
<div class="col-1-3 bg-blue">blue right</div>
</div>
Try flex solution
.container{
display:flex;
}
.col-1-3{
flex:1;
}
.container{
font-size: 0;
}
[class|="col"] {
display:inline-block;
vertical-align: top;
position:relative;
font-size:20px;
}
.container{
display:flex;
}
.col-1-3{
flex:1;
}
.col-2-3{
}
.col-1{
width:100%;
}
.children-has-gutters{
margin-left:-15px;
margin-right:-15px;
}
.children-has-gutters > div{
padding-left:15px;
padding-right:15px;
box-sizing: border-box;
}
.bg-blue{
background-color:#42a5f5;
color:#ffffff;
}
.bg-green{
background-color:#66bb6a;
color:#ffffff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<div class="container">
<div class="col-1-3 bg-blue">blue left</div>
<div class="col-1-3 children-has-gutters" style="font-size:0px;">
<div class="col-1-3">
<div class="bg-green">green 1</div>
</div>
<div class="col-1-3">
<div class="bg-green">green 2</div>
</div>
<div class="col-1-3">
<div class="bg-green">green 3</div>
</div>
</div>
<div class="col-1-3 bg-blue">blue right</div>
</div>
in the unlikely even that someone else stumble on this same problem, the answer is:
This line of code, has two calculations, first the percentage and then the addition of px:
width: calc((100% / (3/1)) + 30px);
IE 11 seem not to be able to handle it, and gets it wrong when! you resize the browser, the answer is to calculate the percentage yourself, like this:
width: calc(33.333% + 30px);
Thats it, flickering gone.

3 columns/divs - two fluid, middle fixed and centered

i am trying to make a kind of responsive header for my website. it should work in this way: fluid div - fixed and centered - fluid. All three cols are filled with content. The problem is that middle column is not always centered and fluid are not equal width.
jsfiddle: http://jsfiddle.net/6f87f/
<div class="header">
<div class="fluid-col">
1234
</div>
<div class="fixed-col">
<h1>Orfin Studio</h1>
</div>
<div class="fluid-col">
123
</div>
</div>
CSS
.header {
display: table;
width: 100%;
height:120px;
text-align:center;
}
.header > div {
display: table-cell;
vertical-align:middle;
}
.fixed-col {
width:200px;
color: white;
}
.fluid-col {
background:pink;
}
why is that?;/ thanks!
Im not sure that exactly you want but try this :
FIDDLE
<div class="header container">
<div class="col col-1">
COL 1
</div>
<div class="col col-2 custom-width">
COL 2
</div>
<div class="col col-3">
COL 3
</div>
</div>
css :
.header {
display: table;
width: 100%;
height:120px;
text-align:center;
}
.header > div {
display: table-cell;
vertical-align:middle;
}
.col {
width:20%;
}
.custom-width {
min-width:300px; // change the value as you want with width and min-width
background:pink;
}
http://jsfiddle.net/RzhDD/
html
<div id="header">
<div class="fluid-col twintypercent">
Left Col
</div>
<div class="fluid-col sixtypercent">
<div class="fixed-col">
Centered Column
</div>
</div>
<div class="fluid-col twintypercent">
Right Col
</div>
css
#header {
width:100%;
}
.fluid-col {
float:left;
}
.Tpercent {
width:20%;
}
.sixtypercent {
width:60%;
text-align:center
}
.fixed-col {
margin:auto;
width:200px;
text-align:left;
}

Float left and right

this problem has been bothering me for some time. So I have created some visual descriptions of my problem
First here is my HTML structure I have 6 divs.. the first 3 float left and the last 3 float right. The last image shows the result I want but can't seem to get. Can someone out there help me here
EDIT// Sorry heres my HTML and CSS
<style>
.left { float:left; }
.right { float:right; }
</style>
<div id="container">
<div class="left"></div>
<div class="left"></div>
<div class="left"></div>
<div class="right"></div>
<div class="right"></div>
<div class="right"></div>
</div>
NOTE: I Cant do a left right left right left right option because Im getting my data from PHP via a Query to my database.. first query goes left second query goes right.... thanks a bunch
/EDIT
My floats result in this
This is what I want
Float one left , one right, and give first the clear:both property
<div class="left clear"></div>
<div class="right"></div>
<div class="left clear"></div>
<div class="right"></div>
css
.left {float:left}
.right {float:right}
.clear {clear:both}
Example
You can use CSS3 column-count property for this. Write like this:
.parent{
-moz-column-count: 2;
-moz-column-gap: 50%;
-webkit-column-count: 2;
-webkit-column-gap: 50%;
column-count: 2;
column-gap: 50%;
}
.parent div{
width:50px;
height:50px;
margin:10px;
}
.left{
background:red;
}
.right{
background:green;
}
Check this http://jsfiddle.net/UaFFP/6/
Add the first left div, then the first right div and after them add <br style="clear:both"> and repeat the procedure.
Edit: Here's an updated answer:
<div style="border:1px solid blue;float:right;height:100px;width:100px;clear:right;"></div>
<div style="border:1px solid red;float:left;height:100px;width:100px;clear:left;"></div>
<div style="border:1px solid blue;float:right;height:100px;width:100px;clear:right;"></div>
<div style="border:1px solid red;float:left;height:100px;width:100px;clear:left;"></div>
<div style="border:1px solid blue;float:right;height:100px;width:100px;clear:right;"></div>
<div style="border:1px solid red;float:left;height:100px;width:100px;clear:left;"></div>
Suppose you have another div in the middle of them. Then use this chronological order:
<div class="left"></div>
<div class="right"></div>
<div class="content"></div>
Or if you don't, just add another div that provide a style clear:both to it.
<style type="text/css">
.parent {width:50px; border:1px solid red;}
.left {float:left; }
.right{float:right;}
.child{height:50px;width:50px;border:solid 1px green;margin:0 0 10px 0;}
</style>
<body>
<div class="left parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
<div class="right parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</body>
</html>
Mind it would be odd not to have a central DIV, if that is a case float the parent DIVs left, at say widths of 20% 60% 20%.
column-count is already widely supported - http://caniuse.com/#feat=multicolumn
So if old browsers doesn't bother you consider using it.
Try this:
.leftcolums {
float: left;
}
.rightcolums {
float: right;
}
.clear {
clear: both;
}
<div class="leftcolums">
<div class="left">1</div>
<div class="left">2</div>
<div class="left">3</div>
</div>
<div class="rightcolums">
<div class="right">4</div>
<div class="right">5</div>
<div class="right">6</div>
</div>
<div class="clear">7</div>
Using the :nth-child selector and clearing after 2 divs:
​div {
width: 50px;
height: 50px;
background-color: red;
float: left;
}
div:nth-child(2n) {
background-color: green;
float: right;
}
Live example
Otherwise use this fairly hacky method, which requires no additional markup:
div {
width: 50px;
height: 50px;
background-color: red;
float: left;
}
div:nth-child(n) {
clear: both;
}
div:nth-child(2n) {
background-color: green;
float: right;
margin-top: -50px; //match this to the div height
}
​
Live example

Resources