Setting width/height in CSS only corresponds to the content area. Is there a way to set the offset width/height (i.e. dimensions including padding/margin/borders) of an element in CSS?
EDIT: Example ->
I have a number of divs tagged with css class "smallBox"
.smallBox{
width: 100px;
height: 100px;
}
Now I want to set the padding individually on each box, while having the overall outer dimensions stay the same.
Strictly speaking, sort of. You can change the box model used with the proposed box-sizing CSS3 property, such that the width specifies the total width of the object. Details can be found here (http://www.quirksmode.org/css/box.html).
However, browser compatibility is iffy (the article only mentions IE8+ and Firefox), so you will likely need to use JavaScript of some kind to achieve this.
Related
I'd like to imitate my favorite site and measure it grid arrangement:
How to measure its width of each part?
If you are using Google Chrome, you can see the width of every element in pixels, by opening Inspect Element (F12), and hovering over the element.
There are some useful JS properties and methods you can use via the Developer Console. This is useful if you have a list of elements you want to get dimensions for and want to get them at different browser dimensions.
You could type/paste in the following in the browser console:
console.log("#content width: " + document.getElementById("content").offsetWidth)
console.log("#answers width: " + document.getElementById("answers").offsetWidth)
Which would provide the following results that you could copy and paste out.
#content width: 1600
#answers width: 728
There may be a way to do this with the Chrome debugging protocol as well.
Here are some JS properties and methods that may be of use:
Use HTMLElement.offsetWidth for width as an integer. You can also use HTMLElement.offsetWidth for height.
MDN: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetWidth
MDN: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetHeight
The HTMLElement.offsetWidth read-only property returns the layout width of an element. Typically, an element's offsetWidth is a measurement which includes the element borders, the element horizontal padding, the element vertical scrollbar (if present, if rendered) and the element CSS width. If the element is hidden (for example, by style.display on the element or one of its ancestors to "none"), then 0 is returned.
Use HTMLElement.getBoundingClientRect() for fractional values:
MDN: https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect
The Element.getBoundingClientRect() method returns the size of an element and its position relative to the viewport.
I think following illustration will help you:
I was writing the layout of an app using the box-flex property (in Chrome) and I have found a strange behaviour, in my opinion, that I am wondering if might be a bug or that I just ignore the reason for those workings.
The code looks like this: http://jsfiddle.net/5tuCh/
There is a weird "div" resize when resizing the "textarea" so that the dimension of the "div" minus the "textarea" is equal to the dimension of the second "div", in order to satisfy "box-flex:1.0" I guess. Now if the reason for box-flex was making it easier to arrange the layout, this behaviour makes it unusable in this case.
Might it be that I am missing something?
Thanks.
This is in fact correct behaviour. From MDN:
The containing box allocates the available extra space in proportion
to the flex value of each of the content elements.
In your example, div.text boxes actually render with a height, meaning that any space beyond that would be spread evenly (or, rather, according to the flex ratio) between the elements. Setting height:0 on these elements would force behavior that I believe you're after (fiddle: http://jsfiddle.net/5tuCh/16/); I also had to remove the height:100% declaration on your textarea to prevent it from collapsing inside an element with zero height. I'd speculate that you may accomplish the textarea to take up full height of the parent element by setting its box-flex property as well.
Update:
OP's having issues with textarea behaviour could possibly be addressed by the following style:
textarea {
position:absolute;
top:10px;right:10px;bottom:10px;left:10px;
resize:none;
}
The parent element, of course, has to have position:relative set, which would result in the textarea taking up all available space in the container (w/10px spacing between the borders). Not sure if that's what you were after though. Fiddle: http://jsfiddle.net/5tuCh/36/
My question says it all. If we specify in css the width and height of textarea or text type form elements and don't use rows and cols property and size attribute respectively. Does it really matter? I would like to know are there any performance degradation's in the same on using on over the other.
width and height will override the values set for any sizing attributes, be it size or col and row (See: http://jsfiddle.net/Wexcode/Bmp65/). I would highly recommend setting the dimensions using width and height, since setting the size or col and row will lead to cross-browser inconsistencies.
The performance does not depend on the width and height properties itself, but on the way you specify your element in the stylesheet. For best results, reference the textbox by ID.
For instance
#thetextbox {width:10em; height:2em}
is faster than
form fieldset:nth-child(3) input[type="text"] {width:10em; height:2em}
setting height on input text is very dangerous!
on some systems the text may not be fully visible in the Y axis
safe solution is setting line-height instead of height
in textareas there is no problem (unless you want a textarea of one single row)
it is preferred to use cols rows and size attrbutes for backward compatibility, but if your audience are users with a modern browser css will be sufficient
HTH
edit:
<input type="text" style="font-size:20px;line-height:1;height:20px;"
value="ASDASDASD">
in firefox, "zoom text only" under View > Zoom
then zoom to 150%
this may happen on older firefox users, IE6 and probably 7 users (not sure)
where zoom applies only to text
in plus some systems have a native padding inside the textbox that you can't override,
a space used for focus rings/highlight outline, and it occupy some space that is included in the css "height"
if you remove height:20px; theres no problem at all I guess,
It is okay to use specify the width and height in css instead of using cols and rows. cols and rows really aren't good if you need the textarea to fit in a certain space, so using css is better.
if you use rows and col in your design , your page dose not displays good in different browser.using Css its better.
Use CSS!
The rows, cols, and size html attributes exist purely for style purposes.
In my opinion, you should leave the styling to CSS, so that you have separation of content and style.
It's the same reason we shouldn't be using the <font> tag, <blink> tag, style attribute, align attribute, etc.
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.
I am trying to give my div and textarea some padding. When I do this, it increases the size of the element, instead of shrinking the content area inside of it. Is there any way to achieve what I am trying to do?
You could add box-sizing:border-box to the container element, to be able to specify a width and height that don't vary when you add padding and/or border to the element.
See here (MDN) for specifications.
Update (copied comment to answer)
Right now, the value border-box is supported in all major browsers, according to MDN Specs
Some browsers of course requires proper prefix i.e. -webkit and -moz as you can clearly see here
According to CSS2 specs, the rendered width of a box type element is equal to the sum of its width, left/right border and left/right padding (left/right margin comes into play as well). If your box has a width of '100%' and also has margin, border and padding, they will affect (increase) the width occupied by the object.
So, if your textarea needs to be 100% wide, assign values to width, margin-left/right, border-left/right and padding-left/right in such a way that their sum equals 100%.
In CSS3 we have three box-sizing models. You can use border-box model:
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.
This was a mess on W3C part and various browsers only added to this complexity with their own versions of box models. Personally, instead of thinking which browser or CSS setting will do the trick I just wrap the box' content in yet another DIV statement and use margins on that DIV, instead of using padding, like this:
<div id="container" style="width: 300px; border: 10px solid red;">
<div id="content" style="width: 250px; margin: 25px;">
Some content
</div>
</div>
Although this only works for fixed size containers
It depends on the browser and it's implementation of the box model. What you are experiencing is the correct behavior.
IE traditionally got it wrong: http://en.wikipedia.org/wiki/Internet_Explorer_box_model_bug
For a more cross-browser solution, you can avoid this behavior, by wrapping whatever tag that needs padding into another tag with fixed width, and giving it width:auto. This way, if the parent has a width of x, and you add padding to the child, the child will inherit the full width of x, applying the padding correctly without modifying the parent width or its own.
A div by default takes the width of its parent container, so to avoid browser compatibility issues, you could add a child div in the specified div then add the required padding to the child div.
N.B - don't specify width to the child div because it would increase if you add padding