Hacker News new | past | comments | ask | show | jobs | submit login
How well do you know CSS display? (chenhuijing.com)
166 points by mgdo on July 6, 2016 | hide | past | web | favorite | 46 comments

I love flexbox. But be aware what it's a beast which is not that super-well supported as you might think when you look it up in caniuse.

When I'm fixing cross-browser bugs nowadays it's mostly about flexbox. It's not very often and I can always fix it in a small amount of time. But it gives me an unpleasant but also nostalgic flashback of the old days in the 00s where I fixed more CSS than I originally developed.

So yes, from time to time I run into different and not so obvious problems. My holy grail to work with flexbox today is this list:


Two recent issues I ran into: There is a very nasty "bug" in the current Firefox browser. It's not a real bug- more a different interpretation of the standard which will hit any developer not working primarily with Firefox I guess. It's about the intrinsic size of a flex item in combination with fluid images. You have to apply min-width: 0 to the flex-item or you get a (very) wrong sizing in some circumstances. See [2] and [3]

And another one. Most of the time I think about IE11 that it's a mostly 'modern' browser and therefore supports flexbox very good. Yes it is good enough to use. But don't underrate the flexbox bugs (just glimpse through [1]). For example you have to set `min-height > 1px` on a flex container to prevent it from collapsing in some scenario (holy grail layout is a very common case). See here [4]

[1] https://github.com/philipwalton/flexbugs

[2] https://bugzilla.mozilla.org/show_bug.cgi?id=1108514

[3] https://github.com/philipwalton/flexbugs/issues/41

[4] https://github.com/Modernizr/Modernizr/issues/1301

It's not so much "a different interpretation of the standard" as the standard draft having changed and Firefox being the only browser that has implemented the change so far...

Have you used intrinsic size values to alleiviate bugs? I found that the hell out a lot and their support is good for where I'm experiencing issues w Flexbox

Good to know! How do you handle Safari 8?

Safari 8.1

> Fun fact: the display values we use all the time are actually short-hand. For example, `block` is actually short-hand for `block flow`. Refer to the specification for full list.



> The `display` property defines box’s display type, which consists of the two basic qualities of how an element generates boxes:

> * the inner display type, which defines [...] the kind of formatting context it generates, dictating how its descendant boxes are laid out.

> * the outer display type, which dictates how the box participates in its parent formatting context.


> <display-outside> = block | inline | ...

> <display-inside> = flow | flow-root | table | flex ...


   Short `display` | Full `display`     | Generated box
   'block'         | 'block flow'       | block-level block container
   'flow-root'     | 'block flow-root'  | block-level block container that establishes a new block formatting context
   'inline'        | 'inline flow'      | inline box
   'inline-block'  | 'inline flow-root' | inline-level block container
   'flex'          | 'block flex'       | block-level flex container
   'inline-flex'   | 'inline flex'      | inline-level flex container


The advent of this kind of explicit systematic consistency in web standards is pretty much my favourite thing about living in the future. Every day I fall to my knees and cry with joy and gratefulness that I will only have spent this a small fraction of my professional engagement with web things in the abominable hellscape that was this world before CSS3 started being widely implemented.

Note that the split between inner and outer display type (which I presume is what it means by short-hand—a term normally defined as one property that sets multiple properties, rather than one property that takes multiple values) isn't implemented anywhere yet, as far as I'm aware.

It looks like there were independent `display-inside/outside` properties, with `display` being a "one property that sets multiple properties" shorthand, in the first draft of the spec:



But that has since been changed to `display` being a "one property that takes multiple values" shorthand, in the current version of the spec:


> Changes since the 11 September 2014 Working Draft include:

> Removed `display-inside`, `display-outside`, and `display-extras` longhands, in favor of just making `display` multi-value. (This was done to impose constraints on what can be combined. Future levels of this specification may relax some or all of those restrictions if they become unnecessary or unwanted.)


But you're right. It's not even on caniuse yet (vote here: https://github.com/Fyrd/caniuse/issues/2337).

But I'm stoked to even see these orthogonal axes and their domains officially laid out, and names given to concepts. Even just `display-inside` vs `display-outside`.

I've had discussions with professionals where no one was certain enough about the `display` mess to make any confident statements on the exact nature of the similarity between `flex` and `block`. Who knew if there were edge cases that made them not have (what I now have the words to describe as) the same `display-outside` behaviour? Thanks also to the crazy muddle of just-slightly-different behaviour the proliferation of other display options has scarred us all with, previously all sharing a single, very arbitrary-seeming, axis.

At some point I really should just sit down, make, and then work through a bunch of box model excercises. After 8 years of trying to treat CSS display as a sensible thing, I've concluded that I really just need to learn it by rote.

Until then, I'll stick with flexbox. Someone has already made this excellent set teaching tool: http://flexboxfroggy.com/

After years of utter failure with CSS alignment, I have to admit that I still struggle with flexbox. Perhaps display:grid will finally save for me.

Granted, I've never sat down and systematically learned the foundations of CSS, but I also never did that with Python, Javascript, Clojure, Bash, PostgreSQL, etc. and yet with all of those, I've not had nearly the number of infuriating, soul-crushing marathon sessions of Googling, Stack Overflowing, grasping randomly in the dark, and making desperate prayers to the binary gods.

I found flexbox frog (despite the kind of 'for kids' feel) to be really helpful in elaborating on all the flexbox options. Get the frog to line up with the lily pad with flexbox.


Just use a table and get on with your life

I know it pretty well. My stuff generally renders right after the 8th or 9th try / refresh!

And opening 3-4 Google searches.

8th or 9th, only 4 searches. Damn, I need to study more.

You should try hot-reloading, then it'll work on the first try... kinda.

If you're building a web app, I have a suggestion to make your life much more pleasant. Go here [0], and set this as your default style. Then go here [1] and grab this style reset. And just use flexbox everywhere.

[0] https://github.com/facebook/css-layout#default-values

[1] https://github.com/necolas/react-native-web/blob/master/docs...

Weird SCSS that I have no idea why it's written like this? Seems to me like 3 exactly the same media queries with overwriting values for no good reason?

    @media screen and (min-width: 720px) {
      .th {
        font-size: 1.294rem;
        line-height: 1.6rem;

    @media screen and (min-width: 720px) {
      .th {
        font-size: 0.8rem;
        line-height: 1.6rem;
        font-family: "Roboto Slab", Rockwell, serif;
        font-weight: 700;

    @media screen and (min-width: 720px) and (min-width: 720px) {
      .th {
        font-size: 1rem;
        line-height: 1.6rem;

I'm sure someone will latch onto this as an example of why CSS sucks.

It's probably just supposed to ve different media queries (I think)

I think display:none is a regularly annoying design mistake. It would be better to separate the concepts of how the content should be displayed, and whether it should be displayed in the first place.

It causes issues such as:

- The built-in rule for *[hidden] { display: none; } is often of no help as another css class may set display to something else, so from the developer's perspective the "hidden" attribute seems to be broken.

- Often a CSS class sets display:none and another CSS class which merely wants to undo that sets display:block. This gets in the way of the developer if they really wanted to use another display type like flex. (one example: Bootstrap's tabs, .tab-content.active{display:block})

- In both cases the fix gets ugly in cases where the problematic css which you want to override comes from parent classes elements, as in that case it is not sufficient to use a simple class like .display-flex{display:flex;} but you need complex rules to override specific cases of parent css.

> I think display:none is a regularly annoying design mistake. It would be better to separate the concepts of how the content should be displayed, and whether it should be displayed in the first place.

This is exactly what the proposed box-suppress property [1] does:

"The display: none value was historically used as a "toggle" to switch between showing and hiding an element. Making this reversible requires either setting up the CSS cascade carefully, or remembering what the display value was before it was set to none. To make this common use-case easier, this module introduces the separate box-suppress property to do the same thing, so that toggling whether or not an element appears in the formatting tree can now be done without affecting its display type when it is displayed."

[1]: https://drafts.csswg.org/css-display/#propdef-box-suppress

I don't like the idea of an attribute affecting things that applies what is essentially a CSS property. Besides, any IE version before 11 doesn't seem to support it. Most can't use it yet.

Best case is that you don't have one class that applies block (or whatever) and another that applies none. You let the element display as its default state and then you have a class that hides it, possibly overriding the CSS of the element. You then remove/add the class as needed. The .show() and .hide() in jQuery caused problems like you described for years.

As for your third example, I would say the CSS structure should be considerd broken at that point and should be refactored because something went wrong along the way.

> - The built-in rule for [hidden] { display: none; } is often of no help as another css class may set display to something else, so from the developer's perspective the "hidden" attribute seems to be broken.

[hidden] { display: none !imporant; } is one of the few examples where I think `!important` is OK.

Most people don't really know css that well, because you can quickly open a browser tab and fiddle around till you get it right. If it took half an hour to compile between changes I'm sure people would know CSS far better.

I think if it took a half hour compilation step, someone would have written a decent intro tutorial which taught a consistent and useful mental model of CSS. Either that or CSS would have just died off.

The fact that a lot of other people here are saying that they have to fiddle with CSS to get it right is making me feel a lot less shitty as a web dev.

Sometimes you just think you know how something works, so you don't study it anymore.

I have a rule that if I'm Googling a symptom for the second time that I have to take some time to learn more about the subject.

I'd rather mess around to get the visual I'm looking for (the results of CSS are nothing if not visual) than read up on copious amounts of documentation. Visual learning for a visual medium.

It's amazing that TeX has basically boxes, glue, and two kinds of lists (vertical and horizontal) and does wonders. CSS, on the other hand...

Flexbox is basically boxes, glue, and two kinds of lists (vertical and horizontal). You can pretty much do all layout in flexbox these days, and all the other display properties are just for legacy compatibility.

And it has error messages. Incomprehensible ones, but at least they exist!

In response to his "responsive numeric stepper," he could have substituted over 20 lines of CSS and eliminated the unsavory plethora of element-specific media queries if he'd just used non-breaking spaces (`&nbsp;`) to achieve the desired line breaks.

Better yet, he could have set `white-space: nowrap;` on `.passenger__label` instead and just thrown a `<wbr>` element before the first parenthesis.

I'll admit, I've been doing frontend for a while and I hadn't heard of the <wbr> element. Thanks for the pointer!

> [1] Support for the <wbr> tag was introduced in Internet Explorer 5.5, though removed again in version 7.

probably the biggest problem with it.

Doesn't seem like a problem to me: http://caniuse.com/#search=wbr

Not supported in IE11, unfortunately, which is a deal-breaker for me.

It was hard enough to get permission to drop IE <10 at $EMPLOYER.

Technically, it's a tag, not a pointer.

He means "pointer" in the non comp-sci sense of the word, as in "thanks for the tip!"

I had meant it in the sarcastic sense.

Ah ok, I thought you might have but wasn't sure :)

See also &zwnj; and friends

Maybe this will come with practice, but I would love to understand, clearly, which use-cases are best fits for flexbox and grid respectively. With the very limited experimentation I've carried out on both, they each seem far superior to messing about with floats (hooray!), but I can't quite get a fix on their respective merits.

What use-cases work with which basically boil down to what you're trying to: flexbox does layout in a single dimensions, and grid does layout in two dimensions.

If you're trying to implement something with layout constraints in both dimensions, you want grid. If you're not, you can probably use grid, but flexbox is likely easier.

In addition, an important determination is not just if you want layout constraints in both dimensions but if you want/need source order independence in both dimensions.

With flexbox you get layout constraints in both dimensions with proper source nesting (rows inside columns or vice versa, ad infinitum) and you get source order independence in the "current direction" (within this row or this column), but not between rows/columns in the grandparent container (or the great-grandparent, etc).

With grid, you can have source order independence in both directions, very nice and easy.

(Source order independence matters for responsive needs where things reflow to different grid places/flex orders based on viewport width, media type or other factors. Source order independence can also be a big important factor for accessibility. The "semantic web dream" is kind of sort of dead or at least asleep these days, but source order independence is a huge win for the semantic web. Finally, source order independence is just nice for keeping HTML markup clean and minimal, which has long been the dream of CSS.)

Just use flexblox on everything, and eat some macaronis. before flexbox it was very hard to me to understand css.

Pretty interesting, I recently switched my nav-bar to display: flex and find it way easier.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact