Please see example at
http://jsfiddle.net/cne94hw4/
.a{
width: 100%;
background-color: #eee;
margin-left: 200px;
}
I was expecting "width 100%" will mean 100% of the windows, but clearly it's not when I add a margin to it. I found this is difficult to understand.
What's the exact relationship of the box and the margin? It's there any written rule for this?
Your question is about the CSS Box model, which is described in detail at the CSS specification: http://www.w3.org/TR/CSS2/box.html
In brief, the width defines the width of the content box. If you add padding, borders
and margins, then the overall width of the block box is the width of the content box plus
any widths due to padding, borders and margins.
As for the height, padding and border widths are added to the overall heigth of the
block. Margins, though, can collapse with the margins of adjacent blocks, which is
another topic to look at (see: collapsing margins).
Another concept is the block formatting context, which comes into play if you
deal with elements that may be floated or positioned.
In your example, the overall width of the a element is 100% plus 200px due to the
left margin.
Finally, you can have some control over how the width is computed by using the box-sizing property.
width: 100%' does mean100%` of the document your example, but you also set a margin, which is what's limiting the width of the element. See what happens when you remove it.
try the following
.class{
width:100%;
padding-left:200px;
box-sizing:border-box;
}
margin adds extra space out of the box.
Related
If you look at the CSS box model spec, you'll observe the following:
The [margin] 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. (emphasis mine)
This is indeed true. But why? What on earth would compel anyone to design it this way? It's easy to think of scenarios where you want, e.g. a certain thing to always be 25% down from the top of the page, but it's hard to come up with any reason why you would want vertical padding to be relative to the horizontal size of the parent.
Here's an example of the phenomenon I'm referring to:
<div style="border: 1px solid red; margin: 0; padding: 0; width: 200px; height: 800px;">
This div is 200x800.
<div style="border: 1px solid blue; margin: 10% 0 0 10%;">
This div has top-margin of 10% and left-margin of 10% with respect to its parent.
</div>
</div>
http://jsfiddle.net/8JDYD/
Transferring my comment to an answer, because it makes logical sense. However, please note that this is unfounded conjecture. The actual reasoning of why the spec is written this way is still, technically, unknown.
Element height is defined by the height of the
children. If an element has padding-top: 10% (relative to parent
height), that is going to affect the height of the parent. Since the
height of the child is dependent on the height of the parent, and the
height of the parent is dependent on the height of the child, we'll
either have inaccurate height, or an infinite loop. Sure, this only
affects the case where offset parent === parent, but still. It's an
odd case that is difficult to resolve.
Update: The last couple sentences may not be entirely accurate. The height of the leaf element (child with no children) has an effect on the height of all elements above it, so this affects many different situations.
For "n%" margin (and padding) to be the same for margin-top/margin-right/margin-bottom/margin-left, all four have to be relative to the same base. If top/bottom used a different base than left/right', then "n%" margin (and padding) wouldn't mean the same thing on all four sides.
(Also note having the top/bottom margin relative to the width enables a weird CSS hack that allows you to specify a box with an unchanging aspect ratio ...even if the box is rescaled.)
I vote for the answer from #ChuckKollars after playing with this JSFiddle (on Chrome 46.0.2490.86) and referring to this post (written in Chinese).
A major reason against the infinite calculation conjecture is that: using width faces the same infinite calculation problem.
Have a look at this JSFiddle, the parent display is inline-block, which is eligible to define margin/padding on it. The child has margin value 20%. If we follow the infinite calculation conjecture:
The width of the child depends on the parent
The width of the parent depends on the child
But as a result, Chrome stops the calculation somewhere, resulting:
If you try to expand the "result" panel horizontally on the JSFiddle, you will find that the width of them will not change. Please note that the content in the child is wrapped into two lines (not, say, one line), why? I guess Chrome just hard-code it somewhere. If you edit the child content to make it more (JSFiddle), you will find that as long as there is extra space horizontally, Chrome keeps the content two lines.
So we can see: there is some way to prevent the infinite calculation.
I agree with the conjecture that: this design is just to keep the four margin/padding values based on the same measure.
this post (written in Chinese) also proposes another reason is that: it is because of the orientation of reading/typeset. We read from top to down, with the width fixed and height infinite (virtually).
I realize the OP is asking why the CSS specification defines top/bottom margin percentages as a % of width (and not, as would be assumed, height), but I thought it might also be useful to post a potential solution.
Most modern browsers support vw and vh now which lets you specify margin numbers against the viewport width and viewport height.
100vw/100vh equals 100% width/100% height (respectively) if there's no scrollbar; if there is a scrollbar the viewport numbers don't account for this (while the % numbers do). Thankfully, nearly all browsers use scrollbar sizes of 17px (see here), so you can use css calc function to account for this. If you don't know whether a scrollbar will appear or not, then this solution will not work.
For example: Assuming no horizontal scrollbar, a top margin of 50% of height, could be defined as "margin-top: 50vh;". With a horizontal scrollbar, this could be defined as "margin-top: calc(0.5 * (100vh - 17px));" (remember that the minus and plus operators in calc require spaces on both sides!).
I know this question is a bit old, but I'd like to refresh it for CSS3. While it's true that the CSS2.1 specification says that percentage padding and margin are defined relative to the width of the containing block, this is not always the case. It depends on the writing mode. This comes straight from the CSS3 specs:
As a corollary, percentages on the margin and padding properties, which are always calculated with respect to the containing block width in CSS2.1, are calculated with respect to the inline size of the containing block in CSS3.
I cover this in my tutorial on aspect ratios with CSS.
Specifically, there's a section on Percentage Padding in Horizontal vs. Vertical Writing Modes. By default, an element has a horizontal writing mode, where text flows horizontally (in the "inline" direction) from left to right. However, using the writing-mode CSS property, you can actually set the mode to be vertical (with text either flowing from right to left or left to right). Here are some diagrams of horizontal vs vertical writing modes:
These are taken from the MDN docs on writing modes.
In vertical writing modes, percentage padding will be relative to the height of the containing block, not to the width.
Here's proof:
.document {
writing-mode: vertical-rl;
width: 100%;
height: 100vh;
}
.parent {
width: 100%;
height: 200px;
background-color: black;
color: white;
}
.child {
padding: 10%;
background-color: white;
color: black;
border: solid 1px;
}
<div class="document">
<div class="parent">
<div class="child">
Child
</div>
</div>
</div>
The child gets 20px of padding, which is 10% of its containing block's height (200px).
As to the why in the question, this was covered well in the other posts here.
Let's say the width of the containing box is 5cm, padding(all sides) is 2cm.
if I set the width of the content to be 50%. Now the absolute value of the width would be 2.5 cm. But if the padding effect is still there, then the box now would be 2+2.5+2 = 6.5cm. But the content would no longer be 50% of width now(2.5/6.5 != 50%).
I'm kinda confused,any help? Thanks!
Look into the Box Model to understand how this currently works.
It does vary significantly between some browsers (especially older ones).
Not as big a problem as it used to be, but the solution to use box-sizing may not be a universal fix depending on your users (any hold-outs still on IE >8?).
As stated by others you can use the box-sizing property to fit either to the content alone, content with padding, or the entire box w/padding & border (which is probably what you want).
The result is correct. To simplify these calculations you could use box-sizing: border-box to include padding in total width.
border-box
The width and height properties include the padding and border, but not the margin. This is the box model used by Internet Explorer
when the document is in Quirks mode. Note: Padding & border will be
inside of the box e.g. IF .box {width: 350px}; THEN you apply {border:
10px solid black;} RESULT {rendered in the browser} .box {width:
350px;}
Reference: MDN - box-sizing
This is a common problem devs come across.
If I have:
<div style="width: 200px"></div>
Then the width will be 200px wide.
If I add 10px padding, then I need to deduct 20px total from the width.
So to keep it 200px wide it must now be:
<div style="width: 180px; padding: 10px"></div>
It is possible to override this so the width doesn't need to be adjusted according to padding, but I feel you should stay true to CSS's intended way of working.
With does not override padding, the padding is added to the width.
Think of padding as extra width but outside of the element.
The width will not override the padding but the padding will still be
there so other elements will be pushed away from their position (if
relative).
Edit: Confused padding with margin.
Unless I completely do not understand the box-sizing property... why aren't those two DIVs next to each other?
http://jsfiddle.net/MK7Fs/
With box-sizing: border-box; shouldn't the padding, margin, and border "cut in" to the 50% width and ultimately end up with 100% width and with enough room to fit both DIVs?
Margin is not added in when using box-sizing : border-box. If you remove the left/right margins your boxes line-up on the same line.
I also noticed your <div> elements have white-space between the first one's closing tag and the second's one opening tag. When using display : inline-block this will add space between the elements and they won't line up on the same line.
Demo: http://jsfiddle.net/MK7Fs/1/
box-sizing Documentation: https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing
Some reading on the space between display : inline-block elements: http://css-tricks.com/fighting-the-space-between-inline-block-elements/
As Jasper said, margin is not added when using box-sizing: border-box. This day and age, however, we've got a new tool in our toolbox: calc.
You can give the boxes width: calc( 50% - 40px ); (assuming you've got a total of 40px of margin).
Demo: https://jsfiddle.net/htwj/yzh7zg25/
You're misunderstanding how border-box works. The box-sizing property will at most constrain the padding and border boxes of an element to its contents width & height.
The definition of the border-box value as stated in the Basic UI Module:
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.
It seems that when I have a table inside a div and I set the table to 100% width and give it some margin, it seems to disregard the rightside margin. Here is the fiddle for it:
http://jsfiddle.net/gFQGb/
The width applies to the actual content of the element, so you have a table with 100% wide content, and on top of that you add some margins pushing the width over 100%, thus the right side of the table extends beyond the parent's right edge. Probably you should go with padding on the parent instead of margin on the table, or an additional wrapper <div> with just the margin.
just add padding: 10px; to the .inner class and remove margin from the table.
Here is the demo
That's how the CSS default box model works: width of the element (defined via width: x) + borders + margins + padding = total amount of space it takes up.
http://css-tricks.com/the-css-box-model/
You can change the box-model by using box-sizing: border-box, which will cause the width: 100% to include your paddings/borders.
http://css-tricks.com/box-sizing/
What is the difference between margin and padding in CSS?
In what kind of situations:
both work.
only margin is appropriate.
only padding is appropriate.
TL;DR: By default I use margin everywhere, except when I have a border or background and want to increase the space inside that visible box.
To me, the biggest difference between padding and margin is that vertical margins auto-collapse, and padding doesn't.
Consider two elements one above the other each with padding of 1em. This padding is considered to be part of the element and is always preserved.
So you will end up with the content of the first element, followed by the padding of the first element, followed by the padding of the second, followed by the content of the second element.
Thus the content of the two elements will end up being 2em apart.
Now replace that padding with 1em margin. Margins are considered to be outside of the element, and margins of adjacent items will overlap.
So in this example, you will end up with the content of the first element followed by 1em of combined margin followed by the content of the second element. So the content of the two elements is only 1em apart.
This can be really useful when you know that you want to say 1em of spacing around an element, regardless of what element it is next to.
The other two big differences are that padding is included in the click region and background color/image, but not the margin.
div.box > div { height: 50px; width: 50px; border: 1px solid black; text-align: center; }
div.padding > div { padding-top: 20px; }
div.margin > div { margin-top: 20px; }
<h3>Default</h3>
<div class="box">
<div>A</div>
<div>B</div>
<div>C</div>
</div>
<h3>padding-top: 20px</h3>
<div class="box padding">
<div>A</div>
<div>B</div>
<div>C</div>
</div>
<h3>margin-top: 20px; </h3>
<div class="box margin">
<div>A</div>
<div>B</div>
<div>C</div>
</div>
Margin is on the outside of block elements while padding is on the inside.
Use margin to separate the block from things outside it
Use padding to move the contents away from the edges of the block.
The best I've seen explaining this with examples, diagrams, and even a 'try it yourself' view is here.
The diagram below I think gives an instant visual understanding of the difference.
One thing to keep in mind is standards compliant browsers (IE quirks is an exception) render only the content portion to the given width, so keep track of this in layout calculations. Also note that border box is seeing somewhat of a comeback with Bootstrap 3 supporting it.
There are more technical explanations for your question, but if you want a way to think about margin and padding, this analogy might help.
Imagine block elements as picture frames hanging on a wall:
The photo is the content.
The matting is the padding.
The frame moulding is the border.
The wall is the viewport.
The space between two frames is the margin.
With this in mind, a good rule of thumb is to use margin when you want to space an element in relationship to other elements on the wall, and padding when you're adjusting the appearance of the element itself. Margin won't change the size of the element, but padding will make the element bigger1.
1 You can alter this behavior with the box-sizing attribute.
MARGIN vs PADDING :
Margin is used in an element to create distance between that element and other elements of page. Where padding is used to create distance between content and border of an element.
Margin is not part of an element where padding is part of element.
Please refer below image extracted from Margin Vs Padding - CSS Properties
From https://www.w3schools.com/css/css_boxmodel.asp
Explanation of the different parts:
Content - The content of the box, where text and images appear
Padding - Clears an area around the content. The padding is transparent
Border - A border that goes around the padding and content
Margin - Clears an area outside the border. The margin is transparent
Live example (play around by changing the values):
https://www.w3schools.com/css/tryit.asp?filename=trycss_boxmodel
It's good to know the differences between margin and padding. Here are some differences:
Margin is outer space of an element, while padding is inner space of an element.
Margin is the space outside the border of an element, while padding is the space inside the border of it.
Margin accepts the value of auto: margin: auto, but you can't set padding to auto.
Tip: You can use the trick to make elements centered inside their parents (even vertically). See my other answer for example.
Margin can be set to any number, but padding must be non-negative.
When you style an element, padding will also be affected (e.g. background color), but not margin.
Here is some HTML that demonstrates how padding and margin affect clickability, and background filling. An object receives clicks to its padding, but clicks on an objects margin'd area go to its parent.
$(".outer").click(function(e) {
console.log("outer");
e.stopPropagation();
});
$(".inner").click(function(e) {
console.log("inner");
e.stopPropagation();
});
.outer {
padding: 10px;
background: red;
}
.inner {
margin: 10px;
padding: 10px;
background: blue;
border: solid white 1px;
}
<script src="http://code.jquery.com/jquery-latest.js"></script>
<div class="outer">
<div class="inner" style="position:relative; height:0px; width:0px">
</div>
</div>
The thing about margins is that you don't need to worry about the element's width.
Like when you give something {padding: 10px;}, you'll have to reduce the width of the element by 20px to keep the 'fit' and not disturb other elements around it.
So I generally start off by using paddings to get everything 'packed' and then use margins for minor tweaks.
Another thing to be aware of is that paddings are more consistent on different browsers and IE doesn't treat negative margins very well.
The margin clears an area around an element (outside the border), but the padding clears an area around the content (inside the border) of an element.
it means that your element does not know about its outside margins, so if you are developing dynamic web controls, I recommend that to use padding vs margin if you can.
note that some times you have to use margin.
One thing to note is when auto collapsing margins annoy you (and you are not using background colours on your elements), something it's just easier to use padding.
Advanced Margin versus Padding Explained
It is inappropriate to use padding to space content in an element; you must utilize margin on the child element instead. Older browsers such as Internet Explorer misinterpreted the box model except when it came to using margin which works perfectly in Internet Explorer 4.
There are two exceptions when using padding is appropriate to use:
It is applied to an inline element which can not contain any child elements such as an input element.
You are compensating for a highly miscellaneous browser bug which a vendor *cough* Mozilla *cough* refuses to fix and are certain (to the degree that you hold regular exchanges with W3C and WHATWG editors) that you must have a working solution and this solution will not effect the styling of anything other then the bug you are compensating for.
When you have a 100% width element with padding: 50px; you effectively get width: calc(100% + 100px);. Since margin is not added to the width it will not cause unexpected layout problems when you use margin on child elements instead of padding directly on the element.
So if you're not doing one of those two things do not add padding to the element but to it's direct child/children element(s) to ensure you're going to get the expected behavior in all browsers.
First let's look at what are the differences and what each responsibility is:
1) Margin
The CSS margin properties are used to generate space around elements.
The margin properties set the size of the white space outside the
border. With CSS, you have full control over the margins. There are
CSS properties for setting the margin for each side of an element
(top, right, bottom, and left).
2) Padding
The CSS padding properties are used to generate space around content.
The padding clears an area around the content (inside the border) of
an element. With CSS, you have full control over the padding. There
are CSS properties for setting the padding for each side of an element
(top, right, bottom, and left).
So simply Margins are space around elements, while Padding are space around content which are part of the element.
This image from codemancers shows how margin and borders get togther and how border box and content-box make it different.
Also they define each section as below:
Content - this defines the content area of the box where the actual content like text, images or maybe other elements reside.
Padding - this clears the main content from its containing box.
Border - this surrounds both content and padding.
Margin - this area defines a transparent space that separates it from other elements.
I always use this principle:
This is the box model from the inspect element feature in Firefox. It works like an onion:
Your content is in the middle.
Padding is space between your content and edge of the tag it is
inside.
The border and its specifications
The margin is the space around the tag.
So bigger margins will make more space around the box that contains your content.
Larger padding will increase the space between your content and the box of which it is inside.
Neither of them will increase or decrease the size of the box if it is set to a specific value.
Margin
Margin is usually used to create a space between the element itself and its surround.
for example I use it when I'm building a navbar to make it sticks to the edges of the screen and for no white gap.
Padding
I usually use when I've an element inside a border, <div> or something similar, and I want to decrease its size but at the time I want to keep the distance or the margin between the other elements around it.
So briefly, it's situational; it depends on what you are trying to do.
Margin is outside the box and padding is inside the box