I am trying to have a header div inherit its width from its parent. The header div is position: fixed. The parent is contained inside a bootstrap container.
However, as you can see in the code I've created, it is not correctly inheriting the width of its parent - it is adding some extra width from somewhere.
This is all very annoying! Any idea how to fix this?
.category-body {
margin-left: 17% !important;
width: 67%;
background-color: red;
height: 500px;
}
.category-header {
position: fixed;
top: 51px;
width: inherit;
background-color: green;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<div class="category-body">We are in the category-body
<div class="category-header">We are in the category-header</div>
</div>
</div>
http://plnkr.co/edit/yVk15RqDqAac4H2eDJQe
The problem stems from using a percentage value on the parent width. Browsers seem to have a problem with this. (Tested on Chrome, FF & IE11.)
If you use pixel values the problem goes away.
Revise PLUNKR
From another answer:
It seems as though the static value (250px) can be propagated through
normal inheritance. Whereas when the relative value (90%) is being
used, the fixed div has already been taken out-of-flow, and now
inheritance-wise, it's parent is the viewport.
Learn more here:
position:fixed and width:inherit with percentage parent
How can I make a fixed positioned div inherit width of parent?
Set a Fixed div to 100% width of the parent container
Set width of a "Position: fixed" div relative to parent div
Set width of fixed positioned div relative to his parent having max-width
Fluid width fixed position
Related
I have an element in my Web Page <div class="col-md-12"></div>. Currently it is maintaining width of parent element. But if I apply position: fixed; on <div class="col-md-12"></div> it's width increases.
How to keep previous width with position: fixed; ?
set width to inherit so the child gets the width of the parent
width: inherit;
The CSS specification requires that position:fixed be anchored to the viewport, not the containing positioned element.
Other way to do it is :-
To set parent element position: relative; and child element position: absolute;
So I'm trying to build a modal window (with a white background) with HTML/CSS and I want the modal window itself to be fixed positioned relative to the browser window. In addition, the modal contains a child img at the top and a child div at the bottom that will contain some description text in it. My purpose is to position the child div relative to the parent fixed modal window so that the child div has a left offset of about 8.33% of the width of the parent.
So initially I thought I should absolute position the child div, but once I do that the background of the parent modal windows does not extend to the child div:
here is the html/css for the above:
html:
<div class="modal col-4 l-offset-4" id="robot-modal">
<img src="media/robot_modal.jpg">
<div class="col-10 l-offset-1">
</div>
</div>
css:
.col-10 {
width: 83.33333%;
}
.l-offset-1 {
left: 8.33333%;
}
.modal {
#include align-vertically(fixed);
display: none;
z-index: 2000;
background: white;
img {
width: 100%;
}
div{
position: absolute;
background-color: blue;
height: 100px;
}
}
But when I change the child div's position to 'relative', then the correct background will show up:
I don't get the intuition why I should always relative position an element inside a fixed parent. Wouldn't positioning an element as relative make it impossible to adjust offset relative to its parent ? According to this article: http://www.webdevdoor.com/html-css/css-position-child-div-parent , if we want to position an element relative to its immediate parent, the parent better be absolute or relative positioned and the child must be absolute positioned. So in my case why does adjusting the offset of a relative positioned child also work? I don't want to assign a height to the parent modal. i want it to automatically enlarge itself when new elements are contained in it.
A parent does not take into account the size of the absolute child. According to MDN:
Absolute: Do not leave space for the element. Instead, position it at a specified position relative to its closest positioned ancestor or to the containing block
If you put something after the absolute element, it goes on top, because the absolute element is no longer in the document flow.
You can do position: relative; left: 8.33%; right: 8.33%, or just leave it as static with margin: 0 8.33%;, or if you do absolute, you can set .modal { margin-bottom: [height of absolute DIV] }, if the height is set and won't change.
Children element not stretch parent container.
My code:
html:
<div class='window'>
<div class='wrapper'>
<div class='short'>short</div>
<div class='long'>long</div>
</div>
</div>
css:
.window{
width: 500px;
height: 100px;
overflow: auto;
background: gray;
}
.wrapper{
background: pink;
border: 1px solid red;
}
.long{
width: 700px;
background: beige;
}
example
I want .long stretch his parent .wrapper.
.wrapper width must be the same as .long (700px).
I can reach this by setting float: left to .wrapper.
But what happens here i don't understand, why it helps? What is the mechanism of such behavior? I need explanation, with links to w3c documentation.
What else can i do to extend .wrapper width?
By default, the .wrapper div is inheriting the fixed width you set on .window. You can float the .wrapper and set it's width to auto so the width expands without restriction to the parent.
CSS:
.wrapper {
float: left;
width: auto;
}
Example: http://jsfiddle.net/WTGAc/3/
Theory:
By default, the dimensions of wrapper are constained to the dimensions placed on it's parent, .window.
Floated elements still live within the parameters defined by their
parent element, ie the width available and horizontal position. They
still interact with text and other elements inside that parent element
(or other following elements). In that respect, they are quite
different from absolutely positioned elements, which are removed from
the document flow and don't interact with other elements ... but even
then, if they have a positioned ancestor then they are restricted by
the envelope of that ancestor and will use that as the basis for
calculating size and dimension (although they can still be made to
extend or exist outside that positioned ancestor).
Source of Quote
Since the element is floated and set outside of the normal document flow, it can now expand to the true width of the parent, instead of the fixed width initially defined.
Widths and the CSS Visual Formatting Model
In you example, you have the following:
<div class='window'>
<div class='wrapper'>
<div class='short'>short</div>
<div class='long'>long</div>
</div>
</div>
In the simplest case, .window is the containing block with a fixed width (500px). The child element .wrapper inherits the width from .window. The .long element has a width of 700px and it will trigger an overflow condition. Since .window has overflow: auto declared, the .window element will generate a horizontal scroll bar. Note that by using overflow: auto, .window establishes a new block formatting context, which is why the horizontal scroll bar appears on .window instead of the viewport/root element.
When you float .wrapper to the left, the .wrapper element defines an additional block formatting context. A new block formatting context will ignore the width inherited from its containing block and computes a new width sufficient to enclose the content (shrink-to-fit), which is why the pink background from .wrapper now extends the entire 700px in width.
You can trigger the same effect by adding position: relative to .window and position: absolute to .wrapper. However, this works because you set the height to .window, otherwise, the .window height would compute to zero since absolute elements are out of the flow and (unlike floats) will no longer affect how the .window content is laid out (not contribute to the height in this case).
As an aside, instead of using float: left on .wrapper, you can also try overflow: auto which will also establish a new block formatting context but this time the scrolling bar appears on .wrapper instead of .window.
The relevant documentation from w3.org is:
10 Visual formatting model details
10.3 Calculating widths and margins
10.3.5 Floating, non-replaced elements
Link: http://www.w3.org/TR/CSS2/visudet.html#float-width
I have a website with a gradient as background on the body. The .main div is absolutely positioned. I want it to have the same height as the content inside it, but how can I achieve that?
if the elements inside your absolute positioned div are positioned relative and have width and height you can apply this css to your .main div:
height:auto;
this will calculate the height depending on the height of all the content inside
Definitely do not have your main/container/wrapper div be absolutely positioned. Have it be positioned relatively.
<div class = "main">
<div class = "content">....</div>
</div>
Then you have your CSS:
.main {
position: relative;
margin: 0 auto;
}
.content {
height: 100%;
}
Look at this jFiddle: http://jsfiddle.net/persianturtle/3eJGr/
A great article on what absolute positioning really does can be found here
A segment:
Absolutely positioned elements are removed entirely from the document
flow. That means they have no effect at all on their parent element or
on the elements that occur after them in the source code. An
absolutely positioned element will therefore overlap other content
unless you take action to prevent it.
I have a DIV that has a width of 512px. Then inside that DIV is another DIV. I set the width of THAT DIV to 100%. However, it goes over which is not what I wanted.
I am trying to make it so it stays within the div. As in 5px padding on all sides.
http://jsfiddle.net/weka/USvTC/
This problem is happening because padding and border are not part of width: 100%.
Assuming you do want to absolutely position #exp_wrap, use this: http://jsfiddle.net/thirtydot/USvTC/1/
I removed width: 100% on .bar_wrap/#exp_wrap, and added right:5px; on #exp_wrap.
A block element such as a div defaults to width: auto, and takes the full available horizontal space. This is similar to how width: 100% works, except that padding and border are counted inside width: auto.
If #exp_wrap does not need to be absolutely positioned, use this: http://jsfiddle.net/thirtydot/USvTC/2/
I removed width: 100% on .bar_wrap/#exp_wrap again, and replaced position:absolute; top:5px; left:5px; with margin: 5px;. I also added overflow: hidden to .container to avoid collapsing margins.
Just set the width of the child element to 512-(2*5) pixels in width (502), not 100%.
Maybe the issue is the box-sizing of the child div. You can set it to border-box and then the child div shouldn't be longer than the parent div:
.child-div {
box-sizing: border-box;
}
You can read more here about the box-sizing property.