Why setting padding on a descendant element reduces content box width? - html

I'm in a confusion since yesterday. Actually I have a markup as follows:
<div class="container">
<div class="child>
<div class="descendant">Content</div>
</div>
</div>
And CSS:
.container {
max-width: 500px;
min-width: 100px;
}
The .container element has some width between 100px to 500px according to my content and the child & descendant elements have some other content without any specific width or min/max-width.
What happens is that when I apply horizontal padding to .container, its content-box size remains as is & just padding is added to it. But whenever I apply horizontal padding to any of the child or descendant elements, they do not add padding to their size or the parent's size. Instead, their content-box size reduces and they accommodate padding.
I seriously can't get what is going on here. Can anyone explain me what's actually happening?

The width describes the content width, which you explicitly set to a maximum of 500px. So long as there is room, the content width of the container will be 500px. If you add padding to the container, that doesn't affect the content width because nothing else constrains it.
The descendants, on the other hand, have their width constrained by the container. If you add padding to a descendants, the width is reduced so the whole box can still fit inside teh container.

This is just normal box model behavior. Adding padding to an element that isn't bound by a parent element restricting it's size will grow outward to accommodate the new padding. But if an element is contained within a parent with a fixed width, and you add padding to the inner element, it can't grow outward and force the bounding parent to grow - it can only reduce it's content-box to make room for the padding.
If you want the outer and inner divs to behave consistently, you can add box-sizing: border-box; to .container and the padding will not cause the element to grow beyond the specified width/height.

Related

How does 'min-height: 100vh' work when there are child elements that stack when width is small?

I have two child elements inside a parent element:
<div id="registration">
<div id="left-panel"></div>
<div id="right-panel"></div>
</div>
Styling:
#registration{
#include l {
flex-direction: column;
}
#left-panel, #right-panel{
width: 50%;
min-height: 100vh;
#include l {
width: 100%;
}
}
For simplicity, let's assume that there is no content in left-panel and there is content in right-panel (not shown)
I have made it responsive such that when the width is > l (i.e. 1025px), the two panels are side by side. When the width is < l, however, the panels will stack on top of each other.
I noticed that when they stack, the height of one, let's say left-panel, remains the same whereas the other one will increase to ensure that the contents don't 'spill out' of the element. Is this because I've set the height to min-height: 100vh? I ask because if I change 'min-height: 100vh' instead to 'height: 100vh', the content spills out.
So, it seems like min-height causes the parent element (i.e. right-panel) to change in height to contain all its contents. Can anyone confirm this?
Any help is appreciated!
There's nothing special about either flex or l in this regard.
min-height just sets the minimum height for the element - it's still allowed to expand in height of the content would exceed the height of the element, but never shrinks below the specified value:
The min-height CSS property sets the minimum height of an element. It prevents the used value of the height property from becoming smaller than the value specified for min-height.
Conversely, height is a fixed height where the element is not allowed to expand, and content will simply get cut off if there is more content than the element can accommodate:
The height CSS property specifies the height of an element. By default, the property defines the height of the content area.
If no height is specified, the default height: auto is used, which gives the element a flexible height based on the height of the content. The element will only be as high as is needed to accommodate the content, and will indefinitely expand to contain it.

Why does `min-height` impact the height of a div in flex layout?

I added a min-height on a div in a flex layout parent. It seems that the min-height impacts the div if its real height is greater than min-height.
Take below code as an example:
https://codepen.io/zhaoyi0113/pen/ejwJGM
I set 100px as min-height on the div but it gets overlay each other if its real height is greater than 100. In above case, I expect the div shows hello world in one block but it doesn't. If you inspect the dom structure you will find that the <p> doesn't extend its parent div height. How can I fix it?
Since you've set height 200px on the .div1 flex box tries to fit all the child elements inside 200px, but the min-height prevents it to fit all children within the 200px.
Depending on what you want to achieve you might want to change the height on the .div1 or add flex-shrink: 0 on .div2
try changing the height of the paragraph to inherit.
p {
height: inherit;
}
this will make it inherit the height from its parent.
see the result here
Alternative solution is to add display: table; to your div2.

Padding inside DIV

Why does adding some padding affects elements outside the DIV box? Padding isn't supposed to create some space between the border of the DIV and contents inside it? How can you create this space without affecting elements outside the DIv box?
How can you create this space without affecting elements outside the
DIv box?
Use box-sizing: border-box
From MDN:
border-box
The width and height properties include the padding and
border, but not the margin.
The reason that this property must be set is because by default the value for box-sizing is content-box. Again from MDN:
content-box This is the default style as specified by the CSS standard. The width and height properties are measured including only
the content, but not the padding, border or margin.
Assuming you have specified a content height or width, then padding will be placed around that. That moves the border outwards. That moves the margin outwards. That pushes nearby elements away.
You can change it by reducing the height and/or width to compensate or by using the box-sizing property to make height and width determine the distance between the outside edges of the border instead of the outside edges of the content.
Try looking into the box-sizing property...
https://css-tricks.com/box-sizing/
Today, the current versions of all browsers use the original "width or
height + padding + border = actual width or height" box model. With
box-sizing: border-box;, we can change the box model to what was once
the "quirky" way, where an element's specified width and height aren't
affected by padding or borders. This has proven so useful in
responsive design that it's found its way into reset styles.
The value you're after is border-box:
.class {
box-sizing: border-box;
}

difference between width auto and width 100 percent

Previously my assumption about width: auto was that the width is set to that of the contents. Now I see that it takes the full width of the parent.
Can anyone please describe the differences between these?
Width auto
The initial width of a block level element like div or p is auto. This makes it expand to occupy all available horizontal space within its containing block. If it has any horizontal padding or border, the widths of those do not add to the total width of the element.
Width 100%
On the other hand, if you specify width:100%, the element’s total width will be 100% of its containing block plus any horizontal margin, padding and border (unless you’ve used box-sizing:border-box, in which case only margins are added to the 100% to change how its total width is calculated). This may be what you want, but most likely it isn’t.
To visualise the difference see this picture:
Source
width: auto; will try as hard as possible to keep an element the same width as its parent container when additional space is added from margins, padding, or borders.
width: 100%; will make the element as wide as the parent container. Extra spacing will be added to the element's size without regards to the parent. This typically causes problems.
Width 100% :
It will make content width 100%. margin, border, padding will be added to this width and element will overflow if any of these added.
Width auto :
It will fit the element in available space including margin, border and padding. space remaining after adjusting margin + padding + border will be available width/ height.
Width 100% + box-sizing: border box :
It will also fits the element in available space including border, padding (margin will make it overflow the container).
It's about margins and border. If you use width: auto, then add border, your div won't become bigger than its container. On the other hand, if you use width: 100% and some border, the element's width will be 100% + border or margin. For more info see this.
As long as the value of width is auto, the element can have horizontal margin, padding and border without becoming wider than its container (unless of course the sum of margin-left + border-left-width + padding-left + padding-right + border-right-width + margin-right is larger than the container). The width of its content box will be whatever is left when the margin, padding and border have been subtracted from the container’s width.
On the other hand, if you specify width:100%, the element’s total width will be 100% of its containing block plus any horizontal margin, padding and border (unless you’ve used box-sizing:border-box, in which case only margins are added to the 100% to change how its total width is calculated). This may be what you want, but most likely it isn’t.
Source:
http://www.456bereastreet.com/archive/201112/the_difference_between_widthauto_and_width100/
The initial width of a block level element like div or p is auto.
Use width:auto to undo explicitly specified widths.
if you specify width:100%, the element’s total width will be 100% of its containing block plus any horizontal margin, padding and border.
So, next time you find yourself setting the width of a block level element to 100% to make it occupy all available width, consider if what you really want is setting it to auto.
When we say
width:auto;
width will never exceed the total width of parent element. Maximum width is it's parent width. Even if we add border, padding and margin, content of element itself will become smaller in order to give space for border, padding and margin. In case if space required for border + padding + margin is greater than total width of parent element then width of content will become zero.
When we say
width:100%;
width of content of element will become 100% of parent element and from now if we add border, padding or margin then it will cause child element to exceed parent element's width and it will starts overflowing out of parent element.
For positioning elements,
width: 100%, not relative to the parent, but the nearest positioned element.
If they are all statically positioned, it is the nearest parent element.
Using width:auto; + display:inline-block; in css giving awesome effect.
width : auto; makes element width auto for adjustment with another object using with display: inline-block; like if we have a div element and another one also div element and div elements are block level element so showing them together in one line use width: auto; and display:inline-block

Why won't box-sizing: border-box; work when applied to the container in 960.gs?

I'm using box-sizing: border-box to everything on my page. However, when I add padding to the container element in my 960.gs grid, it bumps the second grid to the next line. It does, however work as expected if I add it to individual grid classes.
<header role="banner" id="header">
<div class="container container_12">
<div class="grid_4">
logo here
</div>
<div class="grid_8">
tagline here
</div>
</div> </header>
Adding 10px of padding to .conatiner wraps grid_8 to the next line. Adding 10px to both grid_4 and grid_8 doesn't (box-sizing works). Any help is appreciated.
I believe it is working correctly.
box-sizing: border-box overrides the default behaviour where adding padding and borders to an (non-absolutely sized) element increases that element's total size. With border-box, all elements behave as if they've been absolutely sized with respect to padding: adding padding increases the internal space between the element's borders and its contents, but does not increase the total size of the element.
So what's happening is that by adding padding: 10px to .container, you decrease the amount of horizontal internal space available for .container's contents. And since .container's width does not grow (as specified by the box-sizing rule), and the child elements do not shrink, the second child must wrap, since the combined width of both child elements is now greater than the available internal space of .container.
Adding padding to the .grid_ elements "works" (your definition of "works" assumed to be that .container's children fit in one row and do not wrap) because according to the box-sizing rule, those elements should not gain width in addition to their set width (set by 960 gs) when they are given padding. The result of the added padding is instead to increase the space between the .grid_ elements' borders and their contents ("logo here" / "tagline here"), and to decrease the .grid_ elements' "internal width".
Basically, box-sizing: border-box means that padding (and borders!) gets added internally, rather than externally, and your example demonstrates this behaviour consistently.
Here is more info on box-sizing values, plus some demos.