Using negative display-sticky CSS for vertical alignment - css

I'm trying to (mis)use display:sticky in order to replace the (mis)use of floats in page layout.
I found there's this nice behaviour that aligns a sticky element to the edge of the opposite side no matter how much further you try to push it and I'm exploring how it may be used.
For example, if there's a sibling of unknown height (or even more siblings, floats can only deal with just one), it can be vertically aligned nicely, with something like {position:sticky;bottom:9999px;}.
It works well, but with one side effect: the pushed element still takes its original space at the bottom, adding its own height to the height of the wrapper and thus pushing everything else lower.
.wrapper {
border:1px dashed black;
width:500px;
}
.main {
background:#eee;
width:300px;
margin-left:200px;
}
.aside {
background:#aaa;
width:200px;
position:sticky;
bottom:9999px;
}
<div class="wrapper">
<div class="main">
there is some stuff of unknown height.<br/>.<br/>.<br/>.<br/>.<br/>.<br/>.<br/>.<br/>.<br/>.<br/>.<br/>.<br/>.<br/>.<br/>
</div>
<div class="main">
and there some more.<br/>.<br/>.<br/>.<br/>
</div>
<div class="aside">
this goes nicely to the top without float or absolute positioning // but still occupies it's spot at the bottom ↓↓↓
</div>
</div>
I want to get rid of that space, but:
with pure css / no extra markup
no position:absolute / would be even worse than floats
no display:grid / it's overkill until masonry is supported, it would need extra js in the overall context.
I tried with a negative bottom margin, but it doesn't work, no matter how high I set it. Neither does hiding the overflow of either the element or the wrapper. Also, couldn't find anything in the dom inspector hinting to what generates it, but maybe I didn't know where to look.
Wouldn' be surprised that it's either not possible at all or it's just stupid simple.

Related

Firefox css table cells don't respond like other browsers with position:absolute

I have been creating a layout system in Javascript for application windows... The Javascript produces the code listed below...
Everything is working really well, except Firefox seems to have different rules for CSS tables than other browsers.
It seems that Webkit browsers set the context for sizing CSS table-cell elements to the nearest relatively/absolutely positioned parent element, just like normal elements, and from this we can treat each cell as a new context for sizing and positioning things absolutely.
Firefox does not appear to do it this way.
Here's sample code:
<div class="header"></div>
<div class='table'>
<div class='row'>
<div class='cell'>
<div class='wrap'>
<div class='pane'>
Content here that is long enough to wrap at the sides. Content here that is long enough to wrap at the sides. Content here that is long enough to wrap at the sides. And still hit the bottom.
</div>
</div>
</div>
<div class='cell' style='background-color:orange; width:230px;'>
cell2
</div>
</div>
</div>
and css:
.header {
height: 50px;
width: 100%;
background: blue;
}
.table {
width:100%;
height:200px;
display:table;
}
.row {
display:table-row;
}
.cell {
display:table-cell;
background-color:red;
position:relative;
}
.wrap {
display:block;
position:absolute;
background-color:purple;
width:100%;
height:100%;
}
.pane {
background-color:green;
height:100%;
width:100%;
position:absolute;
}
Which can be viewed here: http://jsfiddle.net/XmUZ7/3/
This viewed in Webkit (Safari/Chrome) vs. Firefox/Mozilla exemplifies the issue.
I've tried adding a .wrap element into the cell but it doesn't seem to help reset the context. Am I thinking of this the wrong way? Other posts on SO seem to imply that the cell or the .wrap needs to be an inline-block, but those also don't seem to work.
Here are some other links related to this:
Positioning context on table-cell element in Firefox
css absolute position inside table-cell: strange Firefox display
CSS Positioning Absolute within table cells not working in Firefox
https://bugzilla.mozilla.org/show_bug.cgi?id=203225
At this point I am considering not supporting firefox because I've spent so many hours trying to fix it. But this seems silly because everything else is working well across browsers except for basic layout!
It feels like either there is a magic bullet I'm missing or that Firefox has deep design issues that will not allow this.
I think JSFiddle has gotten around this issue by using iframes and no tables at all in its layout, but it does imply there are bugs being avoided.
Your basic issue is that specifying position: relative on a table cell in Gecko does not make the cell a containing block for absolutely positioned kids. See https://bugzilla.mozilla.org/show_bug.cgi?id=63895
The spec's take on this is at http://www.w3.org/TR/CSS21/visuren.html#choose-position:
The effect of 'position:relative' on table-row-group,
table-header-group, table-footer-group, table-row,
table-column-group, table-column, table-cell, and table-caption
elements is undefined.
What you want to do in the short term is put your position:relative on a block inside the cell (e.g. your "wrap" block).
Yes, that is exactly the issue. It should be defined!
So, is it decided that the Gecko renderer will not reset the sizing context for children of tables (IE the meaningful bits, like cells, who may want to request 100% of width and height) like other renderers?
It seems like cells should be a sovereign space for new sizing...

Float mistake in arbitrary-width div positioned absolutely

again a problem with IE browsers version 6 and 7
Take a look at an example right away, try resizing the window and such.
a preview (easier to open in IE this way)
code
HTML:
<div class="container">
<div class="left-menu">
<ul>
<li>El1</li>
<li>Element 2</li>
<li>3</li>
</ul>
</div>
<div style="margin-right: 60px;">Тест Тест</div>
</div>
CSS:
.container{
position:absolute;
top:100px;
left:100px;
outline: 1px solid red;
background-color:pink;
}
.left-menu{
outline: 1px solid green;
background-color:#AAA;
width: 50px;
float: right;
}
Now I don't understand 2 things
What happens to the float element? the box is never too small, infact the margin of the adjacent div is bigger than the width of ul div. But when the window is small enough the float element appears to be floating to the window edge not its container edge, but if you scroll a little to the right when the window is small you will see the container is wide enough.
Less important issue why is it this wide? Shouldn't it be as wide as it's contents?
The only fix I've come up with is to give my absolute div a width, but there is the problem. It should resize with the contents say if there is a picture near the float div.
And there will be a picture =) This width workaround of course allows to use tons of javascript, to resize every element in the more complex structure than shown in the example, but i wonder may css be used instead?
Internet Explorer has issues with divs and floats, especially older versions of IE. Whenever I have problems with floats and divs not clearing each other properly, I rely on the Clearfix method.
Add the clearfix css to your main css file, then append the class .clearfix to .container so it looks like <div class="container clearfix">.
For the 2 divs inside, take the margins and widths off of them, if you want those 2 divs width to change based on the content inside them. Float one div left, and float the other div right.
You'll see that the Clearfix forces the parent div (.container) to wrap all the way around the floated elements inside.
Hope this helps!

CSS positioning (margin / padding) with markup constraint

I have two sibling divs sitting below each other, both contained in the same parent div.
The requirement is that the divs need a certain amount of space between them, let's say 20px, but the space beween the inner divs and the parent div needs to be the same on all sides (top, right, bottom, left), in this case 0px.
The constraint here is that the inner divs need to have the exact same markup, so I can't apply a different or additional class to just one of them. Also I can't add any markup between the child divs or only above or below one of the child divs.
What would be a good way to solve this problem with CSS (no javascript), in a cross-browser compatible way?
Thanks!
#parentdiv div {
margin-top: 20px;
}
#parentdiv div:first-child {
margin-top: 0;
}
should do it. Alternatively, you could try
#parentdiv div + div {
margin-top: 20px;
}
Which solution to use depends on browers’ support of either the :first-child pseudo-class, or the + adjacent selector. Any modern browser (thus, discounting IE6) should support both.
you could insert another div inbetween them and make its height 20px? or is putting the first inner div into a new div and then making the new divs bottom margin 20px an acceptable solution?
As others have already stated, you cannot use a pure CSS approach that will work in IE6. However, why not use a minified, basic jQuery framework - without the ui it will be tiny - and then you can call the first child and apply the margin to that:
$("#parentdiv:first").css({ marginTop: 0 })
That way you'd have already applied the margin-top:20px; in your css, now you're removing it from the first child only. I know you said you did not want a javascript approach, but you're not left with much choice, unless you're willing to re-engineer ie6 and resurrect him for us?
Hope this helps someone somewhere.
Two divs sitting below each other? Do you mean they're stacked vertically, one on top of the other? Margin-top would do it as long as you don't have padding on the parent div.
Try this example.
<html>
<head>
<style>
div.parent {
background-color: #AAA;
}
div.child {
background-color: #CCC;
margin-top: 20px;
}
</style>
</head>
<body>
<div class="parent">
<div class="child"> </div>
<div class="child"> </div>
</div>
</body>
</html>
You'll notice that as long as there's nothing inside the parent above the first child its margins won't extend the parent div.
If they're side-by-side and floating that's a different story, margin-left doesn't work the same as margin-top. You might be able to use margin-right on both divs but fix the width of the parent and set overflow to hidden in order to chop off the extended margin - but I'm not sure about compatibility on that kind of thing.
Are you absolutely certain you've got no way to distinguish the two divs? Finding a way around that constraint might do a lot to help you.

CSS: is there any way to have the same relative positioning even if the previous element have different heights?

I have a sequence of couples of elements. (.div1, .div2) I'm using position:relative attribute on .div2 to move it a bit on top and right with respect to div1.
However .div1 elements have different content and heights, so the relative positioning of .div2 is not consistent (they sometimes are too high, sometimes too low).
.div2 {
position:relative;
left:200px;
top:-300;
}
thanks
Updated:
The HTML code is very simple
<div class="div1"> blabla </div>
<div class="div2"> blabla </div>
If ".div2" is inside ".div1", you could use position:relative on .div1, and the position:absolute on .div2, to force it to get it's position relative to .div1.
A bit counterintuitive, but it works.
This question will be very difficult to answer without some example markup.
Would you be able to solve the problem by specifying a bottom and a right, instead? Are those numbers more stable?

CSS Container not growing with grid?

I have a container background defined in CSS like this;
.container {
background:#fff;
margin-left:auto;
margin-right:auto;
position: relative;
width:970px;
border:1px solid #000;
padding:5px 10px;
}
The problem is I have a jqGrid put in the bottom of the container (near the bottom edge) and when its initially drawn it does fit inside the container panel and looks correct. Something like this (please pardon my non-l33t graphic skillz):
alt text http://img67.yfrog.com/img67/7162/screenshot002f.jpg
But then when I populate the grid with rows it outgrows the container and it looks really tacky, something like this (I circled the original container background edges):
alt text http://img80.yfrog.com/img80/5419/screenshot003fr.jpg
I am sure its something I am doing wrong with the CSS. Any advice would be appreciated.
EDIT: The problem isn't the width its the height of the container being overlapped by the new height of the now populated grid
I've seen this happen many times when you have floats inside. Add a clearing div just before closing container. You should always clean up after floats.
<div class="container">
<div id="nav" style="float:left;">
...
</div>
<div id="grid" style="float:left;">
...
</div>
<div style="clear:both;"></div> <!-- this does the trick -->
</div>
I disagree with adding float to container. Although this will work, having unnecessary floats will give you more problems down the road. Only use floats where necessary and clear it when done floating.
Also in my experience, overflow doesn't mean anything here unless you define height. I don't think setting overflow on container fixes the issue here. Correct me in the comments if I'm wrong.
.container { overflow:hidden; }
assuming you are dealing with floats, this is one way to make the container actually contain them.
Your container is fixed width and won't grow. What you're probably looking for is min-width. In other words, change:
width:970px;
to:
min-width:970px;
As a note, IE 6 and 7 treat width as min-width, but other browsers do not.
I think you need this in your CSS:
overflow: auto;
Depending on your float situation for the container and the inside grid, you can do a number of different things. You might be able to get away with just adding a clear,
clear:both;
You also can float the parent. This is called, setting a float to fix a float. So if your grid has a
float:left;
Then you can just add
float:left;
to your container css. I really like the Complex Spiral article on containing floats.

Resources