If I have very nested HTML code that looks something like this:
<body style="margin: 8px;">
<div>
<div>
<div>
Some content...
</div>
</div>
</div>
</body>
...and I want the innermost div to span the entire width of the screen on smaller devices, up to a maximum width, but not ignore the margin of the body, how can I best do that? If I set the width of the innermost div to 100%, it has no effect because the other divs are only as wide as their content, but if I set the innermost divs width to 100vw, then it ignores the margin of the body. Is there a simpler way than setting the width of all divs so that I can use %?
div elements are block-level elements, that means that they will be the full width of their parent container by default. Unless there are styles in the parent div elements that override this behavior, your innermost div will be full width while respecting any margin values of its ancestors.
If you have styles in the parent elements that override the block behavior, then you'll want to undo those changes for mobile sizes. This can be achieved using a media-query in CSS.
Here is a contrived example.
body {
margin: 8px;
border: 1px solid black;
}
.less-width {
width: 50%;
background-color: lightgrey;
}
#media (max-width: 450px) {
.less-width {
width: auto;
}
}
<body>
<div class="less-width">
<div>
<div>
<div>SomeContent</div>
</div>
</div>
</div>
</body>
How it works
The #media property of CSS takes in arguments where you can define the condition in which the nested styles will be applied. A common pattern is to check for screen width, and to write styles for mobile views with a max-width argument passed.
Inside the media query, I created a style rule that targets the ancestor of the content and sets its width back to the default behavior with auto.
If your actual code has all div elements as ancestors all the way up to the body, then you will want to look for style rules that override this behavior (such as flex, width, or display), and undo those styles in a media query.
If there are other elements as ancestors to your content, check that these elements are block-level elements. For example, a span is not a block-level element, so it will not take up the full width by default.
Related
I've been doing CSS for a while now but couldn't figure out what's going here. Feeling really dumb :) Could you explain the behaviour?
.parent {
display:inline-block;
}
.child {
border: 2px solid red;
padding: 20px; /* this works as expected */
padding: 20%;
box-sizing: border-box; /* makes no difference */
}
<div class="parent">
<div class="child">CSSisAwesome</div>
</div>
You are facing a cyclic calculation due to the use of percentage value. The parent is an inline-block element so its width is defined by its content and that same content is using a percentage value so the content need a reference for that percentage which is the width of the parent. You have a cycle.
In such case, the browser will first ignore the padding to define the parent width and then calculate the padding BUT we don't get to calculate the parent width again because will have an infinite loop.
Check this:
.parent {
display: inline-block;
}
.child {
border: 2px solid red;
}
<div class="parent">
<div class="child">CSSisAwesome</div>
</div>
<br>
<br>
<div class="parent">
<div class="child" style="padding: 20%;">CSSisAwesome</div>
</div>
Note how in both cases, the width of the parent is the same and that width is defined by the content. The padding is added later and create an overflow.
You can find mode detail in the Specification
Sometimes the size of a percentage-sized box’s containing block depends on the intrinsic size contribution of the box itself, creating a cyclic dependency.
Related questions:
Why does percentage padding break my flex item?
CSS Grid - unnecessary word break
How percentage truly works compared to other units in different situations
As seen in this CSSTricks article, padding using percentage units is in relation to the parent container, not the content within the element. The 20% padding you're setting in your code snippet is in relation to the .parent div's dimensions, not in relation to the content within the .child div.
If you are using % as a unit, Parent should have fixed width and height
I am trying to create an audio player, with playbutton, progress bar, and stop button. I want it to be fixed to the bottom of the page.
So to do this I have the following CSS:
.player-container {
height: 100px;
background-color: #505050;
position: fixed;
bottom: 0;
width: inherit;
}
Now, the weird thing, is what happens to the width. The player container is contained in a Bootstrap container. It usually starts in the correct place, but depending on the width of the browser, it seems to bunch up all small - or it seems to be the normal length, plus the size of the padding, which is really odd.
Here is the HTML:
<div class="container">
<div class="test"></div>
<div class="player-container" ng-show="showPlayer" ng-controller="PlayerController">
<span class="glyphicon glyphicon-play music-control"></span>
<div class="seekBase" seek-track></div>
<span class="glyphicon glyphicon-stop music-control" stop-music ng-click="stopClicked()"></span>
</div>
</div>
I've created a plnkr to display what is happening, with different color backgrounds to make it all very clear:
http://plnkr.co/edit/MU4aK6Wf4UUmQh4egqU7
Is the 'position: fixed' causing all this to go crazy? Ideas on a postcard....
The inherit keyword sets the specified and computed values to the computed value of the same property on the parent element.
The problem is that bootstrap may set some width to the parent .container depending on the width of the browser (by using min-width #media queries).
When the browser is narrow, the parent .container has no cascaded value for width. Therefore, sincewidth is not an inherited property, the specified value is auto. For width, auto computes to auto. Then, inherit makes .player-container have an auto width too.So width: inherit does not affect .player-container in this case.
If you want this behavior when the browser is not narrow, remove width: inherit and let it be auto.
However, when the browser is wider, .container may have widths like 750px, 970px or 1170px. In this case, .player-container will inherit that same width.
If you want this behavior when the browser is narrow, use width: 100%.
I wanted to ask how I can define a div's minimum height in css.
For example if I am on a small screen and the line break has changed, the div should be automatically resized, but it should be at least 100%.
Just use min-height to keep the div height 100% or higher like this:
HTML:
<div class="someName">
<!-- child elements -->
</div>
CSS:
.someName {
min-height: 100%;
}
I've set my html body tag heigth to be 100% but in Firefox that shows as a few more pixels than the screen has, so a nav scroll bar appears. How can I adjust that other than specifiying an arbitrary height :98%? I've set padding and margin to zero.
I'm using only bootstrap for css, if that's of any importance.
Check elements inside the body. One of it probably has margins or even content goes outside the body element. Just try to delete all inner elements one by one in Firefox's dev.tools and notice what element deletion will solve the problem.
Just to follow up the answer above, I noticed that padding can cause the same effect, but can only be noticed when inspecting the elements.
<button class="sbtn">
<span class="text">
my btn
</span>
</button>
.sbtn {
height: 5vh;
background-color: red;
}
.text {
padding: 10vh;
color: white;
}
Try adding this to your main CSS file.
/* CSS */
* {
box-sizing: border-box;
}
border-box tells the browser to account for any border and padding in the values you specify for an element's width and height. If you set an element's width to 100 pixels, that 100 pixels will include any border or padding you added, and the content box will shrink to absorb that extra width. This typically makes it much easier to size elements.
CSS box sizing
Suppose I have this HTML structure:
<div class="a">
<div class="floated-left">...</div>
<div class="floated-left">...</div>
</div>
I have noticed that if I don't set overflow:hidden to .a, then the <div class="a"> does not occupy any vertical size. For example, if I set its background to red, it is not visible at all. Inspecting it with FireBug shows that it's there but of almost no vertical size.
To fix this, I found that I have to set overflow:hidden to .a. Then the first <div> goes over all its content.
Here is a real example:
<html>
<head>
<style>
.a { background-color: red; }
.b { background-color: red; overflow: hidden }
.floated-left { float: left; width: 100px; height: 100px; background-color: blue; }
</style>
</head>
<body>
<p>div with class a, that doesn't overflow:hidden:</p>
<div class="a">
<div class="floated-left">Hi,</div>
<div class="floated-left">Mom!</div>
</div>
<div style="clear:both"></div>
<p>div with class b, that does overflow:hidden:</p>
<div class="b">
<div class="floated-left">Hi,</div>
<div class="floated-left">Dad!</div>
</div>
</body>
</html>
Notice how Hi, Mom! does not get red background (no overflow:hidden), while Hi, Dad! does get red background (has overflow:hidden).
Can anyone explain this behaviour?
Here is screenshot of the example:
Thanks, Boda Cydo.
When you float elements they are taken out of the document flow. Among other things, this means that they have no impact on the dimensions of the parent element (although its width will determine where the floats are positioned on the horizontal axis). They do however impact positioning of siblings within the container depending on whether those sibling are inline or block level elements and whether they have width or not.
In order to make the height of the floats impact the height of the container you must have an element after them that clears them. However, what you are seeing here is actually a part of the CSS standard that you can use to clear floats without additional, non-semantic markup. The only issue is this behavior can vary slightly in older browsers and their css implementations. This effect is present with both overflow auto and overflow hidden but does not present with overflow visible. In IE < 6 you must have a width set on the containing element for it to work.
Hi, Mom does not get any background because the background comes from the a div, which is height 0 (or near 0). The inner divs are actually overflowing its bounds (which is what floats do by default).
The thing to remember with floats is that they don't have inherent height (when it comes to layout and determining the parent's height). Inline content simply flows around them. So without overflow: hidden the parent div has no height. No height means no background. The floats are still rendered but they go beyond the bounds of the parent div ie the content in the floats is outside the parent div.
Floated elements don't occupy any vertical space for clearing, there are a few ways to fix this, something like:
<div class="a">
<div class="floated-left">Hi,</div>
<div class="floated-left">Mom!</div>
<br style="clear: left;" />
</div>
Would clear after, and make the outer div have a vertical height. Set a border: solid 1px red; on .a to see this in action.
Alternative CSS only solution:
.a:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
Per the spec for CSS basic box model:
Margins of a floated box do not
collapse with any other margins.
Margins of a box with ‘overflow’ other
than ‘visible’ do not collapse with
its children's margins.
By providing it the "overflow" property explicitly you have allowed the children to fit into this model, thus the b div no longer has bounds attached to its children. If you apply visible or inherit (which the parent of b is visible by default), the bounds return and the children divs define the margins.
http://www.w3.org/TR/css3-box/ (RE: Example X)