In an effort to make my web sites more responsive, I'm trying to learn how to define elements fluidly. Today I came across a situation that I finally fixed, but I don't understand why the fix worked, and I'd like to.
I can't link to the site (NDA), but I've put up some sample pages with the elements in question:
WRONG: http://cruxwire.com/wrong.html RIGHT: http://cruxwire.com/right.html
What I have is three divs floated left. I'm trying to add padding to them (as a percentage) and am using target/context=result, and then *100 (because it's a percentage.)
My copy of Responsive Web Design by Ethan Marcotte says "When setting flexible padding on an element, your context is the width of the element itself." I gave the divs a width of 20%. Since the parent element is 945px, the pixel width of each div is 189px. I wanted to add padding of 20px, so 20/189=0.1058201058201058. I added a padding to each div of 10.58201058201058%.
This ends up giving each div a padding of 100px, not 20px. I eventually realized that the padding was being calculated based on the width of the parent element, not the div itself.
My solution was to put an extra div around each existing div, so that I could apply the width to one and the padding to the other, and that solved the problem.
Why is the padding calculating relative to its parent element rather than its own element?
How can I do this without having to add the additional divs?
You can see the code on the pages linked to in this post, and I've added it below as well.
WRONG:
<!DOCTYPE html>
<head>
<meta开发者_运维知识库 http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>WRONG</title>
<style>
#main { width:945px; margin:0 auto; padding:40px 0; background-color:blue; }
#slideshow { background-color:green; }
.threecolumn { float:left; width:20%; padding:10.58201058201058%; background-color:yellow; } /* 20px/189px */
.slide { position:relative; margin:0 1%; background-color:red; }
p { background-color:white; margin:0; padding:0; }
</style>
</head>
<body>
<div id="main">
<div id="slideshow">
<h1>WRONG</h1>
<div class="threecolumn slide">
<p>According to Firebug, this element has 100px padding.</p>
</div>
<div class="threecolumn slide">
<p>According to Firebug, this element has 100px padding.</p>
</div>
<div class="threecolumn slide">
<p>According to Firebug, this element has 100px padding.</p>
</div>
<div style="clear:both;"></div>
</div>
</div>
</body>
</html>
RIGHT:
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>RIGHT</title>
<style>
#main { width:945px; margin:0 auto; padding:40px 0; background-color:blue; }
#slideshow { background-color:green; }
.threecolumn { float:left; width:20%; margin:0 1%; background-color:yellow; }
.slide { position:relative; padding:10.58201058201058%; background-color:red; } /* 20px/189px */
p { background-color:white; margin:0; padding:0; }
</style>
</head>
<body>
<div id="main">
<div id="slideshow">
<h1>RIGHT</h1>
<div class="threecolumn">
<div class="slide">
<p>According to Firebug, this element has 20px padding.</p>
</div>
</div>
<div class="threecolumn">
<div class="slide">
<p>According to Firebug, this element has 20px padding.</p>
</div>
</div>
<div class="threecolumn">
<div class="slide">
<p>According to Firebug, this element has 20px padding.</p>
</div>
</div>
<div style="clear:both;"></div>
</div>
</div>
</body>
</html>
The W3 box model includes the padding into the calculated width. What you actually want to do is wrap the contents which desire the padding in another div, and apply a margin to that div which is equivalent to the padding which you can not use:
Example HTML:
<div id="nav">
<div class="block" id="left">
<div>
<h1>blah blah</h1>
</div>
</div>
<div class="block" id="middle">
<div>
<h1>blah blah</h1>
</div>
</div>
<div class="block" id="right">
<div>
<h1>blah blah</h1>
</div>
</div>
</div>
Example CSS:
.block {
width:33%;
height:50%;
position:relative;
float:left;
background-color:#CCC;
/** Instead of applying a 20px padding here... */
}
.block>div {
margin:20px; /* we apply a 20px margin here */
}
http://jsfiddle.net/AlienWebguy/Yf34X/1/
You are correct in assuming that target / context = result, but this includes the width, padding and margin of the element.
I've made a codepen so you can see how it works - http://codepen.io/justincavery/pen/dtusa
You don't need to add the extra div, just follow the rules of the target and context but remember the context is the parent container, not the current element, when it comes to padding and margins.
.wrapper {
margin: 0 auto;
width: 1000px;
}
#main {
width:100%;
padding:40px 0;
background-color:blue;
float:left
}
.pixeled {
float:left;
background-color:green;
width: 400px;
margin: 25px;
padding: 25px;
}
.percentaged {
float:left;
width:40%;
padding:2.5%;
background-color:yellow;
margin:2.5%;
}
<div class="wrapper">
<div id="main">
<div class="pixeled">
<div class="inner">
This is content
</div>
</div>
<div class="percentaged">
<div class="inner">
This is conent
</div>
</div>
</div>
</div>
Here is one way to do it without having to add the extra divs:
You want the padding to be approx 20px. Therefore, 20 pixels out of an overall width of 945 pixels = 20/945 x 100 = 2.116402116%
Therefore, if you use this percentage in your original "wrong" code instead of the 10.58%, you will get the desired effect. Below is the code you provided for your "wrong" example, just with the altered css.
CSS:
#main {
width:945px;
margin:0 auto;
padding:40px 0;
background-color:blue;
}
#slideshow {
background-color:green;
}
.threecolumn {
float:left;
width:20%;
padding:2.116402116%; /*<<<<<<<<padding is 20px/945px*/
background-color:yellow;
}
.slide {
position:relative;
margin:0 1%;
background-color:red;
}
p {
background-color:white;
margin:0;
padding:0;
}
HTML:
<div id="main">
<div id="slideshow">
<h1>WRONG</h1>
<div class="threecolumn slide">
<p>According to Firebug, this element has 100px padding.</p>
</div>
<div class="threecolumn slide">
<p>According to Firebug, this element has 100px padding.</p>
</div>
<div class="threecolumn slide">
<p>According to Firebug, this element has 100px padding.</p>
</div>
<div style="clear:both;"></div>
</div>
</div>
精彩评论