Why Does CSS Padding Increase Size of Element

padding increases width and height of div

You can use CSS3 box-sizing property to do this:

box-sizing: border-box;

http://css-tricks.com/box-sizing/

Supported in IE8+ but some browsers may require a prefix:

http://caniuse.com/css3-boxsizing

Is there a reason why padding adds to the size of an element?

There are two different so-called "box models", one adds the padding (and border) to the specified width, while the other does not. With the advent of CSS3, you can luckily switch between the two models. More precisely, the behaviour you are looking for can be achieved by specifying

box-sizing: border-box;
ms-box-sizing: border-box;
webkit-box-sizing: border-box;
moz-box-sizing: border-box;
width: 200px;

in your div's CSS. Then, in modern browsers, the div will always stay 200 px wide no matter what. For further details and a list of supported browsers, see this guide.

Edit: WRT your edit as to why the traditional box model is as it is, Wikipedia actually offers some insight:

Before HTML 4 and CSS, very few HTML elements supported both border and padding, so the definition of the width and height of an element was not very contentious. However, it varied depending on the element. The HTML width attribute of a table defined the width of the table including its border. On the other hand, the HTML width attribute of an image defined the width of the image itself (inside any border). The only element to support padding in those early days was the table cell. Width for the cell was defined as "the suggested width for a cell content in pixels excluding the cell padding."

CSS introduced margin, border and padding for many more elements. It adopted a definition width in relation to content, border, margin and padding similar to that for a table cell. This has since become known as the W3C box model.

Padding makes the element bigger instead of clear the space around the element

Let's say you got elements like this:

.parent{

padding:20px;

background:blue;

display:inline-block;

}

.parent div{

padding:20px;

height:80px;

width:80px;

}

.child1{

background:green;

box-sizing:border-box;

}

.child2{

background:purple;

}
<div class="parent">

<div class="child1"></div><br>

<div class="child2"></div>

</div>

Button height getting bigger when adding padding

Setting box-sizing:border-box; on your button or on all your elements (my advise) with * selector solves your problem.

*{
box-sizing:border-box;
}

button{
height:40px;
padding : 0.5rem;
}
<button>My button</button>

Why does child padding expand parent width?

A complex case of shrink-to-fit behavior. All your rows are flex items so their width depend on their content. Now the complex part is that you are making the child having width:100% which means 100% of the parent width so we have a cycle here.

In such case the browser will do the following:

  1. ignore the width:100% (consider it as auto)
  2. find the width of the child using other properties
  3. set the width of the parent based on (2)
  4. get back to the resolve width:100% based on the width found in (3)
  5. the width of child may change but not the one of the parent.

If one child is 100% then logically both cannot fit into one line and each one will be on its own line.

Here is a 2 steps illustration to understand what is happening:

body {
margin: 0;
font-family: Arial, Helvetica, sans-serif;
color: #C0C0C0;
background-color: #202020;
display: flex;
flex-direction: column;
align-items: center;
}

* {
box-sizing: border-box;
}
.col {
display: flex;
flex-direction: column;
}
.row {
display: flex;
flex-direction: row;
background-color: gray
}
.wrap {
flex-wrap: wrap;
}
.align-center {
align-items: center;
}
.justify-center {
justify-content: center;
}
.gap {
gap: 20px;
}
input {
background-color:#202020 ;
border: 1px solid #C0C0C0 ;
border-radius: 5px;
padding: 12px 20px;
margin: 8px 0;
box-sizing: border-box;
}
.inputContainer {
max-width: 300px;
width: 100%;
}
.inputContainer > * {
width: 100%;
}
<form class="col gap align-center" style="width: 90vw" action="">
<div class="row wrap gap justify-center">
<div class="col inputContainer" style="width:auto">
<label>expands:</label>
<input />
</div>
<div class="col inputContainer" style="width:auto">
<label>parent:</label>
<input />
</div>
</div>
</form>
<hr>
<form class="col gap align-center" style="width: 90vw" action="">
<div class="row wrap gap justify-center">
<div class="col inputContainer" >
<label>expands:</label>
<input />
</div>
<div class="col inputContainer">
<label>parent:</label>
<input />
</div>
</div>
</form>

Why does padding change the height of the child div with border-box set?

From the specification:

The position and size of an element's box(es) are sometimes calculated relative to a certain rectangle, called the containing block of the element. The containing block of an element is defined as follows:

..


  1. If the element has 'position: absolute', the containing block is established by the nearest ancestor with a 'position' of 'absolute', 'relative' or 'fixed', in the following way:
    1. In the case that the ancestor is an inline element, the containing block is the bounding box around the padding boxes of the first and the last inline boxes generated for that element. In CSS 2.1, if the inline element is split across multiple lines, the containing block is undefined.
    2. Otherwise, the containing block is formed by the padding edge of the ancestor.

So the position:absolute element will use 400px that include the padding

For other elements, if the element's position is 'relative' or 'static', the containing block is formed by the content edge of the nearest block container ancestor box.

The other one will use the content-box which is 400px - 20px so you won't have the same height

400*0.8 = 320 [positionned element]
(400 - 20)*0.8 = 304 [non-positionned element]

This is somehow logical since padding is a way to create space so it will get removed from the calculation when considering non-positionned elements. This logic is different for positionned element.

An example to illustrate:

.box {
border:2px solid;
padding:20px;
height:300px;
width:300px;
box-sizing:border-box;
position:relative;
}

.box > div:last-child {
height:100%;
width:100%;
background:red;
}

.box > div:first-child {
position:absolute;
width:100%;
height:100%;
background:rgba(0,255,0,0.5);
}
<div class="box">
<div></div>
<div></div>
</div>

What happens when the padding is bigger than the defined size?

Your element will have a width equal to 70px*2 + 1px*2 = 142px. The sum of the padding and border is bigger than the specified width so it's like you have width equal to 0 and only the padding/border are defining the final width

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. As the content width and height cannot be negative ([CSS2], section 10.2), this computation is floored at 0 ref

You can clearly see why the content width will end being equal to 0 and the final width is only the padding and border.

To express this using math, you have the following formula:

content-width + padding + border = final-width

And

content-width = max(0,specified-width - (padding + border))

I am using max() to express the fact that we take only positive value.

Do the calculation and you will get 142px

If specified-width - (padding + border) is positive, you will get the logical result of specified-width = final-width



Related Topics



Leave a reply



Submit