Why does CSS2.1 define overflow values other than "visible" to establish a new block formatting context? - overflow

The CSS2.1 spec mandates that overflow other than visible establish a new "block formatting context". This strikes me as odd, that a property whose obvious purpose is to hide overflow without affecting layout, actually does affect layout in a major way.
It seems like overflow values other than visible combine two completely unrelated features: whether a BFC is created and whether the overflow is hidden. It’s not like "overflow:hidden" is completely meaningless without a BFC, because floats historically can overflow their parent element, hiding the overflow without changing the layout seems sensible.
What are the reasons behind this decision, assuming they are known? Have the people who worked on the spec described why this was decided to be the case?

I asked about this on the mailing list on your behalf; the thread can be found here. In summary, this has to do with scrolling content for the most part:
Fundamentally, because if the spec didn't say this, then having floats intersect with something that's scrollable would require the browser to rewrap (around intruding floats) the contents of the scrollable element every time it scrolls. This is technically what
CSS 2.0 required, but it was never implemented, and it would have been a huge problem for speed of scrolling.
-David
Most likely, it refers to scrollable content in a box that may occur outside of the float's parent but would intersect with the float. I don't think this is related to rewrapping content around a float within a scrollable container, as that already happens naturally, plus the float would clip into the container and scroll along with the rest of its content anyway.
Finally this makes sense to me. In fact, I'm going to provide an example here so hopefully it makes sense to you and anyone else who may be wondering. Consider a scenario involving two boxes with the same fixed height and overflow: visible (the default), of which the first contains a float that stretches beyond its parent's height:
<div>
<p>...</p>
</div>
<div>
<p>...</p>
<p>...</p>
</div>
/* Presentational properties omitted */
div {
height: 80px;
}
div:first-child:before {
float: left;
height: 100px;
margin: 10px;
content: 'Float';
}
Notice the similarity to one of the examples given in section 9.5. The second box here is simply shown to have overflowing content for the purposes of this answer.
This is fine since the content will never be scrolled, but when overflow is set to something other than visible, that causes the content to not only be clipped by the bounds of the box, but also to become scrollable. If the second box has overflow: auto, this is what it would look like had a browser implemented the original CSS2 spec:
Because of the float, attempting to scroll the content would cause the browser to have to rewrap it so it doesn't become obscured by the float (and what should happen to the part that scrolls out of the top edge?). It would probably look something like this when scrolled to the bottom:
The catch here is that the browser has to rewrap the content every time it repaints it during scrolling. For browsers that are capable of pixel-based smooth scrolling — which is to say, all of them — I can see why it would be a performance disaster! (And a user experience one, too.)
But that's for when the user can scroll the content, right? This would make sense for overflow: auto and overflow: scroll, but what about overflow: hidden?
Well, a common misconception is that a container with overflow: hidden simply hides content by clipping and cannot be scrolled. This is not completely true:
While scrolling UI is not provided, the content is still scrollable programmatically, and a number of pages perform just such scrolling (e.g. by setting scrollTop on the relevant element).
-Boris
Indeed, this is what it'd look like if the second box was set to overflow: hidden and then scrolled to the bottom with the following JavaScript:
var div = document.getElementsByTagName('div')[1];
div.scrollTop = div.scrollHeight;
Again, notice that the content would have to be rewrapped to avoid being obscured by the float.
Even though this wouldn't be as painful for performance as had scrolling UI been available, my best guess is that they made boxes with any overflow value other than visible generate a new BFC mainly for the sake of consistency.
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. This particular behavior is specified in the following paragraph:
The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap the margin box of any floats in the same block formatting context as the element itself. If necessary, implementations should clear the said element by placing it below any preceding floats, but may place it adjacent to such floats if there is sufficient space. They may even make the border box of said element narrower than defined by section 10.3.3. CSS2 does not define when a UA may put said element next to the float or by how much said element may become narrower.
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.
If you apply overflow: auto to the first box instead, the float is clipped into its containing box with the rest of the content due to its fixed height, which is set to 80px in the example code given above:
If you revert the first box to height: auto (the default value), either by overriding or removing the height: 80px declaration from above, it then stretches to the height of the float:
This happens to be new in CSS2.1 as well, in that an element with height: auto that generates a new block formatting context (i.e. a block formatting context root) will stretch vertically to the height of its floats, and not just enough to contain its in-flow content unlike a regular box. The changes are documented here and here. The change leading to the side-effect of shrinking the box so that it does not intersect the float is documented here.
In both of these cases, no matter what you do to the second box, it will never be affected by the float because it has been restricted by the bounds of its container.

I know this will be a speculative answer, however after reading the specifications a few times here is my view on this:
What section 9.4.1 is talking about is any block element that does not fully contain or does not fill the containment space. For example when you float an element it is no longer filling 100% of the parent, like in-flow elements do. Inline blocks, table cells, and table captions are also elements that you can affect height and width but that are not intrinsically 100% of the parent (yes table>tr>td is one that would fill 100% of it's parent but it is designed to allow for multiple td's so the td doesn't count as it will automatically shrink to accommodate additional td's) this also applies to any overflow other than visible because it breaks the containment of the block element.
So if I am reading this correctly the way it works is the 9.4.1 section is referring to block elements that break the default containment rules of the block elements as specified by section 9.2.1

Related

v-select changes width depending on length of selected item

I am using v-selects inside a flexbox, and I would like the v-selects's size to depend on the flexbox settings instead of changing depending on whether a long or short item is selected.
Is there a way to make the width independent of the selected item?
Yesterday I remembered that it didn't happen when I used a v-container, so I mimicked the css of a v-container but with a few changes to apply a different style.
Essentially, if the v-select has rather low width, you can't get around setting the width of the v-select manually if you want it to stay a certain size, which in the end is what v-col is effectively doing.
I wanted it to change depending on the parent's width so I used a percentage and subtracted the total flexbox gap (20px) divided by the number of items (2) in the parent, like this:
.v-select-class {
width: calc(50% - 10px);
}
Hope this helps someone in the future.

Layout using Singularity

I've been trying to create a couple of typical layout examples using Singularity, and I have a question about grid-span and floats.
I've created a sample scss stylesheet and html layout. Here's the complete example on Sassmeister.
http://sassmeister.com/gist/a7ca98b7520b12bd6241
My question is whether the containing content div <div id="content"> is necessary? I'm having to use it with a clearfix mixin in order to 'pull' the div down and keep the footer below the content section and aside.
Is there another way to achieve this layout with Singularity, without having to use the surrounding clearfix div? Is there an option for grid-span in the main section that will either not use a float, or self clear this section?
To understand your problem you have to learn how floats and clearing work.
0.
When you float an element, it is removed from the flow. It's vertical height does not count when calculating the height of the container.
1.
The intended usage of floats is to add images to a long sheet of text. The text would wrap around the floated image and increase its overall height and stretching the container vertically, just like an object submerged into water increases the height of water surface.
Before:
After:
2.
If the floated image is located very close to the bottom of the text, it will pop it's bottom out of the bottom of the container, just like an iceberg exposing it's top from the water.
3.
Now imagine that your text is comprised of paragraphs and each paragraph starts with a title. When there's an image floated at the bottom of a paragraph, the image would stretch into the next paragraph, pushing the next paragraph's title aside.
4.
If you don't want that to happen, you apply clearing to paragraph titles:
h2 { clear: both; }
This basically tells the titles: don't let floated images push you aside, let them push you down instead.
5.
But web pages have become more than formatted text, and HTML/CSS didn't provide any means of formatting layouts. So we started using floats for layouts. It's ugly, it's like using wallpaper to sew your clothes, but we have no better option (until Flexbox becomes a thing, and it seems to already).
What happens when you float all content in a container? There will be no flow left, no text to stretch the container vertically, and it's height will be zero (plus border and padding):
6.
You already know that in order to make containers regain their height (wrap around the floated content) we have to apply a clearfix to the container. But what a clearfix actually is?
When you apply a clearfix to a container, you use :after in CSS to create an additional element within the container, after all it's content. Then you apply clearing to the little mother fcuker:
.container:after {
content: '';
display: block;
clear: both;
}
7.
Now back to your question! What's the alternative of using the clearfix?
You've probably have guessed already.
If you've got got content below the floated element, simply apply clear: both to the next element below the floated one! Just like we did in #4 for paragraph titles.
In your case:
footer { clear: both; }
And here's a demo: http://sassmeister.com/gist/df8af8a3c7f8d3df2796

Skrollr.js relative key frames and best practices

I'm not sure if something I want to do is possible with skrollr, it doesn't seem to be possible but maybe I am misunderstanding. I would like to be able to describe keyframes in scroll points relative to other keyframe events, as in "start this animation event 500px after another element's animation event", and wondering what the best practice is. I am working on a large page of multiple sections of animated content. Each section scrolls to the top, then becomes temporarily fixed as multiple animations occur within the section on many key frames, then once that section's animations are done it scrolls up off the screen and the next section comes into view and does it's own animating, and so on (not unlike the main skrollr demo but more complex with many more animation events). My main issue is that I want to be able to easily edit in the future each sections' animation timings independently, for example to adjust little details here and there as needed, anticipating some back-and-forth with the artists and clients I'm working with. But when relying on an absolute scrollTop for all timings, this becomes problematic because one little timing change means I have to adjust all subsequent timings throughout the remainder of the page. To get around this I am using constants to denote the start of each animated section so that at least I can have each animated section be timed relative to its start, as in:
<style type="text/css">
#fixedanimatedcontent1, #fixedanimatedcontent2 {position: fixed;}
</style>
<section id="fixedanimatedcontent1" data-_fixedanimstart1--630="top:100%;" data-_fixedanimstart1="top:0%;" data-_fixedanimstart1-1500="top:0%;" data-_fixedanimstart2="top:-100%;">
<div data-_fixedanimstart1="width: 0%;" data-_fixedanimstart1-470="width: 100%"></div>
<img src="x.png" data-_fixedanimstart1-270="opacity: 0;" data-_fixedanimstart1-670="opacity: 1;" data-_fixedanimstart1-1170="opacity: 0;" />
</section>
<section id="fixedanimatedcontent2" data-_fixedanimstart2--630="top:100%;" data-_fixedanimstart2="top:0%;" data-_fixedanimstart2-2000="top:0%;" data-_fixedanimstart3="top:-100%;">
<img src="y.png" data-_fixedanimstart2-500="opacity: 0;" data-_fixedanimstart2-1000="opacity: 1;" data-_fixedanimstart2-1500="opacity: 0;" />
</section>
But even still, for complex sequences making a small timing change will be a bit of a mess, requiring at the least changing all key frame offsets within that section, and probably also changing constant values. Looking at my example above, 2 questions:
1) Is there a way to describe a relative keyframe that, let's say, begins 500px after section #fixedanimatedcontent2's top=0%? I know I can do data-top, but in my setup #fixedanimatedcontent2 becomes fixed at the top for some time once it hits the top. So how do I describe a keyframe that I want to begin 500px of scrolling after #fixedanimatedcontent2 hits data-top? Is this not possible within the syntax of "relative key frames" since offsets are only relative to element position in the viewport? If this were doable somehow, I wouldn't have to rely on constants so much...
2) How about a keyframe that begins when section #fixedanimatedcontent2's <img> reaches an opacity of 1? That way I could later if I needed make a change in the length of that <img>'s opacity interpolation without having to change all subsequent key frame timings. Pretty sure this is not possible but had to ask...
So: Am I misunderstanding what is the best way to do this sort of relative sequencing most efficiently? Or is using constants as in the example above the best practice?
(this was a really verbose post, sorry!)
It is very well possible in skrollrjs. I am telling nothing different from skrollrjs documentation. If you look carefully there, there are two modes for keyframes
absolute
relative
I think you wanted to use relative mode. So, i would answer each of your questions orderly.
1) Is there a way to describe a relative keyframe that, let's say, begins 500px after section #fixedanimatedcontent2's top=0%? I know I can do data-top, but in my setup #fixedanimatedcontent2 becomes fixed at the top for some time once it hits the top. So how do I describe a keyframe that I want to begin 500px of scrolling after #fixedanimatedcontent2 hits data-top? Is this not possible within the syntax of "relative key frames" since offsets are only relative to element position in the viewport? If this were doable somehow, I wouldn't have to rely on constants so much...
Answer:- It is possible to do that. In relative mode of work, you can define your relative targets and you can define css accordingly. So for your element #fixedanimatedcontent2 when reaches top i would use like following html
You can use following cheatseet for this. This is helpful.
https://ihatetomatoes.net/skrollr-cheatsheet/
I think all you need is already described if you read carefully
https://github.com/Prinzhorn/skrollr

First word in sentence has bigger font-size: container element cuts it off on top

The main text of my website's first word has a significant larger font-size than the rest. For some reason or another the container that contains the text cuts the first word off on top. Probably because the line-height of the first word is identical to the rest of the text and thus the container is not able to calculate its own height properly.
Codepen snippet: http://codepen.io/sardasht/pen/maJup (I've included the full contents of my css file to be able to debug properly, so will not embed this here. If this is requested, I'd happily edit my post to include it, but it will be ~300 lines of text)
If I increase the line-height of the first word, the rest of the text which is on the same line gains the same line-height and thus jumps up from the rest of the text below. If I add a margin-top to the container element, the first word is not cut off anymore, but then the bottom line of the text is cut off.
I played with overflow: visible/hidden as well on all parent elements, but to no avail.
The p element has line-height: 1.5em, which will set the height of the text lines inside it. Because of the em unit, the height is determined based on the font size, and it's the font size set for the p element that is used, so the line height won't increase because of the larger font size set on a child element.
I would try using a line-height declaration that isn't set in px, or ems.
p, span { line-height:1 }
I also tried
span { line-height:0.8 }
which seemed to give the very least amount of top "push", but I only viewed it in FF on a Mac.
I've noticed, with fonts, that their heights and widths are rendered differently from browser to browser. And this can be exacerbated with fonts that haven't been given proper leading, kerning, etc. This can cause "odd" line breaks, which causes a 'problem' with set block heights -- especially going from FF, and Chrome to IE. FWIW.
EDIT:
http://jsfiddle.net/mvf6j/
Setting the line-height to 1 (of the child) equates to 100% of the parent's line-height; thus, in your example code 1 = 1.5em. In my fiddle/example, 1 = 1em (even with the child being a 2em font). It's inheritance. It makes the child relative to the parent. And takes the guess work out, if you should want to change the parent's size. All of that ease in sizing/relationships disappears when you set explicit line-heights to the children.

Why doesn't my webpage scroll in Internet Explorer 8?

So I've spent a significant amount of time coding and designing this webpage, and it works perfectly in every browser I've tested it in: IE7, IE9, Firefox, Chrome, Safari. But when I view the webpage in IE8 (and only IE8), the vertical scroll is disabled. The scroll bar is there all right, but it's turned off and I can't use it or the mouse scroll wheel.
I'll post the code for the webpage if I absolutely have to, but first I wanted to see if anyone had ever heard of this happening before or had any initial thoughts.
Okay, I figured this out. If you put height: "100%"; in the html tag of your page's CSS stylesheet, it will break scrolling in IE8, but other browsers will still work. Go figure.
Here is a hack way of getting the scrollbar to work with a height of 100%. Not the best solution but it now scrolls in IE8.
html {
overflow-y: hidden\9;
}
html, body {
height: 100%\9;
}
body {
overflow-y: scroll\9;
}
mainly three things you should see
If you have given style as overflow:hidden
If you have given hight in page percentage.
if you have given float:static.
Fix this issue your IE 8 problem will be solved.
Reason : IE 8 is different than nything else for CBC check IE frist! To the topic, IE 8 hides (only scrolling bar) of scroll bar if you have overflow as hidden, secoundly if you have places hight as 100% IE 8 takes overflow as hidden (can say takes by its own!) n float is element who can go beyond page size if you have it as inherit or relative but static dose not increase dynamicly.
You tried on other IE8 (not your local ie8)? Maybe the problem is in your ie8.
Run with no-addon mode or try to disable all addons (including bars)
Restore advanced settings. Tools -> Internet Options -> Advanced -> Restore Advanced options.
I have also faced this type of problem many times.Scroll bar with IE8 , should not visible in a plain HTML page. So, please check the content inside your <body></body> tag . There may be is some margin or padding tag.
I am using IE8 currently , but there is no such scroll bar is showing. No need to fix the height:100% for HTML or BODY. Please check your page deeply.
If you are using CSS, it may come in handy that you need a reset CSS value so that the page renders properly in IE8. I have provided the link as well as the snippet from http://sixrevisions.com/css/css-tips/css-tip-1-resetting-your-styles-with-css-reset/ . This may help you. If anything this is a nice site to read if you are starting development.
A reset to where it all started…
The concept of CSS Reset was first discussed formally way back when dinosaurs still roamed the internet (2004 to be exact) by Andrew Krespanis. In his article, he suggests using the universal selector (*) at the beginning of your CSS file to select all elements and give them 0 values for margin and padding, like so:
* {
margin: 0;
padding: 0;
}
The universal selector acts like a wildcard search, similar to regular expression matching in programming. Since in this case, the * isn’t preceded by another selector, all elements (in theory – some browsers don’t fully support it) is a match and therefore all margins and paddings of all elements are removed (so we avoid the spacing differences shown in Example 1).
Applying the universal selector margin/padding reset to our earlier example, we now remove all inconsistent spacing between all browsers (in other words, we don’t make the browsers think for us, we show them who’s boss).
Example 2: Applying the universal selector margin/padding reset
But now we don’t have any spacing in between paragraphs, so somewhere below our universal selector reset, we’ll declare the way we want our paragraphs to look like. You can do it a number of ways – you can put margins (or padding) at the beginning or top of your paragraphs, or both. You can use ems as your units or pixels or percentages.
What’s important is that we choose the way the browser will render it. For our example, I chose to add margins (instead of padding) both at the top of the paragraphs and at the bottom – but that’s my choice, you may want to do it differently.
Here’s what I used:
* { margin:0; padding:0; }
p { margin:5px 0 10px 0; }
Example 3: Declaring a style rule after the universal selector.
Note: The example I used for discussion is a simplified example. If you only used paragraphs for your web pages and no other elements, you wouldn’t want to reset your margins to 0 using the universal selector only to declare a style rule right after it for your paragraph. We’ll discuss this more fully along with other best practices later on down the page.
Shortly thereafter – CSS guru Eric Meyer further built on the concept of resetting margins and paddings. In Eric Meyer’s exploration, he discusses Tanek’s work undoing default HTML styles (which he called undohtml.css) which not only resets margins and padding, but also other attributes like line-heights, font styles, and list styles (some browsers use different bullets for unordered list items).
After many iterations and refinements, we come to a wonderful solution called CSS Reset Reloaded CSS Reset, which not only makes this CSS reset method more accurate than the universal selector method by using higher specificity by naming all possible HTML tags (because the universal selector fails to apply the reset to all HTML tags), but also sets default values for troublesome elements like tables (in which the border-collapse attribute isn’t rendered consistently across browsers).
Of course, there are other methods of resetting your CSS (such as Yahoo!’s YUI Reset CSS which I currently use on Six Revisions), and you can roll your own based on your preference and project needs.
SITE: http://sixrevisions.com/css/css-tips/css-tip-1-resetting-your-styles-with-css-reset/
NOTE: I am kind of new at this, so please bear with me.

Resources