Position fixed element with percentage width relative to container - html

I know that position: fixed makes an element relative to the viewport instead of it's offsetParent however I have an issue where I have a side element which takes x amount of space and then some fixed position heading elements which I want to take up a percentage of the remaining viewport width.
See fiddle: http://jsfiddle.net/U5DSZ/
Now I could put all the h1 element's into their own container but then they lose their semantic meaning as they are no longer associated with their content.
I understand JavaScript could do this but I am against using JavaScript for page structure.
Is there a way to do this in a purely HTML or CSS way? I don't mind moving the h1 element's as long as they retain their relationship with the content and the content remains statically positioned.

You can get the effect that you want as follows.
Your HTML snippet is good as is:
<div id="content">
<section>
<h1>Heading 1</h1>
<p>...</p>
</section>
<section>
<h1>Heading 2</h1>
<p>...</p>
</section>
</div>
and the CSS is good but just requires some explanation:
#content {
overflow: visible; /* default, but important to notice */
}
section {
float: left;
width: 25%;
}
h1 {
position: fixed;
width: 25%;
background: #00FF00;
text-align: center;
}
and the demo fiddle: http://jsfiddle.net/audetwebdesign/4zLMq/
How This Works
Your #content block takes up the remaining width to the right of your 200px left floated sidebar.
Within #content, you have two left-floated section elements that take up 25% of the parent container, which in this case, is the width of the view port panel.
Your child h1 elements have position: fixed, which means that their width of 25% is also computed based on the width of the viewport (not #content).
Case 1
If you want h1 and #content to have the same width, they need to have the same relative (25%) computed from the same containing block (view port in this case).
However, the value of 25% is not 25% of the remaining space after you account for the floated sidebar. However, maybe you can live with this.
Case 2
You could make the width values a bit easier to determine if you set the sidebar width to be a relative value. Using mixed units is always an issue.

tldr; Shorter and cleaner solution:
h1 {
width: inherit;
...
I stumbled upon this question, with a similar issue : my container's size can be user defined through resize:both (and moveable too!).
If I followed the accepted solution, it implied I had to apply the same props to my fixed header inside my container (top, left, width and height…).
Instead, inheriting the width from the parent container works properly. I found this way much simpler, and it makes more sense too, tested on major browsers and mobiles (demo).

Related

How to show full image size in a variable-height container, with an element above the image

I have a dynamic-height container (its height is specified in relative measurements), inside of it, two elements - a header, and an img, e.g.:
<div class="item">
<header><h1>Title</h1></header>
<img ... />
</div>
I want the image to show in its entirety. Its css is set with height:100% .
Because of the height that the header takes, the image is clipped a little bit below (it is has an hidden overflown edge), where I want its height to auto adjust (become smaller) to fit inside the container.
There is a solution, where I use calc(100%-[height of header]) for the height of the image, but since calc is not supported in all browsers I was wondering if there is a different more supported solution for this.
Here is a jsfiddle:
http://jsfiddle.net/7xLo7mr6/
(Apply the class fix to the container to apply the calc fix)
Perhaps CSS flex could be your solution for this one:
http://jsfiddle.net/7xLo7mr6/9/
Using flex-direction: column; and applying a max-width to the container (allowing the image to fill in the rest of the height after the header text while not stretching the width) could potentially solve your issue, but might cause you more troubles depending on what you're ultimately after.
Another option: http://jsfiddle.net/7xLo7mr6/11/
apply height: 7%; to the header and height: 93%; to the image
Make the clipping happen at the top of the image instead of the bottom:
http://jsfiddle.net/7xLo7mr6/13/
Apply position: absolute; to the header, give it a background: white; and width: 100%;, then apply a position: relative; to the container so that the header applies a width 100% to the container and not the body.
If you just want the image to shrink when its container shrinks, you can give it a max-width of 100%, and that will stop your image from growing so large it exceeds its container.
.item img {
height: 100%;
max-width: 100%;
}
It might be important to note that declaring height: 100% does not make elements 100% of the height of their containers, it makes them 100% of their own intrinsic height. The heights of elements are determined by their content, not the other way around. Read a full explanation here: https://stackoverflow.com/a/5658062/4504641.
http://jsfiddle.net/ingridly/337wrgj8/1/

Why does positioning effect div width?

I was fiddling with my web-app to try and get a div to wrap around some p elements. The structure looks like this, i.e. pseudo-code ...
<div id='outer'>
<p></p>
<p></p>
<p></p>
</div>
What I found is that if I set the outer div to
position:absolute;
instead of
position:relative
that the div would correctly wrap around only the p elements.
Otherwise it would extend all the way to the very right of the page, and I had previously had to set the width manually.
What is governing this behavior?
Also, the p tags use
display:inline
and the containing div just uses the default display.
This CSS below works well in my app.
// outer div
#mi_control {
position: absolute;
left: 580px;
top: 660px;
width: auto;
padding-top: 5px;
padding-bottom: 5px;
}
// p elements
.menu_bottom {
margin-left: 18px;
display: inline;
}
This is a common issue..
I quote:
Question: relative div takes 100% width automatically but absolute div only takes content width. why?
Answer: Setting position:absolute removes the element in question from the normal flow of the docment structure. So unless you explicitly set a width it won't know how wide to be. you can explicitly set width:100% if that is the effect you're after.
By default, a div element is set to display: block;. Block elements will be 100% of the width of the parent element.
When you set an element to position: absolute; it takes it out of the document flow and the element is no longer sized according to the parent element. It can mess with your layout though.
My recommendation is to set the div element to display: inline-block; - this will make it sized as per its contents, but will not remove it from the flow of the document.
#outer
{
display: inline-block;
}
I don't know exactly what rules governing this behavior but what you observed is the right behavior and is consistent across all browsers. A DIV takes minimum width when its position is set to absolute or fixed; otherwise it takes full available width.
The default value for width for a div element is auto.
This means that it will take up the full with of the available space, or more if the contents forces it to. If you use position: absolute however, you take the element out of the document flow. As there is nothing that it can relate to as the full width any more, it will use the width that the contents forces it to use.
The behaviour is governed by the spec. Absolute positioned elements have dedicated rules about how widths are calculated: http://www.w3.org/TR/CSS2/visudet.html#abs-non-replaced-width and http://www.w3.org/TR/CSS2/visudet.html#abs-replaced-width
Once it is set to absolute, it is taken out of the normal flow of content. Absolutely positioned elements always appear in the top left corner, unless otherwise specified. The element will also shrink to be only as big as it has to, because that's how position:absolute works
divs naturally have a width of 100%, so that is why you have to set the width manually. Relatively positioned elements behave almost identically to statically positioned elements. The only difference is how they can be moved
Not sure what you are seeing but even if your div is positioned absolutely, it will STILL wrap your P tags
http://jsfiddle.net/8MSDH/
you are seeing it at the bottom right because you set your top and left
left: 580px;
top: 660px;

Overriding the width of a parent element

http://www.mysecretathens.gr/kulte_test/as_index.html
I am trying to override the width of #kontainer in my <li> list at the bottom. I want the .nav3 list to be full width, 100% but I cant override the 700px of the parent element, #kontainer
What can I do? I tried the !important; rule, but that didn't give me the results I wanted.
When specifying percentage width, it calculates based off the parent's width. So 100% of 700 is... 700.
You need to specify a pixel width if you want it to go over 700.
Solution 1: You can get .nav3 out of #kontainer
Solution 2: You can add position: absolute; left: 0; to .nav3 and then add some margin-top on #footer tu push it down.
Width 100% means get 100% of the parent element that the child is inside. It actually does what you said it to do! You can get nav3 out of the #kontainer to take the 100% of the body element.
I want the same thing, to override the parent width.
I'm developing a Joomla component
<div class="container mainbody"> //** width 1170px **//
<div>some content</div>
<div>some content</div>
</div>
I don't want to change the width (1170px) of the outer div or .container class because it is default in Joomla template, which will take effect in every page if I change.
In my case, I only need a 100% width for some child div in my website's home page for some design.
What I did is add css in home page html file, since it will not call in other page.
<div class="container mainbody">
<div class="container">some content, width 1170px</div>
<div>some content, width 100%</div>
</div>
<style type="text/css">
.mainbody
{
width:100% !important;
}
</style>
For the div you want a full page width, you should use:
position: absolute;
left: 0px;
right 0px; //but make sure that any content you have below that div, gets margined in response.
margin-top: 200px; //Use the height of the above div
I have just noticed a "VERY" interesting (and bold) way of overriding the parent element's width. Set the child's width to something like:
width: calc(100% + 30%);
Believe it or not, at least Firefox 51 is calculating correctly the child's width, and yes, it is bigger than the parent's width.

height and width on html and body elements

If I have the following markup
<html>
<body>
<div id="wrapper">
<div id="container">
<p>Lots of pragraphs here</p>
</div>
</div>
</body>
</html>
with the following styles
html, body, #wrapper
{
width: 100%;
height: 100%;
}
#container
{
width: 960px;
margin: 0 auto;
}
why does not my html, body and wrapper elements extend to 100% height of the browser/view port in FF13. The html, body and wrapper stop vertically about some distance from the bottom when looking in Firebug. The container div extends to the full height as it's height is determined by the content.
(1263px X 558px for html, body, wrapper) and (960px X 880px for container)
Looking at default 100% the above happens as the first image below shows. But when I zoom to the last poosible zoom in, the above does not happen as the second image below shows and the html, body, wrapper extends to the full height.
(4267px X 1860px for html, body, wrapper) - (960px X 1000px for container)
Your html actually exactly extends to 100% height of your viewport cause viewport here is the browser window, not the inner content.
Consider this (jsfiddle):
<div id="div1">
<div id="div2">
<div id="div3">
very much content
</div>
</div>
</div>
#div1 {
height:300px;
overflow-y:scroll;
border: 1px solid black;
}
#div2 {
height:100%;
}
#div3 {
height:600px;
}
div1 here has the height of 300px and is scrolled. When you scroll content you simply move inner div but height remains untouched that is 300px. Exactly the same happens when you set height:100% to html. Your browser's height remains the same.
When you zoomed out your viewport then you have not scroll, so inner content's height is less than the height of viewport.
Shortly, html {height:100%} relates to parent's height not to the height of the inner content
UPDATE:
you can specify 3 types of values to the block-element's height:
length - set fixed height (i.g. '200px', '50em'). That's all, I can say nothing more about that.
percentage - from W3C spec:
The percentage is calculated with respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the value computes to 'auto'. A percentage height on the root element is relative to the initial containing block.
auto - The height depends on the values of other properties. (Generally on the height of inner content: text, other inline elements, block elements etc.)
What is happening when browser shows your page:
it gets height: 100% for <html>. That means that the resulting height is calculated with respect to the height of the generated box's (html-element in that case) containing block (initial containing block, i.e. browser window in that case). Let's say 1024px.
then it takes height: 100% for <body>. It will set body's height to the already calculated height of the html, that is 1024px.
then browser applies height:auto to the #wrapper and then the #container and the <p>. I don't know how it does that exactly but can suppose that it postpones the height setting (and respectively all other styles which depend on that i.e. backgrounds, borders etc.) and proceeds to the inner content.
next point is text content. Browser takes related properties specified or it's own, that is default styles, like font-family, font-size and the height of the text.
after that it will set height to the <p>-element so the <p> will stretch down to contain all content (the text in that case). The same then happens to the #container and the #wrapper.
If it happens that the height of the #wrapper is greater than the body's one (1024 px as it were agreed) than the overflow should be applied to the body. That is visible which is the default. Then overflow: visible is applied to the html. Then browser shows scroll for the entire window. Honestly, I don't know whether this is specified by the W3C spec, but can suppose it is.
So when you scroll the window your html and body are moved as are all the other elements. This is the same behavior as is with any other elements (like in jsfiddle I posted above):
Note that the background is set on the body element, but it extends to the entire canvas i.e. far beyond of the body element itself. This is towards your concern of the possible necessity of setting bg-property on the body. This is 100% compliant with the W3C spec which states (cutted):
For documents whose root element is an ... "html" element that has computed values of 'transparent' for 'background-color' and 'none' for 'background-image', user agents must instead use the computed value of the background properties from that element's first ... "body" element child when painting backgrounds for the canvas, and must not paint a background for that child element. Such backgrounds must also be anchored at the same point as they would be if they were painted only for the root element.
When you zoom out your page then browser recalculates all dimensions. Let's say, with each Ctrl + - click page shrinks, for example, for 20 %. Then all your text is reduced, cause its height depends on the font-size, which is affected by the Ctrl + - click, correspondingly <p>, #container and #wrapper all are reduced cause their height depends on text's height. But body and html both have height which depends on the window's height which is not affected by the Ctrl + - click. That is why you finally get this:
There is no difference here between width and height behavior in that case. You don't see the same issue with horizontal dimension simply because you've set width: 960px; for the #container which turned out to be less than your browser window's width, so no overflowing occurs. If the width of the #container were exceeding body's width you would see this:
This all is a normal and expected behavior and there is nothing to solve here.
Because you can never set the height to 100% if the element is relative to the browser window. The reason for this is that because of scrolling, your browser window could potentially be infinitely big. You will have to set a fixed height, or you will just have to set the height to expand to whatever is inside of it.
However width: 100%; is perfectly valid.
You will also need to use valid html tags. what I would do is, instead of using <wrapper> and <container>, I would make a class in your css. Class names are declared by starting them with a period.
.container{
width: 100%;
}
<div class="container"></div>
Good Luck,
-Brian

equalization 2 divs height only with css

I want to equal two divs height when a div height large
example :
<div style="float:left;padding:2px;background:red;">B</div>
<div style="float:left;padding:2px;background:green;">A<br />C<br />D</div>
<div style="clear:both;"></div>
the Div 2 height larger then div one
I may have a possible solution for you:
http://jsfiddle.net/adaz/wRcWj/1/
Well, it'll probably work on ie7+ so I'm not sure if that's good enough for you.
Brief description:
1) Set position relative to the container and self-clear it (I've used overflow: hidden but you can also use clearfix).
2) Float one of the divs inside so the container will expand depending on content inside.
3) Set position absolute to one of your divs, and give it top and bottom position 0px, this will make sure that it has 100% height.
Cons:
- Lack of IE6 support
- You need to chose which div will always have less content and then position in absolute
Hope it helps!
This is typically the behavior of a table, so you can do this with display: table-cell. I based an example on Adaz's : http://jsfiddle.net/L2uX4/
Wrap the two div's whose height you are trying to equalize in a container div, i.e.
<div id="container">
<div class="column">A<br/>B</div>
<div class="column">C</div>
</div>
Set an explicit height on the container and set height=100% on the columns:
div#container {
float: left;
height: 10em;
}
div.column {
height: 100%;
background-color: red;
}