Incorrect resizing of fixed element's children - css

I have some nested divs that aren't resizing correctly with the window in Chrome 26 (stable), but they work fine in previous versions as well as in Firefox. Before I go file a bug report, I want to make sure what I'm seeing isn't expected standard behavior that my other browsers just aren't getting right.
Using Chrome 26, try resizing your preview pane on this Plunkr. The #inner element will either shrink or expand beyond the bounds of its parent, which I do not want it to do, and which it doesn't do in previous versions of Chrome or in Firefox.
Setting my #outer div to absolute positioning fixes the issue—except that I need the #outer div fixed in place. I've also noticed that removing position:absolute from #main also fixes the problem…but I need #main to be absolutely positioned.
I'm at a loss as to why this is happening, or even if this is expected behavior. I need the #inner child to resize with its #outer parent, not have the #outer element scale independently. How can I achieve this?
HTML/CSS
<!doctype html>
<html>
<style>
#main {
min-height: 100%;
position: absolute;
width: 100%;
}
#container {
min-width: 400px;
width: 50%;
margin: auto;
position: relative;
}
#outer {
position: fixed;
border: solid 2px black;
margin-top: 100px;
top: auto;
max-height: 150px;
position: fixed;
width: 50%;
min-width: 400px;
margin: auto;
background-color: green;
}
#inner {
background-color: rgba(0,0,0,.5);
padding: 10px;
border: 2px gray dashed;
position: relative;
}
</style>
<div id="main">
<div id="container">
<div id="outer">
<div id="inner">
<input type="text">
</div>
</div>
</div>
</div>

If you change the main container to position:fixed as shown below, it will fix the resizing issue. Don't know what effect that will have on page layout, but it is a similar look.
#main
{
position:fixed;
top:0;bottom:0;left:0;right:0;
background-color:#d3fcee;
}

Related

when css position sticky stops sticking

I was wondering why position: sticky works for some x-axis-scrolling, but once you scroll past the initial width of the screen width, your 'sticky div', stops sticking.
In this example, I have a left-side-bar that sticks to the left (please note that I cannot use position: fixed or position: absolute, because in my actual project both the left-div and the right-div need to scroll up and down along the y-axis, hence we only want left-side-sticking)
is there an additional CSS parameter I can define, such as
left-sticky-distance=999999%
or something like that?
some test code illustrating is below
<html>
<body>
<div style='
position:sticky;
z-index:1;
left:0;
width:100px;
height:200px;
overflow: hidden;
background-color:#ff0000;
opacity:0.8;'
>
</div>
<div style='position: absolute; top: 10; left: 10; width: 200; height:50px; background-color: blue'>B</div>
<div style='position: absolute; top: 10; left: 110; width: 200; height:50px; background-color: blue'>C</div>
<div style='position: absolute; top: 10; left: 210; width: 200; height:50px; background-color: blue'>D</div>
</body>
<html>
After I add the height: auto; into body's CSS attributes as below, this auto-hiding problem is fixed.
body {
background: #fff;
color: #444;
font-family: "Open Sans", sans-serif;
height: auto;
}
Hope it will be helpful to you. :)
This question: https://stackoverflow.com/a/45530506 answers the problem.
Once the "sticky div" reaches the edge of the screen, it is at the end of the viewport of the parent element. This causes the sticky element to stop and stay at the end of parent's viewport. This code pen provides an example: https://codepen.io/anon/pen/JOOBxg
#parent{
width: 1000px;
height: 1000px;
background-color: red;
}
#child{
width: 200px;
height: 200px;
background-color: blue;
position: sticky;
top: 0px;
left: 0px;
}
body{
width: 3000px;
height: 3000px;
}
<html>
<div id="parent">
<div id="child">
</div>
</div>
</html>
What i've just realized is that is stops sticking because you haven't captured an overflow. if you've specified an overflow: hidden;, then check that all content within that axis fits perfectly on all screen sizes and if not then make the necessary adjustments to make the content fit. This also happens when you have specified the height of a div and the content overflows past that height in a certain screen sizes.
I hope this helps anyone that made the same mistake i did.

Absolute positioning without content wrapping

I'm experiencing a nasty css problem I can't seem to solve.
I want to position a wrapper inside a container with the left property (in the positive direction; negative seems to work for some reason) without the content inside to start wrapping up.
Here is a jsfiddle for the following HTML and CSS.
<div id="container">
<div id="wrapper">
<div id="one"></div>
<div id="two"></div>
</div>
</div>
#container {
width: 200px;
height: 200px;
position: relative;
border: 1px solid #000;
/*white-space: nowrap;*//*Works for chrome, but not for firefox*/
}
#wrapper {
position: absolute;
/*left: 100px;*/
}
#one, #two {
width: 80px;
height: 80px;
background-color: #000;
margin: 10px;
float: left;
}
If you uncomment the left: 100px;, you'll notice the two boxes get moved but also wrapped. In chrome, this can be fixed using white-space: nowrap; on the container. It doesn't work for Firefox, though, and also affects the text content. I have tried removing position: relative; from the container and calculating the right offset with Javascript but that's somewhat inconvenient.
Edit: It does work with CSS3's transform: translateX(100px) but I'd still prefer the left variant.
Specifying a width for the wrapper seems to work in both Firefox and Chrome (and doesn't require the white-space property at all). The CSS for wrapper becomes:
#wrapper {
position: absolute;
left: 100px;
width: 200px;
}

Children element with height: 100% getting pushed by siblings

I have a very simple structure:
<div class="parent">
<h1>Element taking space</h1>
<div class="stretch">
Not much content, but needs to be stretched to the end.
</div>
</div>
The parent div has a set height, and I want div.stretch to stretch all the way to that height, regardless of how little content it has. Using height: 100% does the trick, until you add some other element which pushes the content down.
I guess that specifying height: 100% means that the element should have the exact same absolute/computed height as the parent element, and not the remainder of the height after all the other elements have been computed.
Setting overflow: hidden obviously hides the overflowing content, but that's not an option for me.
Is there any way I can achieve that in pure CSS?
Demo of my problem
In the time since this question was asked and answered, a better way to achieve this has come into existence: flex-box.
Just set the parent's display to "flex" and flex-direction to "column", and set the "stretchy" child's height to "inherit". The child will inherit a height of however many pixels are left over to fill up its parent.
In the following example, lines marked /* important */ are part of the actual solution; the rest of the CSS is just to make it visually easier to understand.
.parent {
display: flex; /* important */
flex-direction: column; /* important */
height: 150px;
border: 6px solid green;
}
h1 {
background: blue;
margin: 0px;
height: 90px
}
.stretch {
background: red;
height: inherit; /* important */
}
<div class="parent">
<h1>Element taking space</h1>
<div class="stretch">
Not much content, but needs to be stretched to the end.
</div>
</div>
You could float the h1 element. It would work no matter what height it is, and the content of the stretch element will be pushed below it. But I'm not entirely sure if this is what you are looking for.
EDIT: I'm not certain what kind of browser support you're looking for, but you could also set the display to table on .parent and then have .stretch inherit the height. Then you can nest the column divs inside of .stretch and float them.
Updated: http://jsbin.com/oluyin/2/edit
HTML
<div class="parent">
<h1>Element taking space</h1>
<div class="stretch">
<div class="col">Not much content, but needs to be stretched to the end.</div>
<div class="col">Not much content, but needs to be stretched to the end.</div>
</div>
</div>
CSS
.parent {
display: table;
}
.stretch {
height: inherit;
}
.col {
float: left;
width: 50%;
}
If you know the height of your H1 you can do this to fill out the child:
.parent {
background-color: #eee;
border: 1px solid black;
width: 300px;
height: 600px;
position:relative;
}
h1 { Height: 100px; }
.stretch
{
background-color:#dddddd;
position: absolute;
left: 0;
width: 100%;
top: 100px;
bottom: 0;
}
Example: http://jsbin.com/apocuh/1/edit
If you don't know the height of H1, I'm afraid you will probably need to use JavaScript or thgaskell's method.
Take a look at this post for more information, and an example with JS: CSS: height- fill out rest of div?
Maybe using display:table properties fits your needs ?
Edit: This answer actually looks like thgaskell's one, but instead of using floats I use table-row and table-cell display, and it seems to achieve what you are looking for.
Here is the jsfiddle : http://jsbin.com/ebojok/17/edit
.parent {
background-color: #eee;
border: 1px solid black;
width: 600px;
height: 600px;
display:table;
}
h1{
display:table-row;
width:100%;
}
.stretch{
vertical-align:top;
display:table-cell;
height:100%;
background-color: #ddd;
}
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
<div class="parent">
<h1>Element taking space</h1>
<div class="stretch">Not much content, but needs to be stretched to the end.</div>
</div>
</body>
</html>
CSS
.parent {
background-color: #eee;
border: 1px solid black;
width: 300px;
height: 600px;
position:relative;
}
.stretch {
background-color: #ddd;
height: 100%;
position: absolute;
top: 0;
}
http://jsbin.com/amesox/1/edit
This will cover your h1 element as the .stretched goes over it. You could get around this by using z-index: 1; on your h1 element, but I'd advise against it if you want text in your .stretched element.
You need position:relative; on your parent div to give position: absolute something to 'hook on' to. absolute positioned elements, ignore other elements and are placed on top of them unless their z-index is higher or they are its children.

Decoration outside the main div is unstable using CSS...?

I'm trying to make some decoration outside the main content div,
that would be getting hidden if the window size is small.
I thought for a while and came up with the following markup, (you can copy paste and see it),
and that's best I could think of right now. The problem however is that because I used percentage margins, the decoration gets unstable and shaky while resizing, and sometimes is even stepping on the content div.
Here's the code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<style>
body {
padding: 0px;
margin: 0px;
width: 100%;
height: 100%;
background-color: yellow;
}
div.content {
display: block;
width: 958px;
height: 400px;
background-color: #CCC;
margin: 0px auto;
}
div.wrap {
margin: 0px auto;
min-width: 958px;
max-width: 1058px;
overflow: hidden;
position: relative;
background-image: url(http://www.ephotobay.com/image/ooo-ml.png);
background-position: center;
}
div.left, div.right {
background-image: url(http://www.laserpros.com/images/site/HP_Circle_Logo_Vector1_small.jpg);
width: 50px;
display: block;
height: 50px;
bottom: 0px;
position: absolute;
}
div.left {
right: 479px;
margin-right: 50%;
}
div.right {
left: 479px;
margin-left: 50%;
}
</style>
</head>
<body>
<div class="wrap">
<div class="left"></div>
<div class="right"></div>
<div class="content">
<-- Content
</div>
</div>
</body>
</html>
So, could you recommend guys for some other way around without using percentage margins, to make it more flexible..? Thanks!
EDIT:
This is what happens in Google Chrome on resize:
As the browser has to re-calculate the margins based on the parent's width changes, this is kind of expected behaviour.
If you want to keep content centralized on the screen without playing with max-width, min-width and margins as percentage, and there won't be any element that should be affected by the .wrap position in the document flow, you could do something like this:
div.wrap {
width: 1058px;
overflow: hidden;
position: absolute;
left: 50%;
top: 0;
margin-left: -529px; /* 1058/2 * -1 */
background-image: url(http://www.ephotobay.com/image/ooo-ml.png);
background-position: center;
}
This will centralize the content horizontally in every situation.
Hope it helps.
Clear your floats:
<div>
<div class="left"></div>
<div class="right"></div>
<div class="clear"></div>
</div>
<style>
.clear{clear:both;}
</style>

CSS Fluid Layout?

I have a quick question about to how setup my basic fluid layout. I have one 40px high, and 100% wide header bar at the top, this looks great.
Then i have a #left and #right div, each floated respectively. This looks cool. They both have height 100% which works great but the issue is the page then scrolls 40px down, because there is the 40px from the header bar... if i use a fluid layout for the header and then the content box's it would look awful on a tiny or very large resolution.
Any ideas?
Here is my CSS
body
{
background: #ebebeb;
margin: 0;
padding: 0;
min-width: 750px;
max-width: 1500px;
}
#wrap
{
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
#header
{
background: #414141;
height: 40px;
width: 100%;
}
#sidebar
{
width: 30%;
background: #ebebeb;
height: 100%;
float: left;
}
#rightcontent
{
width: 70%;
background: #fff;
height: 100%;
float: right;
}
#footer
{
width: 100%;
background: #414141;
height: 40px;
clear: both;
}
And here is my html page:
<body>
<div id="wrap">
<div id="header">
head
</div>
<div id="sidebar">
side
</div>
<div id="rightcontent">
right
</div>
<div id="footer">
footer
</div>
</div>
</body>
Does that help :)
height: 100%; is a tricky thing for web pages, as you are no doubt keenly aware. Looking at your code in Firefox 3.5.7 the #sidebar and #rightcontent columns only have only the height of about an em — just enough to hold the text you put in them, not the full page length I think you were hoping for. The columns are trying to calculate percent height from the explicit height of their parent, but #wrap also has a %-based height, which causes this to fail (at least in my Firefox).
Now, as you've described it (the columns being the right height, except for an extra 40px scroll) what seems to be happening is that whatever browser you're using is passing the full height of #wrap as 100% of it's parent, which is <body>. So naturally, when your columns are sized to the height of <body>, which also encloses the height of your header and footer, the columns are too tall.
A trick I've used a couple of times to achieve the full page length appearance of columns that scales appropriately to whatever page dimension is to stick a position: fixed; bottom: 0px; <div> tag at the bottom of my page with just enough markup inside it to mimic the structure and relevant CSS of the columns.
Here's what I did to your page to get this effect:
<!--Add this to your HTML-->
<div id='columnfooter'>
<div id='sidecont'></div>
<div id='rightcont'></div>
</div>
/* And modify your CSS like this */
#sidebar, div#sidecont {
width: 30%;
background: #ebebeb;
float: left;
}
#rightcontent, div#rightcont {
width: 70%;
background: #fff;
float: right;
}
div#rightcont, div#sidecont {
height:100%;
}
#footer {
width: 100%;
background: #414141;
height: 40px;
position: relative;
bottom: 0px;
}
div#columnfooter {
position: fixed;
z-index: -25;
bottom: 40px;
height: 100%;
background: #ebebeb;
width: 100%;
}
Yes, using the HTML to form empty background columns this way does kind of mix semantic and stylistic markup — a technical no-no. But the CSS is clearly abstracted from the HTML, and with this code I have full page columns, #footer at the bottom (even when more than a page of content is added to either column above it), and it behaves the same in the latest versions of Firefox, Safari, Opera, Chrome and IE8 at any resolution (tested down to 800x600).
Hope this helps!

Resources