Max-height on border-boxed div with padding is not set
The property max-height
works on the height
of the element and you want to use it on the height
and padding-bottom
.
I think you are confused by the box-sizing
property that it changes the element height to the overal height including the padding top and bottom (also me). But this is not the case as you will see in the jsFiddle example.
An example:
- The element with content is
100px
in height. - The
max-height
is set to50px
(element is now50px
in height). - Now we apply the
padding-bottom
of100px
(more then the height of the element). The padding of100px
is added to the total height of the element making it150px
.
JsFiddle example: clicky
max-height ignored when percentage padding defines element height
The min/max width/height properties never take any other box dimensions into account, neither borders nor padding. They only constrain the used values of the width
and height
properties respectively. Section 10 of CSS2.1 does not explicitly mention borders or padding in the prose for the min/max properties, but it does refer to the width
and height
properties, both of which refer to content dimensions.
If you set height: 50px
, the element will still be constrained to a content height of 40px. The padding then extends from the content area.
Unfortunately, it appears box-sizing: border-box
does not address this fully, at least not when the borders and/or padding are in excess of width and height.
While I can infer that this happens as a result of browsers following the spec, why the spec was written this way I cannot answer objectively. Given that padding and overflow clipping can work together, I don't think the reason for this behavior has anything to do with overflow.
padding with max height
max-height
and padding
are 2 different properties. The last one won't be limited or affected by the first one.
So, to limit the overall height of the box you need to compute when 200px
is the 39.65%
of your parent width. Assuming this is the whole viewport that happens when the width is ~504px
. At that point with a mediaquery you just set the padding-bottom to 200px
;
.wrapper {
width: 100%;
padding-bottom: 39.65%;
height: 0;
box-sizing: border-box;
}
@media all and (min-width: 504px) {
padding-bottom: 200px;
}
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:
..
- 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:
- 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.
- 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>
CSS: padding-bottom and max-height on a div do not work well together
You can also use a pseudo and a negative margin
if you want things treated from ul and not its :last-child
: https://jsfiddle.net/g4c704yx/9/
ul.dropdown-menu{ border:1px #ccc solid; width:200px; max-height:100px; overflow-y:auto; } ul.dropdown-menu:before {/* using :before has its purpose, it will disseaper once the content will reach 200em height meaning content has an equal top negative margin, :after will always add 200em or will be swallowed if a negative margin is applied at content's bottom */ content:''; display:block; padding-top:200em;/* average 200 lines ? */}ul.dropdown-menu li:first-child { /* this margin-top has its purpose */margin-top:-200em; /* climb back up those 200 empty lines made of padding and i'm gonne pull up all my folowing siblings, i'm a leader, i'm a ladder !*/}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script><link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" rel="stylesheet"/><link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/><script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="dropdown"> <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown"> Dropdown <span class="caret"></span> </button> <ul class="dropdown-menu" aria-labelledby="dropdownMenu1"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li role="separator" class="divider"></li> <li><a href="#">Separated link</a></li> </ul></div>
Padding makes div bigger even though it has box-sizing: border-box;
As mentioned in the docs
border-box
...
The content box can't be negative and is floored to 0, making it
impossible to use border-box to make the element disappear.
...
What you could do, is to add the padding in the p
inside the .content
.
Why doesn’t height: 0 hide my padded div, even with box-sizing: border-box?
The exact definition of border-box
is:
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.
So you can modify the height and width properties, but padding
and border
never change.
As the content width and height cannot be negative ([CSS21], section 10.2), this computation is floored at 0.
Then, if height
is 0, you can't make the padding be inside, because that implies the height will be negative.
Related Topics
How to Shift a Background Image with CSS
Min/Max Width/Height with Multiple Values
Can the :Before and :After Pseudo-Elements Inherit Height from the Parent Element
How to Change Inline Text Height, Not Just the Line-Height
Cross-Browser 'Cursor:Pointer'
CSS Multiple Class/Id Selectors
Getting the Right Font-Size on Every Mobile Device
Applying Transition on Flexbox Justify-Content Property
How to Change Height of Ui-Grid Row
Input Background Colour Destroys Styling
Is the Hash Necessary in Svg Font-Face Declarations
CSS Linear Gradient Transparency Misbehaving Only in Safari
How to Use CSS Text-Overflow on Text That's Wrapping
CSS 3 or Svg Wave in a Background
Angular Material Mat-Spinner Custom Color