3 column layout with inline block not working- the divs aren't lining up correctly - css

I have a div which contains three child div's, and for some reason the first child div is properly positioned within its parent, but the other two children are positioned lower from the first child. The more content I add to the first child the lower the other children become positioned relative to the top of the container parent.
Heres a jfiddle showing you my problem: http://jsfiddle.net/gY72a/7/
the three children arent on the same line here but you can see the problem when you look at how high the first child is positioned compared to the second one.
Code is already in the jfiddle, but here is the css I am using:
/*Parent div in which all three children are nested*/
#main {
width: 80%;
min-width: 1000px;
background-color: #FFFFFF;
margin: 1% auto;
border-radius: 1px;
border: 0px solid rgba(0, 0, 0, 0.15);
box-shadow: 2px 2px 2px 0px rgba(0, 0, 0, 0.2);
}
/*First child*/
#leftside {
display: inline-block;
width: 18%;
margin: 10px 1% 8px;
padding: 1em;
background-color: rgba(0, 0, 0, 0.1);
}
/*Second Child*/
#innermain {
display: inline-block;
width: 50%;
margin: 10px 1% 8px;
padding:1em;
background-color: #eaeaea;
border-radius: 1px;
border: 0px solid rgba(0, 0, 0, 0.15);
box-shadow: 2px 2px 2px 0px rgba(0, 0, 0, 0.2);
}
/*Third child*/
#rightside {
width: 20%;
min-width: 320px;
padding: 1em 0px;
display: inline-block;
background: #FFFFFF;
margin: 10px 1% 8px ;
border-radius: 1px;
border: 1px solid rgba(0, 0, 0, 0.15);
}

The main problem here is that you are using `display:inline-block" and also that you are using a combination of percentages and margins with ems. Now, theoretically, you could have 3 blocks, and add their widths and the padding, and the margin - to all equal 100, but even if you wanted to go that route, you are using the inline-block method - which by default leaves a little unwanted space between each block, and throws off that number. Beyond that, padding and margins add to the size of the box, so if you have a box that is 20% wide, and has a padding of 1em and a margin of 1% - then it's 20%+2%+2em (+total border width) - and what does that equal? Well, I don't know - and the browser isn't going to love dealing with that either, because depending on window size, that number is going to be different. So, if you want to know the problem, those are the factors leading to the problems.
If you want a solution, then you have a few routes, but they depend on what you need to do. It doesn't appear as though you are building this site responsively. So in that case, you are working with a 1000px wide canvas. - and in that case, then there is no reason why you cant just use px to add up margin/padding/box size etc to equal 100. leave the boxes as display: block; and float them left.
If you want to come into the present, and start using a bit of modern stuff - you should read about box-sizing: border-box - What that does is change the box model so that the padding and borders of boxes moves inside the box and therefore doesn't add to it's size. It's really great and makes working with css a pleasure. Then you don't have to add stuff up to determine the box's size. - so - unless you need to support IE 7 - I would suggest you make it standard in your overall approach to CSS from now on. http://www.paulirish.com/2012/box-sizing-border-box-ftw/
If you are going to float the columns in their "wrapper" thing - then that wrapper thing is no longer going to regognize them in the same way, so you are going to have to look up clearfixing the div, or use overflow:hidden; (which has some issues) or float that wrapper itself to get them to live in the same world again, because floating takes the elements out of the regular flow.
In the case that you can go with box-sizing, then you still have to worry about margins(they don't move inside the box). So, you'll need to have those in percentages, or get another fancy way of making consistent gutter widths, but since you have a static sized site - I'm not going to go into that.
Here is a fiddle without all of your styles - to show how it works.
HTML
<div class="content-wrapper">
<div class="column what">
<h2>What We do</h2>
<p>Bla bla bla</p>
</div>
<div class="column main-content">
<h2>Latest News and Events</h2>
</div>
<div class="column where">
<h2>Where To Find Us</h2>
</div>
</div> <!-- .content-wrapper -->
CSS
*, *:before, *:after {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.content-wrapper {
width: 1000px;
margin-right: auto;
margin-left: auto;
border: 1px solid red;
overflow: hidden; /* should be clearfix instead */
}
.column { /* what the columns have in common */
float: left;
padding: 1em;
}
.what {
width: 25%;
margin-right: 1%;
background-color: orange;
}
.main-content {
width: 48%;
margin-right: 1%;
background-color: yellow;
}
.where {
width: 25%;
background: red;
}

You have specified display:inline-block for the divs below which should align them properly in a row with the widths given. But the width is taken by the content section of the div and the div adds the margins given to them with the width. This is why the blocks are jumping below one another.
When you apply box-sizing: border-box; to the divs, the width of the div will be calculated including the margins given to the corresponding divs.
Hope this helps you.
#main, #leftside, #innermain{
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
-moz-box-sizing: border-box; /* Firefox, other Gecko */
box-sizing: border-box; /* Opera/IE 8+ */
}

This should do what you want:
#main div {
float: left;
}

Related

CSS: containing five floated 20% elements with borders

I'm trying to align five horizontal menu elements with 'float:left' next to each other inside a container that spans 80% of the screen and a minimum of 960px. For this, I had initially set their min-width to 192px (960/5) and their width to 20%, but quickly realized this does not play well with adding 1px borders, causing one of the buttons to be 'thrown overboard'.
Changing the widths to 19.895333% and 191px, respectively, solved the issue, however this is clearly a hacky solution which also leaves an ugly space of 2-3 pixels at the right side of the menu.
Is there a more elegant way to align these elements and account for the bonus width added by borders, padding etc? I have tried 'overflow:hidden' to simply hide whatever may poke outside the container, but this just hides the entire 5th button.
A picture to illustrate the result:
The html code:
<div class="menucontainer">
<div class="menutab" id="menutab_first">News</div>
<div class="menutab">Game Guide</div>
<div class="menutab">Articles</div>
<div class="menutab">Media</div>
<div class="menutab" id="menutab_last">Community</div>
</div>
The css code:
.menucontainer {
height: 26px;
margin-left: auto;
margin-right: auto;
border-width: 1px;
border-style: solid;
border-color: #303030 #101010 #000 #101010;
border-radius: 0px 0px 8px 8px;
}
.menutab {
line-height: 26px;
float: left;
width: 19.895333%;
text-align: center;
min-width: 191px;
border-right: 1px solid #202020;
background-image: url('../img/menubutton2.png');
background-size: 100% 100%;
font-family: 'Cabin', sans-serif;
}
#menutab_first {
border-radius: 0px 0px 0px 8px;
}
#menutab_last {
border-right: 0px;
width: 20%;
min-width: 192px;
border-radius: 0px 0px 8px 0px;
}
Thank you in advance!
For this you can make use of the box-sizing property to set your borders to appear within your elements rather than outside of them:
elem {
-webkit-box-sizing: border-box; /* Some mobile browsers. */
-moz-box-sizing: border-box; /* Firefox. */
box-sizing: border-box; /* All other browsers IE8+. */
}
border-box
The specified width and height (and respective min/max properties) on this element determine the border box of the element. That is, any padding or border specified on the element is laid out and drawn inside this specified width and height. The content width and height are calculated by subtracting the border and padding widths of the respective sides from the specified ‘width’ and ‘height’ properties.
So in the case of your CSS:
.menutab {
...
width: 20%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
...
}
What you need is box-sizing:border-box;
This CSS property will change the box model for the element such that the border is included inside the width, rather than outside of it as with the standard box model.
This means that your boxes will then be 20% of the width of the page, rather than 20% + the width of the borders.
Problem solved.
box-sizing: border-box causes the width of the borders to be counted as part of the 20%. That's the best solution but if that will interfere with your layout in some way, an alternative is use calc to subtract the borders from the 20%, e.g. width: calc(20% - 2px);

CSS floats and padding

I'm trying to create a 2 column box (33%/66%) with CSS, but I'm having problems with floats and padding. I want to house the icon and all text withing the containing box with 30px padding all round. The 'facttext' is not showing any padding to the left, even though it's set at 30px, is there any obvious reason why?
Code used is as follows:
Codepen: http://codepen.io/graemebryson/pen/mvBKs
On website (displays better): http://energy-hypermarket.org/test (# bottom)
HTML
<div class="fact">
<div class="facticon">
<img src="/wp-content/uploads/fact.outline.png">
<h2>Did You Know?</h2>
</div>
<div class="facttext">
You could save up to 40% on your energy bills by simply upgrading your Boiler with Energy Hypermarket.
<a class="offerbutton" href="/boiler-package">Learn more</a>
</div>
</div>
CSS
.fact {
border: 1px solid rgba(0, 0, 0, 0.09);
}
.facticon {
border-right: 1px solid rgba(0, 0, 0, 0.09);
float: left;
margin-left: auto;
margin-right: auto;
padding: 30px 30px 0;
text-align: center;
width: 33%;
}
.facttext {
padding: 30px;
}
thats because your facttext is not floating, when you check your code in FireBug, you would see that the padding is added, but on a block level.
See updated codepen for a corrected padding version.
CSS
.facttext {
padding: 30px;
float: right; /* -- New -- */
width: 66%; /* -- New -- */
}
This will give the right padding on the .facttext element.

How to add borders to div without messing up the layout?

I have the following elements:
<body>
<div id="container">
<div id="sidebar1"></div>
<div id="content">
<h3>Lorem ipsum</h3>
<p>Whatnot.</p>
</div>
<div id="sidebar2"></div>
</div>
</body>
Following this style:
/* ~~ this fixed width container surrounds all other divs~~ */
#container {
width: 960px;
background-color: #FFF;
margin: 0 auto;
overflow: hidden;
}
#sidebar1 {
float: left;
width: 180px;
/*border: 2px solid black;*/
background-color: #EADCAE;
padding: 0px 0px 100% 0px;
}
#content {
padding: 10px 0;
width: 600px;
float: left;
}
#sidebar2 {
float: left;
width: 180px;
/*border: 2px solid black;*/
background-color: #EADCAE;
padding: 0px 0px 100% 0px;
}
I am trying to achieve this layout: http://jsfiddle.net/QnRe4/
But as soon as I un-comment the borders it turns into this: http://jsfiddle.net/FZxPQ/
** Solved **
The border width was added to each element's total width making them too wide to fit in the container. Removing 2x the border width from each column's width solves the problem: http://jsfiddle.net/FZxPQ/4/
CSS box-sizing to the rescue! This property
alters the default CSS box model used to calculate widths and heights of elements
The border-box value means that
the width and height properties include the padding and border
/* support Firefox, WebKit, Opera and IE8+ */
#container, #sidebar1, #sidebar2 {
box-sizing: border-box;
-moz-box-sizing: border-box;
}
However, browser support is not 100% standardized.
As other answers have already mentioned the extra width which pushes the sidebars out of alignment is because the width calculation includes the border width. box-sizing simply tells the browser that an element with a given width/height should include any border and padding values into the final width/height calculations.
The problem is that when you add in the boarder, the size of the outer divs increased by 4, 2px on each size. So, your container needs to grow in size by 8px.
So change your container to:
#container {
width: 970px;
background-color: #FFF;
margin: 0 auto;
overflow: hidden;
}
See: http://jsfiddle.net/QnRe4/13/
When you apply the borders, that goes outer the divs, so the sidebars will have 184px width which doesn't fits to the container. try addig width: 176px
http://jsfiddle.net/QnRe4/12/
#sidebar1 {
float: left;
width: 176px;
border: 2px solid black;
background-color: #EADCAE;
padding: 0px 0px 100% 0px;
}
Like this? http://jsfiddle.net/QnRe4/3/
What's happening is that your elements are losing their block display properties when you remove the borders.
So, adding display: block to those elements resolves that.
I've also adjusted your element's widths by 4px in width to retain the layout, since removing those borders essentially reduces the space that those elements occupy on-page.

Keeping/scaling DIV Ratio with percentages

At the moment I have a layout that pulls a number of thumbnails into a grid - each is defined by a style that keeps them a fixed ratio, (roughly 16:9) which is defined by pixel dimensions (389px x 230px) but they are looking a bit small on high-res screens.
The images are actually pulled into the DIV as a background that covers 100% width and height of the DIV and then the DIV's obviously control the aspect and size.
What I am looking to do is have these DIV's dynamically resize based on the page size of the device but to keep the ratio of the DIV's.
Is this possible?
My thoughts would be to set the width based on the percentage of the page but then I'm not sure how I would set the height and keep the correct aspect ratio (due to different resolutions etc.)
What would be the best way to do this?
EDIT - Thanks for all your ideas so far, thought maybe I should show you how I'm pulling in the data at the moment.
In my HTML I've got the following code which generated the grid
<a class="griditem" href="../video.php?video=13" style="background-image:url(../video/Relentless/Relentless.jpg); background-size:100% 100%;">
<div class="titles">
<h5>Relentless Short Stories</h5>
<h6>Frank Turner: The Road</h6>
</div>
This is styled with the following CSS
.griditem {
position: relative;
float: left;
margin-right: 17px;
margin-bottom: 17px;
background-color: #777;
-webkit-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.5);
-moz-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.5);
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.5);
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
border-radius: 2px;
width: 389px;
height: 230px;
text-align: left;
}
.titles {
padding: 5px;
position: absolute;
bottom: 10px;
left: -1px;
right: -1px;
background: transparent url(../images/layout/white80.png) top left;
-moz-border-radius: 1px 1px 0 0;
border-radius: 1px 1px 0 0;
text-align: left;
}
The reason I'm implementing it this way is so that the Div can float over the bottom of the image.
Just a quick idea which might be useful for you.
It is based on the fact that vertical padding/margin use the WIDTH of the parent box when it is set to percentages, so it is possible to resize a div relative its parent box
http://jsfiddle.net/xExuQ/2/
body,html { height:100%; }
.fixed-ratio-resize {
width: 50%; /* child width = parent width * percent */
padding-bottom: 50%; /* child height = parent width * percent */
height: 0; /* well, it is not perfect :) */
}
​If you want to put some (non-background) content into this nicely resized box, then put an absolutely positioned div inside it.
Reference:
http://www.w3.org/TR/CSS2/box.html#margin-properties and
http://www.w3.org/TR/CSS2/box.html#padding-properties says:
Margins: "The percentage is calculated with respect to the width of the generated box's containing block. Note that this is true for 'margin-top' and 'margin-bottom' as well. If the containing block's width depends on this element, then the resulting layout is undefined in CSS 2.1."
Paddings:"The percentage is calculated with respect to the width of the generated box's containing block, even for 'padding-top' and 'padding-bottom'. If the containing block's width depends on this element, then the resulting layout is undefined in CSS 2.1."
EDIT
http://jsfiddle.net/mszBF/6/
HTML:
<a class="griditem" href="#" style="background-image: url(http://pic.jpg);">
<span class="titles">
<span class="name">Unicomp Studios</span>
<span class="title">Springs Buckling (2012)</span>
</span>
</a>
CSS:
.griditem {
float: left;
margin-right: 17px;
margin-bottom: 17px;
min-width: 100px; /* extremely narrow blocks ==> crap looking */
width: 30%;
background: blue no-repeat;
background-size: contain; /* from IE9 only: https://developer.mozilla.org/en/CSS/background-size */
border: 1px solid transparent; /* prevent .titles:margin-top's margin collapse */
}
.titles {
/* <a> elements must only have inline elements like img, span.
divs, headers, etc are forbidden, because some browsers will display a big mess (safari) */
display: block; /* so display those inline elements as blocks */
padding: 5px;
margin: 0 auto;
margin-top: 105%;
background: yellow;
}
.titles > span {
display: block;
}​
I know this might not be the best solution, but
<html>
<style type="text/css">
#cool{
width:40%;
background:blue;
padding-bottom:10%;
}
</style>
<div id="cool" >
</div>
</html>
Here Ive used padding-bottom, to maintain its height relative to its width. U can set padding-bottom as a percentage. Hope this helped.

Margin behavior of "overflow:hidden" div after floating div on webkit

I've found that an "overflow:hidden" div following a "float:left" div has doubled margin on the right. This can be tested with following code:
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
div.intro {
border: 1px solid #DBDBDB;
margin: 10px 0;
padding: 10px 0;
}
div.intro>div {
border: 1px solid #DBDBDB;
height: 150px;
margin: 0 10px;
}
div.brief {
float: left;
width: 150px;
}
div.list {
overflow: hidden;
}
</style>
</head>
<body>
<div class="intro">
<div class="brief"></div>
<div class="list"></div>
</div>
</body>
</html>
The space between right border of div.list and right border of div.intro is 20px in chrome(17.0.963.56 m) and safari(5.1.2), while being 10px in Firefox(11.0) and IE9.
Is this a bug of webkit or just an undefined preference of css?
Thanks!
I was able to reproduce this on Chrome for Mac, 17.0.963.56.
The problem stems from the fact you've given #brief and #list a height, but haven't contained the float. There actually isn't a double margin; the margin-right of 10px is combining with .intro's 10px padding-right to give the allusion of a 20px double-margin.
All things considered, the fact the WebKit (Chrome's & Safari's renderer), rendered things that way is a little strange.
Everything worked as expected with this CSS (see the Fiddle):
.intro {
margin: 0 0 20px;
padding: 20px;
background: #FFA;
overflow: auto;
height: 100%;
}
.brief {
background: rgba(255, 0, 0, 0.25);
width: 150px;
float: left;
}
.list {
background: rgba(0, 0, 255, 0.25);
margin: 0 0 0 170px;
}
The above solution seems to do the trick as long as the width of your floating element is static and predictable (as the margin of the non-floating div is set to span the floating div's width, plus the required space between the two).
If, however, you're working with a floating div with a dynamic width, you can target what appears to be a Webkit-specific issue with a -webkit-margin-start property which all other browsers will ignore:
.div.list {
overflow: hidden;
-webkit-margin-start: 0px !important; /* you can ditch the 'important' by adding 'div.intro' to the front of your selector */
}
This effectively sets div.list's margin-left: 0 in Webkit only, while accommodating a dynamic width for your floating div. Unfortunately, I haven't been able to test this in Chrome 19b yet, so I'm not sure how it'll handle this kludge.

Resources