Some confusions about css overflow - css

Recently I am learning some stuff about CSS,I found some awesome tricks about overflow:
Set parents of float elements to overflow:hidden or overflow:auto can keep parents from collapsing
<div style="overflow: auto;">
<div style="float: left;">Div 1</div>
<div style="float: left;">Div 2</div>
</div>
make two columns have same height,set a big enough padding at the bottomof each floated element, and countering it with an equal negative margin at the bottom of the same elements. The trick is to set the overflow on the parent container to hidden
I can not image how it work,why is overflow so obscure? someone can explain it?

The clearfix behavior you describe in 1 is a well known properties of overflow as you can see here: https://css-tricks.com/almanac/properties/o/overflow/#article-header-id-6 and http://www.stubbornella.org/content/2009/07/23/overflow-a-secret-benefit/ and this is an expected behavior, since it is part of the CSS 2.1 spec: https://www.w3.org/TR/2004/CR-CSS21-20040225/visudet.html#root-height (see the last sentence of the 10.6.7 'Auto' heights for block formatting context roots paragraph)
The 2 is (as #alohci says in the comment) the overflow: hidden expected behavior.
For further details you can read the official spec: https://www.w3.org/TR/CSS22/visufx.html#overflow

Related

css-formatted tabular divs ['table'] w/fixed header and both x/y scrolling

I've found a number of posts on stackoverflow that address similar problems to mine, but none of them are similar enough, and I just can't solve this... I have tabular output that may exceed a viewing area in width, height, or both. The output is accompanied by a header. If the output exceeds the height, the user should be able to scroll up/down, but the header must remain fixed. If the output exceeds the horizontal area, the user should be able to scroll left/right, and the header must move w/the content.
I've tried various combinations of overflow:scroll, overflow:scroll-x [and scroll-y], overflow:auto, w/the table header both part of the content, and separate from it. I've met w/only mixed success ; either I can get the header to scroll l/r along w/the content and it disappears on vertical scrolling, or I can get the header to remain fixed in case of vertical scrolling, but it remains fixed if the output is scrolled horizontally.
Here's a fiddle w/some html that I used as a starting point.
[code]jsfiddle code[/code]
Constraints
the output must be divs, as in the example. I can't use <table>
the solution must be css/html only, no j/s, jquery, etc.
Any help appreciated !
You can't achieve that with pure css/html even if you give an element position: fixed; or position: absolute;. by doing that you can't move the element because while scrolling element's position on the page does not change and it is impossible to get element's scroll value from css or html.
So the only solution you can find is in using javascript
If you can set a width to some of your divs this can be a starting point using pure css/html:
.row div, .head div {
display: inline;
}
.head, .rows {
width: 160px;
}
.rows {
height: 40px; // this height is set to force scroll
overflow-y: scroll;
}
.tbl {
width: 100px; // this width is set to mimic small width
overflow: auto;
}
<div class='tbl'>
<div class='head'>
<div>head 1</div> <div>head 2</div> <div>head 3</div>
</div>
<div class='rows'>
<div class='row'>
<div>data 1</div> <div>data 1</div> <div>data 1</div>
</div>
<div class='row'>
<div>data 2</div> <div>data 2</div> <div>data 2</div>
</div>
<div class='row'>
<div>data 2</div> <div>data 2</div> <div>data 2</div>
</div>
</div>
</div>
http://jsfiddle.net/jL4ch/
i figured this out. there are several things to take note of :
the widths can be made to function w/any inline block-structuring style, including inline-block, for example. you don't have to use table-cell. using only inline will cause the browser to disregard the width: elements.
it's pretty silly, but if you use overflow-x, you also have to state an overflow-y policy explicitly, or you get 2 scrollbars. the trick was to declare the axis w/the desired constraint as auto and the other overflow as hidden.
here is a jsfiddle that illustrates my solution. the fiddle has inlined widths because in real life, the tabular data will actually be generated dynamically and the column widths won't ever have the same values, as they do here in the example.

Why do `inline-block` elements auto-clear their children?

display: inline-block is used in a number of clearfixes (1, 2), though none of those articles explain why it makes an element clear after itself. Why is it so?
I've looked through the spec, and haven't found any definitive explanation on that matter.
This example illustrates the behavior in question (consistent in IE9, and the latest versions of Chrome and Firefox):
<div style="display: inline-block;">
<div class="float"></div>
<div class="float"></div>
<div class="float"></div>
</div>
<hr/>
<div>
<div class="float"></div>
<div class="float"></div>
<div class="float"></div>
</div>
Inline-block elements establish new block formatting contexts for their contents. A block formatting context root always tries to contain its floats if sized automatically; see section 10.6.7 of the spec:
In addition, if the element has any floating descendants whose bottom margin edge is below the element's bottom content edge, then the height is increased to include those edges.
This is what makes an inline block able to contain its floats; no clearance is actually involved since no clearing element is introduced after the floating children.

Floating divs, equal height - fill space with additional div without overflow

I have two div-columns of different height which I like to have the same height. I achieved this using the padding-margin hack with the following css for my div-columns:
.lane1 {
padding-bottom: 800px;
margin-bottom: -800px;
}
The html is displaying a flow-diagram. I would like to have a line from the end of each lane to the bottom of the two-lane part to have a continuous diagram.
I tried to achieve this with an additional div with class .LineFilling that is a line going down, but I don't know how heigh the line should be. So I put
position: absolute;
overflow: hidden;
in the .lane1-class and made the .LineFilling-element of height 600px, but that doesn't work, since the overflow is displayed. Is there a way to have the .LineFilling-element extend to the end of the lane? Or extend further but the overflow being cut?
Thanks for help.
EDIT: I posted the code online here: Click here to see code
Yes it is possible with pure css.
I have used display table-row and table-cell properties to achieve it.
HTML:
<div class="parent">
<div class="child">
<p>line 1</p>
</div>
<div class="child">
<p>line 1</p>
<p>line 2</p>
<p>line 3</p>
<p>line 4</p>
</div>
</div>
CSS:
.parent{display:table-row;}
.child{display:table-cell;border:1px solid #ccc;padding:10px;}
p{margin:5px 0;}
See fiddle.
Update: probable solution DEMO
Pure CSS solution
Here is a DEMO of that solution.
In this DEMO, you see multipple Rows,
each Row can have a variable number of columns without stating anything in the markup, and without fixing any width. (the width is always divided evenly between the columns).
Each column is called ElementsHolder, and can have any number of Elements you want.
all the column in a row will always have the same height, and the last arrow in the row will fill that space.
In the DEMO you can see 3 Rows.
The First Row has the starting point, so no stretch needed there.
The Second Row has 3 ElementsHolder, without stating anything special in the markup, 2 of them will stretch to fill the gap.
The Third Row has 2 ElementsHolder, behave as expected.
notice that the stretching works regardless of the Elements height. (some of them have 2 or 3 lines of text, and it works perfectly)
If you want to use that technique, you only have to implement the other kind of boxes and arrows (Curve etc..)
The solution is done by using the new CSS flex model.
the direction is set via flex-direction: row;,
Each row has ElementsHolders that gets equal width.
each one of those ElementsHolder is also a flex box, but this time his direction is opposite (flex-direction: column;).
the child's of ElementsHolder are Elements & Arrows, I dont want them to have equal height, but to span excatly the natural height. except the last arrow, that should span the rest of the container.
all of that is achieved using the flex property with the appropriate values.
More about the flex-model can be found HERE
I don't know if I really understand what you need. I've tried the following
Adding a new absolute element in the laneContainer with height: 100% ​​
#straightLine {
background-color: #FFBF80;
height: 100%;
left: 104px;
position: absolute;
width: 3px;
z-index: 5;
}
Plus some small modifications to some other objects, you'll find them in the fiddle...
http://jsfiddle.net/RRupc/9/
Is something like that what you want?
Rather than adding another div to fill the space, wouldn't it be easier to add a class to the div on the left column, and style that to fill any spacing/line requirements you have?
So you could have:
HTML:
<div class="twoColumn">
<div class="column">
<div class="step doubleRow">
<p>One step covering two rows here</p>
</div>
</div>
<div class="column">
<div class="step">
<p>Single size step</p>
</div>
<div class="step">
<p>Single size step</p>
</div>
</div>
</div>
have you seen these 2 plugins?
jQuery Isotope
jQuery Mansonry
Eventually there is a solution for you!?
Take a look.
FlexBox could be worth a look too.
if you are ok with IE10 +
Auto Align Heights (CSS)
align-items: stretch
Good Reads here and here
Cheers,
Rob

Effect of overflow:auto on floated divs

Short version: Why does overflow:auto cause a div to the right of a left floated div not to wrap its text around the left floated div? (Bonus: Is this an acceptable way to accomplish a column effect?)
Long version...
I have two divs that I wish to be next to each other, and displayed as columns. The div on the left has a specific width and height. And the div on the left is shorter than the div on the right. However, I do not want the text in the right div to wrap under the left div.
Here was my first attempt...
<div>
<div style="border:1px solid grey;
width:100px;
height:100px;
float:left;">
Div on the left.
</div>
<div>
Imagine lots and lots of text here...
</div>
<div style="clear:both"/>
</div>
...I knew the text in the right div would wrap under the left div. And it did.
Then I remembered a page I had created that had a column effect. I had copied and pasted it from I know not where. All it did was assign overflow:auto to the div on the right. It looks like this...
<div>
<div style="border:1px solid grey;
width:100px;
height:100px;
float:left;">
Div on the left.
</div>
<div style="overflow:auto">
Imagine lots and lots of text here...
</div>
<div style="clear:both"/>
</div>
Voila, the right divs text no longer wrapped under the first (left) div! The second (right) div appeared as a column.
So, I read everything I could find on overflow:auto and found no mention of why I should see this behaviour. Can anyone explain it to me?
Also, is this an acceptable way to achieve a column effect?
overflow: auto (or anything but visible) causes your second div to create a new block formatting context. This means the text within that div is now in its own formatting context, rather than sharing the same one as your first, left-floating div (which is the containing block of both divs), and so it is no longer allowed to flow around the first div.
Floats also generate their own BFCs, but that doesn't exactly relate to the matter at hand. It does however also prevent reflow, achieving a column effect, as shown in the other answers.
Is this an acceptable way of creating a column effect? I don't know, but it does seem unconventional. You can just float the second div as well instead for the reason mentioned above (although even that, in favor of upcoming true layout modes like flexbox and grids, is now seen as a browser compatibility hack these days, but is the best we've got for the time being).
Remember that inline content is designed to be able to flow naturally around floated content; see CSS2.1, §9.5 Floats.
Remember also that the purpose of overflow is to control content overflow in a box with a limited size. That it causes a box to create a new BFC, influencing floats as a result, is but a side effect, the reason for which is explored here. It's a lengthy read, but it includes a bit about preventing reflow, which I'll quote here for ease of reference:
And so, this change was brought about in CSS2.1, documented here. Now if you apply an overflow value other than visible only to the second box, what a browser does is push the entire box aside to make way for the float, because the box now creates a new block formatting context that encloses its contents, instead of flowing around the float. Here's what it looks like with overflow: auto for example:
Note that there is no clearance; if the second box had clear: left or clear: both it would be pushed down, not to the side, regardless of whether it established its own BFC.
By the way, yes, this means your clearing div needs to be there if you want to always clear the first div.
To get the divs next to each other they both will need a float and fit in the surrounding div.
Example:
<div style="width:200px;">
<div style="width:100px; float:left;">
content
</div>
<div style="width:100px; float:left;">
content
</div>
</div>
If you want the outlining div to grow with the largest div place overflow:hidden; to the div.. If that div doesnt have a height with it then it will scale with the larges div.
Preview:
http://jsfiddle.net/WzVBE/
Remove float:left from the first div.
<div>
<div style="border:1px solid grey; width:100px; height:100px;">
Div on the left.
</div>
<div style="overflow:auto; ">
Imagine lots and lots of text here...
</div>
<div style="clear:both"/>
</div>​
DEMO
You can try this
<div style="width:800px; background-color:#CCC">
<div style="width:300px; height:100px; float:left; background-color:#CCC">
Div on the left.
</div>
<div style="height:100px; float:left; width:500px; background-color:#999">
Imagine lots and lots of text here...
</div>
<div style="clear:both"/>
</div>

CSS float arbitrarily wrapping non-quirks mode despite having room

I have come across a weird problem where floated elements wrap to the next line when there is still plenty of space for them.
I realize this can be solved by removing the < p > or the < div > but I want clean valid code.
Most importantly I want to know why this is happening.
HTML:
<div class="section" style="width: 8000px;">
<div style="" class="bottom">
<div class="img6"></div>
<p class="n">
</p>
</div>
</div>
CSS:
p.n{margin:0;}
div.section{width: 8000px;}
div.section:after{content:"";display:block;clear:left;}
div.section div{float:left;}
a.b{display:block;float:left;}
div.img6{background:#933;width:78px;height:15px;}
a.t1{background:#123;width:74px;height:15px;}
a.t2{background:#456;width:86px;height:15px;}
a.t3{background:#555;width:92px;height:15px;}
a.t4{background:#786;width:126px;height:15px;}
Or you can see it here at JSbin
One interesting thing worth noting is that no matter how many elements you add only the last one is wrapped.
This is happening because the p is not floated left. If you inspect the elements with for example firebug, you will see that the wrapper div.bottom has the exact width of it´s largest, unfloated, block level element, p.n, 378px.
If you float p.n as well, your problem is solved.
The problem is that floating the .bottom div left reduces its width and therefore everything it contains. Try changing div.section div {float: left} to div.bottom div {float:left}.
If you need to float everything, consider floating the external content right and/or specify fixed widths.

Resources