Why do the CSS width and height properties not adj

2019-01-09 04:16发布

问题:

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?

回答1:

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:

  1. without squishing the content unreasonably
  2. 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.



回答2:

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.



回答3:

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.



回答4:

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 ;)



回答5:

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.