box model extra pixels width - css

Thank you for reading this
I'm having an odd problem with layouts. I've used Meyer's CSS reset. I have a div containing 3 divs as follows. I've not added any content yet.
<div id="container">
<div class="gallery"></div>
<div class="gallery"></div>
<div class="gallery"></div>
</div>
The following styles are applied
#container{
width: 954px;
}
.gallery {
display: inline-block;
width: 270px;
margin: 24px;
}
So in my mind each gallery is 24px + 270px + 24px = 318px wide. The combined width of the 3 gallery divs is therefore 318px * 3 = 954px.
However the divs will only display across a single row when I increase the width of #container to 960px.
Where are the 6 mystery pixels coming from? I've double checked all other border, margin and padding values are 0. I've even set outline to 0px although this shouldn't have an effect either way.

The inner divs are set to display: inline-block;. This means that any white-space between them will result in a single space added between them in the layout.
Option 1
While not a pleasant solution, you will not see the extra space if you do this.
<div id="container">
<div class="gallery"></div><!--
--><div class="gallery"></div><!--
--><div class="gallery"></div>
</div>
Option 2
Another solution that is unpleasant for different reasons, is to set font-size: 0; on the #container. If you intend to have text inside, you will need to set the font-size of the elements inside to a pixel value.
#container{
width: 954px;
font-size: 0;
}
.gallery {
display: inline-block;
width: 270px;
margin: 24px;
}
Option 3
The cleanest solution however would probably be to float the inner divs left, and clear-fix the wrapper.
#container{
width: 954px;
}
#container:after {
content: "";
display: table;
clear: both;
}
.gallery {
display: inline-block;
width: 270px;
margin: 24px;
float: left;
}

Have you tried to "nowrap" the white-space?

Related

Why is my CSS table displaying height for an element that has max-height of 0?

I have an outer div which I am displaying as a table, and and 2 inner divs.
The first inner div is floated to the left. The second inner div has a max height of 0.
.d-table {
display: table;
border: solid 1px black;
}
.float-left{
float: left;
}
.hidden{
max-height: 0px;
overflow-y: hidden;
clear: both;
}
<div class="d-table">
<div class="float-left">
hey
</div>
<div class="hidden">
cool
</div>
</div>
Expected result is:
Actual result is:
The table is taking into account the div with a height of 0 for some reason.
JSFiddle
Seems causes due to non-zero line-height of the div and the vertical-align: baseline of the anonymous cell.
I would use display: table-cell in order to be able to style the cell with vertical-align: top
.d-table {
display: table-cell;
vertical-align: top;
border: solid 1px black;
}
.float-left {
float: left;
}
.hidden {
max-height: 0px;
overflow-y: hidden;
clear: both;
}
<div class="d-table">
<div class="float-left">hey</div>
<div class="hidden">cool</div>
</div>
If you need display: table, then you can't style the anonymous table cell, but you can reduce the space with line-height: 0.
.d-table {
display: table;
vertical-align: top;
border: solid 1px black;
}
.float-left {
float: left;
}
.hidden {
line-height: 0;
max-height: 0px;
overflow-y: hidden;
clear: both;
}
<div class="d-table">
<div class="float-left">hey</div>
<div class="hidden">cool</div>
</div>
This is because the .hidden div is still part of the DOM and factors into the position calculations for the .d-table element.
Instead of max-height: 0;, use display: none. This removes the element from the flow of the DOM.
The .hidden element is theoretically being displayed correctly with a height of 0.
But then it has a clear:both, while the other div hass float:left, and their parents is displayed as table.
This is the magic combo, confusing the height of the parent div.
The problem is: you first kind-of take the first div out of document flow. It is placed somewhere new, but still not really there (yes, floats are spooky as f***).
THEN you clear:both the second div, forcing it on a new line. The parent div (having forgotten all about the first div and the 18 vertical pixels it's taking up), can't have a height of 0 (because it's display-table), so it's given a minimum height of something-something.
There's really no other solution known to me than not using that combination. I would recommend actually hidding the hidden div (display:none).

Centered website layout with varying sized columns and responsive?

I'm looking to create a website (or at the very least a homepage) like Joules.com
I essentially want to create boxes side by side in varying sizes but want them to resize or move to a new line with the browser window resizing (responsive?). It's also necessary for them to be centered. I can get to the point where I have the divs side by side but they don't seem to be centered... Here's what I have so far. Any help would be greatly appreciated. I'm kind of nooby in this department but wanting to learn!
CSS
#container {
width: 100%;
margin: 0 auto;
overflow: hidden;
}
#Womens {
height: auto
width: 241px;
float: left;
margin: 0 auto;
text-align:center;
}
#Mens {
height: auto
margin: 0 auto;
width: 241px;
float: left;
text-align:center;
}
#Footwear {
height: auto
margin: 0 auto;
width: 241px;
float: left;
text-align:center;
}
#Accessories {
height: auto
margin: 0 auto;
width: 241px;
float: left;
text-align:center;
}
HTML
<body><center>
<div id="container">
<div id="Womens">Womens</div>
<div id="Mens">Mens</div>
<div id="Footwear">Footwear</div>
<div id="Accessories">Accessories</div>
</div>
First at all you don't need to use an ID for each element, since your CSS code is the same for everyone use a classname instead:
<div id="container">
<div class="column">Womens</div>
<div class="column">Mens</div>
<div class="column">Footwear</div>
<div class="column">Accessories</div>
</div>
Then don't use float because you can't center those elements, use inline-block:
#container {
font-size:0;
text-align:Center;
}
.column {
font-size:14px;
display:inline-block;
}
Check this Demo Fiddle
Your CSS could be much simpler by using a class (Don't Repeat Yourself ;) ).
If you put text-align: center; on the container instead the container itself and its child contents will be centered. If you want you could then override the setting for the separate columns, or just for their content.
You've also used fixed pixel values for the column width, so they can't really be "responsive." You can use percentage values there as well, but that can have some screwy side effects. Note that 4 columns even with auto margins still need to be < 100% or else they wrap oddly. They also might collapse or overlap at smaller sizes. You can set a min-width on the container or the columns to help prevent this, along with a margin-bottom to keep them separate if they do wrap.
Also, if you just use percentage width and inline-block, the columns will be aligned at the bottom. Using vertical-align: top; fixes that. You said initially you wanted different heights, but if you didn't you could set a min- or max-height & put something like overflow:scroll on the content.
#container {
width: 100%;
min-width: 320px;
margin: 0 auto;
overflow: hidden;
text-align:center;
}
.box {
margin: 0 auto;
margin-bottom: 10px;
width: 20%;
min-width: 90px;
padding: 1%;
vertical-align: top;
display: inline-block;
background-color: #678;
color: #fff;
}
.content {
background-color: #fff;
color: #333;
padding: 1em;
text-align: left;
}
<body>
<div id="container">
<div id="Womens" class="box">Womens
<div class="content">This is some left-aligned women's content about/for women. View the Code Snippet in fullscreen!</div>
</div>
<div id="Mens" class="box">Mens
<div class="content">This is some left-aligned men's content about/for men. If you resize the browser the columns will be responsive, but break after a certain point.</div>
</div>
<div id="Footwear" class="box">Footwear
<div class="content">This is some left-aligned footwear content about/for feet. Feet are weird.</div>
</div>
<div id="Accessories" class="box">Accessories
<div class="content">This is some left-aligned accessory content about stuff you men or women could potentially put on their feet, or whatever.</div>
</div>
</div>
</body>

Responsive CSS - how to 'dynamically' align div to parent width with padding/margin?

I can't make it any clearer than this, sorry. I want to properly align 4 divs (on a width of 1150px as that is max-width of the content div) and upon resizing when it can't do 4, 3 in the center etc etc)
On >1150px screens it would/should like this: http://i.imgur.com/KaOPqZK.png. Now, the closest I can come is this: http://i.imgur.com/6khwQkR.png. I can set the first-child margin to 0 on the left one, but as there are multiple rows, those would still have the padding. Creating new rows as divs isn't possible either, because that would ruin everything when it's resized and only shows 3/1 on both rows.
When resizing it should center, with even margins on all sides, and not like this as it is right now: http://i.imgur.com/GiR1nZ2.png.
Basically all the code I have right now is this, simply because I know of no other way.
div.project-container {
float: left;
margin: 0 8px 30px 8px;
position: relative;
width: 270px;
}
I'm guessing it has to be Javascript who rescues the day, and I'm fine with that. Pointers in the right direction, examples on the internets, all is welcome. Thank you.
Adapted from an old answer :
HTML
<div id="container">
<div class="obj">1</div>
<div class="obj">2</div>
<div class="obj">3</div>
<div class="obj">4</div>
<div class="obj">5</div>
<div class="obj">6</div>
<div class="obj">7</div>
<div class="obj push"></div>
<div class="obj push"></div>
<div class="pushend"></div>
</div>
CSS
#container
{
max-width: 980px;
background-color: lavender;
display: inline-block;
text-align: justify;
}
.obj
{
width: 180px;
height: 180px;
background-color: lightgreen;
display: inline-block;
margin-bottom: 20px;
}
.obj.push {
height: 0px
}
.pushend {
width: 100%;
height: 0px;
display: inline-block;
}
demo

How can I horizontally align my divs?

For some reason my divs won't center horizontally in a containing div:
.row {
width: 100%;
margin: 0 auto;
}
.block {
width: 100px;
float: left;
}
<div class="row">
<div class="block">Lorem</div>
<div class="block">Ipsum</div>
<div class="block">Dolor</div>
</div>
And sometimes there is a row div with just one block div in it. What am I doing wrong?
To achieve what you are trying to do:
Consider using display: inline-block instead of float.
Try this:
.row {
width: 100%;
text-align: center; // center the content of the container
}
.block {
width: 100px;
display: inline-block; // display inline with ability to provide width/height
}​
DEMO
having margin: 0 auto; along with width: 100% is useless because you element will take the full space.
float: left will float the elements to the left, until there is no space left, thus they will go on a new line. Use display: inline-block to be able to display elements inline, but with the ability to provide size (as opposed to display: inline where width/height are ignored)
Alignments in CSS had been a nightmare. Luckily, a new standard is introduced by W3C in 2009: Flexible Box. There is a good tutorial about it here. Personally I find it much more logical and easier to understand than other methods.
.row {
width: 100%;
display: flex;
flex-direction: row;
justify-content: center;
}
.block {
width: 100px;
}
<div class="row">
<div class="block">Lorem</div>
<div class="block">Ipsum</div>
<div class="block">Dolor</div>
</div>
Using FlexBox:
<div class="row">
<div class="block">Lorem</div>
<div class="block">Ipsum</div>
<div class="block">Dolor</div>
</div>
.row {
width: 100%;
margin: 0 auto;
display: flex;
justify-content: center; /* for centering 3 blocks in the center */
/* justify-content: space-between; for space in between */
}
.block {
width: 100px;
}
The latest trend is to use Flex or CSS Grid instead of using Float. However, still some 1% browsers don't support Flex. But who really cares about old IE users anyway ;)
Fiddle: Check Here
Another working example, using display: inline-block and text-align: center
HTML:
<div class='container'>
<div class='row'>
<div class='btn'>Hello</div>
<div class='btn'>World</div>
</div>
<div class='clear'></div>
</div>
CSS:
.container {
...
}
.row {
text-align: center;
}
.btn {
display: inline-block;
margin-right: 6px;
background-color: #EEE;
}
.clear {
clear: both;
}
Fiddle: http://jsfiddle.net/fNvgS/
Although not covering this question (because you want to align the <div>s inside the container) but directly related: if you wanted to align just one div horizontally you could do this:
#MyDIV
{
display: table;
margin: 0 auto;
}
If elements are to be displayed in one line and IE 6/7 do not matter, consider using display: table and display: table-cell instead of float.
inline-block leads to horizontal gaps between elements and requires zeroing that gaps. The most simple way is to set font-size: 0 for parent element and then restore font-size for child elements that have display: inline-block by setting their font-size to a px or rem value.
I tried the accepted answer, but eventually found that:
margin: 0 auto;
width: anything less than 100%;
Works well so far.
I've use this two approaches when I need to handle horizontal div alignment.first (Center Aligning Using the margin Property):
.center-horizontal-align {
margin-left: auto;
margin-right: auto;
width: (less than 100%) or in px
}
Setting the left and right margins to auto specifies that they should split the available margin equally. Center-aligning has no effect if the width is 100%.
and the second:
.center-horizontal-align {
display: table
margin-left: auto;
margin-right: auto;
}
Using the second approach is convenient when you have several elements and you want all of them to be centred in one table cell(i.e. several buttons in one cell).
instead of float use flex
.row {
display: flex;
flex-direction: row;
}

Dual Column Layout in CSS with dynamic height in IE

I have a dual column layout using CSS:
<div id="nav"></div>
<div id="left_column"></div>
<div id="right_column"></div>
<div id="footer"></div>
#left_column{
float: left;
width: 463px;
display: inline-block;
margin-left: 12px;
}
#right_column{
float: right;
width: 463px;
display: inline-block;
margin-right: 12px;
}
#footer{
clear:both;
text-align: center;
padding: 40px;
}
This works fine in Firefox, but creates problems in IE. The main problem is that the content of these two columns is dynamic and never amounts to the same height with either column sometimes having a bigger height than the other. In IE, the left and right columns align with the bottom which creates a variable amount of space between the shorter column and the nav. What I would like is to have the columns align with the top/nav and then when an element is inserted with ajax at the top of the left_column, it just pushes the content in that column down and the two columns remained aligned at the top. I hope that made sense, any help is appreciated.
...
Using igoogle layout as an example, I have added the following css and it seems to be working:
<div id="outside">
<div id="left_column"></div>
<div id="right_column"></div>
</div>
<div id="footer"></div>
#outside{
display: block;
float: none;
margin: 0 0 1em;
overflow: hidden;
position: static;
width: auto;
}
.column {
display: block;
width: 40%;
float: left;
margin-left: 0px;
}
I have yet to fully implement it, but this seems to be aligning the columns with the top regardless of height and expands/contracts with the top as a reference point.
Maybe this resource will be of help to you:
http://matthewjamestaylor.com/blog/equal-height-columns-cross-browser-css-no-hacks
Since you want to have only 2 columns,
have a look at the given example here:
http://matthewjamestaylor.com/blog/equal-height-columns-2-column.htm
Kind regards, mtness.

Resources