Why do the CSS width and height properties not adjust for padding? - html

So first a bit of meat to set the scene:
HTML
<div id="container">
<div id="inner">test</div>
</div>
CSS
#container {
width:300px;
height:150px;
background-color:#d7ebff;
}
#inner {
width:100%;
height:100%;
padding:5px;
background-color:#4c0015;
opacity:.3;
}
This will produce something that looks like this in all modern browsers:
Now I know this is the standards-compliant behavior (as I knew before, but reconfirmed in this post, and I also know that if I include this code in the inner CSS declaration:
box-sizing:border-box;
-moz-box-sizing:border-box;
-webkit-box-sizing:border-box
...it will adopt the "border-box" model and get the behavior that seems more intuitive to me, but I just found myself trying to logically justify the reasoning behind why this is the way it is and I was unable to do it.
It seems (on the surface of things) more logical to me for the inner box to always fill the container to exactly 100% of the container's width, regardless of the padding or border of the inner box. I run into this problem all the time when I'm trying to set the width of a textarea to 100% that has a border or something like a 4px interior padding...the textarea will always overflow the container.
So my question is...what is the logic behind setting the default behavior to ignore the border and padding of an element when setting its width?

The reason CSS uses the box model as:
+---------------------
| Margin
| +-------------------
| | Border
| | +-----------------
| | | Padding
| | | +---------------
| | | | Width x Height
Is because CSS is a document styling language. It was (originally) designed with research papers and other formal documents in mind, not as a way to make pretty graphics. As such, the model revolves around the contents, not the container.
CSS isn't a programming language, it's a styling language. It doesn't explicitly tell the document how it should be displayed, it suggests some guidelines the browser should follow. All of these can be overwritten and modified by an actual programming language: JavaScript.
Going back to the content-model idea, consider the following CSS:
p
{
background-color: #EEE;
border: 1px solid #CCC;
color: #000;
margin: 10px;
padding: 9px;
width: 400px;
}
height isn't specified, because the content defines the height, it may be long, it may be short, but it's unknown, and unimportant. The width is set to 400px because that's how wide the content (text) should be.
The padding is just a means of extending the background color so that the text can be nicely legible away from the edges, just like how you leave space when writing/printing on a sheet of paper.
The border is a means of surrounding some content to differentiate it from the other backgrounds, or to provide a border (go figure) between various elements.
The margin tells the paragraph to leave some space between edges, and with margin-collapsing, each group will remain evenly spaced without having to specify a different margin for the first or last element.
To maintain fluidity, width defaults to auto, which means the width will be as wide as possible:
without squishing the content unreasonably
without the padding extending beyond its container
Of course, in edge cases, the padding will extend beyond its container because the content might get squished. It's all about the content.

You might want to review the following at w3c: http://www.w3.org/TR/CSS21/box.html
The box model is such that the height and width pertain to the content area of the element. Padding is outside of that area which is why you see the inner box overflowing the outer one.
After padding comes the border, if any. Then Margin applies outside of the border. This means the elements actual width is defined as: Width + Padding + Border + Margin.
In effect, the css you have defines the inner box to have a 300px by 150px content area plus an additional 5px of padding beyond that which yields a box that is 310px by 160px.
Personally, I agree that the Width should include the padding. However, that isn't what the spec says.
As a side note, quirks mode does include the padding (and border) in the actual width. Unfortunately, quirks mode screws up so many other things that it's usually better to just deal with the w3c spec'd model than try and create all the css necessary to fix the other "quirky" things.
Another site (who agrees with you and I) is here: http://www.quirksmode.org/css/box.html
They mention that CSS3 includes the box-sizing declaration (as you've found) which is supposed to give you more control over which box model to use. It looks like just about everyone (IE8, chrome, Firefox) supports that which is good.

To answer your question, I think the logic is that it is all about the content; if you specify dimensions, these are the dimensions that the content is going to get.
But in the end it is just a choice that was made and that´s what we have to work with.

Look at the following picture:
Now consider what happens when you set the values width and height to 100% - should the padding and border just magically disappear from this picture? How would you as a developer ever handle that in a reasonable way?
width and height is width and height, border and padding is something else - to me it does't get anymore logical than that.
On the other hand
width and height is width and a height, but sometimes when you choose to set them to 100% they are also border and padding - now that would make no sense to me.
But then, one mans logic can be another mans nonsense, so i don't know if this will help you ;)

Although this may not have been an original intention of the CSS box model, another benefit is if you want something with an offset background image (e.g. the image is to the left or right of the text). Then you could specify the padding to be the width of the background image so that the text does not overlap it, and still specify a width for the text itself. For example:
.imageDiv{
width:200px;
background-image:url('someimage.png') /*this image is 50 px wide*/
background-repeat:no-repeat;
padding-left:50px;
}
Now any text entered into a div with the class imageDiv will show the image to the left of the text with any overlap.

Related

Wordpress How to make Slider Full-Width (Metaslider)

When I switch off the blog part and sidebars in the terrifico theme in Wordpress I don't seem to be able to place a full width slider anywhere.
The theme looks like this in the form that I'm talking about: http://vpthemes.com/preview/Terrifico/page-full-width/
As you can see all the text is 'bounded' by a box (the black line). Is there any way in which I can make the metaslider go OUTSIDE of this box (i.e. to span the FULL width of the page)? I don't necessarily want to get rid of the box all toghether, the text can stay within it.
I have seen on the Metaslider website that some solutions for certain themes are given (here - but I am not sure how to adapt this to the theme that I'm using.
Thanks in advance!
Disclaimer
Before I suggest a solution, I'd like to point out that what you're asking is to break the Box flow model. I wouldn't recommend that because you're likely to run into inconsistent results across browsers.
That said, what you're trying to accomplish is possible. You could use javascript to do this and it may in fact be easier in some respects but here's a CSS solution.
1. Break out of the box model
float: left;
width: 200%;
margin-left: -50%;
text-align: center;
The float CSS property specifies that an element should be taken from the normal flow and placed along the left or right side of its container, where text and inline elements will wrap around it.
The width of the container is still relative to its parent so if you use % units to scale it up you would need to compensate for the responsiveness of the parent. Here, I'm just overcompensating.
To ensure that our element remains centered, we use a negative margin that is half of the overflow. That is, we want our box to be 100% wide, we have 100% overflow to ensure that so half the overflow is 50% (comment below if that doesn't make sense).
We use text-align to put the element we add in step 3 in the center of the viewport.
2. Allow Overflows
This is where you may well break themes. The parent elements will hide elements that float outside of them if they have the overflow: hidden property (note overflow can also be used to show scrollbars).
You will need to ensure that the parent elements have:
#post-body, .content-posts-wrap {
overflow: visible;
}
As far as I can see that affects #post-body and .content-posts-wrap
3. Add an element that will be the right size
Now we have an oversized container for our slider but we need it to be the width of the page. Inside the div or whatever it is you want to put your slider into you will need to nest another element that will be the correct width. That element will need the following css:
display: inline-block;
width: 100vw;
text-align: left;
You need display because we are back to the box model now and we want our block to obey the width rule we give to it.
We set our width using vw (viewport width) units to make this a bit easier (but they may not be supported on your target browser). There may be some ingenius way to do this without vw units but I would probably just use javascript if it's not an option for you.
Finally, since we set our text-align above, we need to reset it here.
4. Add a Clearing Div
Because you've broken out of the flow, elements aren't too sure what to do. You probably want to add another element after your parent slider that
specifies whether an element can be next to floating elements that precede it or must be moved down (cleared) below them. source
It can be as simple as a <div> element with:
clear: both
write your code something like this...
html like that...
<div id="parent_for_slider">
<div id="slider">
//place your slider code
</div>
</div>
Css for that
#parent_for_slider{
position:relative;
}
#slider{
position:absolute;
width:100% !important;
height:auto;
}
i am recommending to use ResponsiveSlides.js for full width slider with responsiveness

CSS give different look in mozila and chrome

CSs for rate box:
.rating-input {
font-size: 25px;
position:relative;
left:101%;
}
Button:
.custom-input-button {
text-align: center;
position:absolute;
left:64.4%;
top:12.1%;
}
image :
<img src="https://graph.facebook.com/<?php echo $user_id; ?>/picture?type=large"
style ="position:relative; top:-46px; left:0px;"/>
It gives different look in chrome and firefox:
Firefox:
In chrome bookmark menu is not open. The change in spacing is due to that?
I am frustrated changing the positions, but problem does not solved.
I agree that your not giving us enough code to really give you a good response to.
If this helps at all, when I do custom form boxes as such, I wrap them in a div to start off with. Then define my widths/heights, and do a left float. This might be a deprecated method, and there may be a better way to do it, but this has always worked for me so I still tend to do it.
That should keep your elements all at the top, then you could do a clear:both, and float your rating system to the right? Just an idea.
Just to sum up conversation in comments.
You could make resizable containers with width in %. That will make your site adjustable to screen resolutions. Make it for minimum resolution of 15" display (1024px in width). Then position elements inside those containers. You can wrap them in another node of wrappers. More wrapper divs - the less can go wrong. But you don't want them too many, ofcourse. It depends on structure of your site. Then you can set margins and size of elements in px inside those containers.
Quick example of what babbling about in upper paragraph
jsfiddle.net/Driveash/qgbLB
You can also make extra css for specific browser.
Are left and margin-left the same?
Left and margin-left could do the same thing but they are not the same. Left is for positioned element (as absolute, relative, fixed). If you don't have positioned element then you want to use margin-left.
add z-index:-999; to the image so it doesn't sit in front of the green banner

CSS - make div's inherit a height

I'm trying to make a box with rounded corners where the height and width of the div depends on the content, so it's automatically adjust to it...
You can see the example here: http://pastehtml.com/view/1duizyf.html
The problem is that i can't get the "test_mid_left" (black background) and "test_mid_right" (turquoise background) to inherit the height from the "test_mid_center" (green background). I have tried height: 100% and auto, but none of thoose work. So how do I get them to inherit the height from the content?
(The reason why I have used "min-height: xx" in the left and right content on the example is just to show which boxes I am talking about)
As already mentioned this can't be done with floats, they can't inherit heights, they're unaware of their siblings so for example the side two floats don't know the height of the centre content, so they can't inherit from anything.
Usually inherited height has to come from either an element which has an explicit height or if height: 100%; has been passed down through the display tree to it.. The only thing I'm aware of that passes on height which hasn't come from top of the "tree" is an absolutely positioned element - so you could for example absolutely position all the top right bottom left sides and corners (you know the height and width of the corners anyway) And as you seem to know the widths (of left/right borders) and heights of top/bottom) borders, and the widths of the top/bottom centers, are easy at 100% - the only thing that needs calculating is the height of the right/left sides if the content grows -
This you can do, even without using all four positioning co-ordinates which IE6 /7 doesn't support
I've put up an example based on what you gave, it does rely on a fixed width (your frame), but I think it could work with a flexible width too? the uses of this could be cool for those fancy image borders we can't get support for until multiple background images or image borders become fully available.. who knows, I was playing, so just sticking it out there!
proof of concept example is here
The Problem
When an element is floated, its parent no longer contains it because the float is removed from the flow. The floated element is out of the natural flow, so all block elements will render as if the floated element is not even there, so a parent container will not fully expand to hold the floated child element.
Take a look at the following article to get a better idea of how the CSS Float property works:
The Mystery Of The CSS Float Property
A Potential Solution
Now, I think the following article resembles what you're trying to do. Take a look at it and see if you can solve your problem.
Equal Height Columns with Cross-Browser CSS
I hope this helps.
The negative margin trick:
http://pastehtml.com/view/1dujbt3.html
Not elegant, I suppose, but it works in some cases.
You need to take out a float: left; property... because when you use float the parent div do not grub the height of it's children... If you want the parent dive to get the children height you need to give to the parent div a css property overflow:hidden;
But to solve your problem you can use display: table-cell; instead of float... it will automatically scale the div height to its parent height...
Most of the times, the Previous parent has a heigt manually set, so you can use that value as reference, no other dirty tricks will be needed, and if the number is not the same for any reason maybe a comment can be added with the original number so in case you need to change it, by searching at the all the values, this one can be adjusted or even changed, in the time someone resolve this one for us.

How to make height squeeze with css

I've got an example mht file here that will help demonstrate my issue; if you are using FF then this addon will help you view the mht file. You will prob need to download the file and view it locally since github doesn't provide the right mime type for the file.
Basically my issue is this that I have a div which is 32px in height surrounding another div which is 29px in height, and I have no idea why the former is 32px tall.. It should be 29px tall afaict.. I don't want to set height:29px tho because if you resize the window so that the nav items take two lines then the height shouldn't be 29px for either div.
So what is wrong here?
make the following changes-
(-) to make your ul and wrapper div bottoms to align change class #navigationSecondary ul.base
to have a display:table; instead of display:inline-block;
(-) to remove the 3px of blue at the bottom change class #navigationSecondary to have padding:0; as sugested by Marcel.
the use of display: inline-block; on the ul.base is the cause.
when you use that it formats an element like it were inline (it only formats the actual content of the element like a block), so ul.base will have the usual 2-3px top and bottom "padding" that a normal inline element has. It's not really padding it's the leading vertical spacing i.e. it's what gives lines enough space to provide for the ascenders and descenders of letters like g, h, p, etc.
the use of it here is to make it seem like your ul is containing the floated child list elements. To make an element contain it's floated children there are other ways to do this, one way is, on ul.base
remove: display: inline-block
add: overflow: hidden;
[UPDATED] re the tabs.. sorry I didn't see them before I started
Here's the "float everything" solution to containing child floats as it applies to your code, with some other suggestions too
.menuContainer all it needs is position:relative; and the border-right rule
.navigationSecondary float it left with a width of 100%; (you can remove z-index it's not doing anything)
.wrapper float it left with a width of 100%, remove the height
ul.base doesn't actually need anything but remove the display-inline-block.. it's not containing the child lists but there's no effect involved, if you want to you can float it left with a 100% width too
[UPDATE 2]
I just copied this to a plain HTML document and I think that just changing the DOCTYPE to an HTML4 transitional one solves the problems with no changes to the code ?? (why that should change the display be I don't quite know! - but the use of "target=_parent" is "not allowed" in Strict Doctypes so that'll be why it's not validating)
I'll put it in JSBIN so others can try it out on various browsers
I changed it to:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
jsbin (with original HTML5 doctype) is here http://jsbin.comhttp://jsbin.com/agihe5/2/ - shows gap
jsbin with changed Doctype - but no changes to CSS code - with flash video to show dropdowns are working is here : http://jsbin.com/inare6/2 - no gap!
jsbin with no changes to Doctype, suggested changes to code and the flash insert to show z-index working is here: http://jsbin.com/iriya4
with the latter, code changes are detailed in the source, they have moved to the bottom of the snapshot CSS
I've tested the changed Doctype version as working in IE7, IE8, FF3.6.15, Safari4 (Win) and Chrome
Providing a test case which requires me to use Firefox and download an extension to view it is highly annoying.
I just did it anyway (purely because of the bounty), and the only change you need to make to your test case is:
On #navigationSecondary ul.base, add vertical-align: top.
The extra height is gone.
Here's a demo based on #clairesuzy's demo titled "jsbin (with original HTML5 doctype)".
(The only change was adding the aforementioned CSS rule):
http://jsbin.com/agihe5/3
The other answers may work (I didn't test them), but (providing I've understood the issue properly), this is by far the easiest fix.
Apparently #navigationSecondary has padding:0 0 3px; set in unnamed-1.css on line 2.
Everything inside ul.base has a height of 24px. Itself has a padding of 2px. So it's height is 26px. It's parent div.wrapper has a height of 29px, 3px extra. It's not caused by the 3px padding of div#navigationSecondary. Nothing is contributing the extra 3px so I'm suspecting a float issue. Anyway I managed to fix it by floating 2 divs.
Add float: left; width: 100%; to div.wrapper and div#navigationSecondary.
Remove display: inline-block; from ul.base.
Floating div.wrapper and div#navigationSecondary collapses them to their nearest floated child element, in this case li.base, and removes the extra 3px. 100% width brings back the stretch.
Hope this helps.
<body style="zoom:0.99; -moz-transform: scale(0.99); -moz-transform-origin: 0 0;">
adjust accordingly, and change hight and width around
Of course. This is simple. A very elementary element positioning issue.
inline-block default vertical-positioning
ul.base is an inline-block. which means that it has spacing calculated like a block, but positioned like an inline-element.
The default positioning of inline-element is to align on the baseline of text. However, text goes below the baseline for letters such as g, j, q etc. This is called "descenders".
The height of a box is always from the top of the font to the bottom of the descenders.
The wrapper takes on the height of its children. Which means that the inline-block ul.base, positioned on the baseline.
Your font at that particular size happens to have a 3-pixel descender. Voila. Your mysterious 3-pixel gap is merely the text's descenders. And your inline-block element is positioned on the baseline (i.e. on top of that 3 pixels).
Tests to confirm that this is right
Change font size. You'll see that 3-pixel changes. Change font size to small enough and it'll reduce to a 1px descender. Your so-called "gap" will shrink.
Change ul.base to something other than an inline-block (of course you have to add something to clear the floats inside). It will no longer have the 3 pixels at the bottom because a non-inline element is not positioned on the baseline.
Position ul.base on the absolute bottom instead of the default (baseline). That 3-pixel gap disappears. Use this CSS rule: vertical-align:bottom
Morale of the story
You always have to be careful with baseline positioning whenever you use inline-block display style.
Off topic
Handling font descenders is especially frustrating with Asian languages. As you know, CJK languages do not have characters that go below the baseline. However, they are typically placed on the baseline (so that they can inter-mix with other European languages, which have descenders). However, when one places a block of text with a background containing only Asian characters, the text will look like it is moved to the top, with an ugly empty gap on the bottom (the descender).

Not using widths & padding/margins on the same element?

I've seen numerous people mentions that you shouldn't use widths and padding or margins on the same element with CSS. Why is that?
Because some browsers treat the width as the total width of the element including the padding and the margins, and others treat the width as the base width to which the padding and margins are added. As a result your design will look different in different browsers.
For more information, see the W3C page on Box Model and quirksmode's take.
A lot of people still cling to notions about faulty box-models in IE and reckon that if you start messing around with element widths, padding and margins, you're going to get into trouble.
That's pretty outdated advice - assuming you're using a correct doctype, all fairly modern browsers (including IE6+) will work to the same box model, and you shouldn't really have too many issues related to it.
This being CSS, you will obviously have a million other cross-browser issues, but the infamous IE box-model is becoming a thing of the past.
I've never come across a problem caused by using width, padding and/or margin together.
So long as you have a valid DOCTYPE and are not in Quirks Mode, you will have a predictable box model and therefor should use whichever is most appropriate out of margin/padding to represent what you are trying to do.
Note:
Margin applies outside of borders, padding applies inside of borders.
Width means inner width of the container, the Total width = margin+border+padding+width (remembering that the first three are added for both left and right hand side).
Are you stating that padding and/or margin values shouldn't co-exist with a DOM element that also has a width value assigned to it? If so, that is only true if you do not want to write CSS that is compatible with both IE as well as browsers which implement web standards (e.g. Firefox). It would be difficult to achieve the layout you're looking for usually without some margin or padding value. But I suggest that you write CSS that is compatible for both browsers. If this is not what you are asking, then please correct me :)
The reason may be the famous box model problem.
Summary: IE renders width different then the standard rendering if padding and margin used with width or height.
I can think of 2 reasons:
1) the old "box model" of IE is really flaky, so when you have an element with the style { width: 300px; padding: 30px; margin: 20px;} it's outline might not actually match up to the expected 400px (300 px size, plus 2 30px padding, plus 2 20 px margin. I think its actual width would be 340, as it rolls the padding into the width calculation.
which brings is to...
2) Some people find the calculations a little confusing.
That said, I personally use widths along with padding and margins and have no problems with it. If you limit yourself to not using widths when using paddings/margins, that means you are peppering your code with a lot of non-semantic cruft. It does mean you have to be aware of what the various browsers are going to do with the element, but this is why we browsertest.
One important point to note is that it can make using percentage widths almost impossible. Take this for example, if you want your "content" div to take the full width, but have a 10px padding:
#content {
width: 100%;
padding: 0 10px;
}
That works in the (sensible, but incorrect) IE model, but in standards compliant browsers your div will occupy a width of 100% + 20px which is no good. The solution is to use another "inner" container.
<div id="content">
<div class="inner">
content here.
</div>
</div>
#content {
width: 100%;
}
#content .inner {
padding: 0 10px;
}
It's a bit annoying have the extra markup, but it makes a lot of things easier in the long run.