Hacker News new | past | comments | ask | show | jobs | submit login
Coping with Flexbox (kgrz.io)
155 points by technicolor on Dec 14, 2019 | hide | past | favorite | 55 comments



When you feel a lack of confidence or speed with of a tool you use frequently, it is easy to feel a mixture of frustration and shame.

That suffering might be due to an unmet desire: that you should get fluency but not require training. As a programmer, you might feel that human repetition is a sign that something needs to be built to prevent that repetition. But, if you talk to a teacher, sports coach, martial artist, or anyone else who works in the domain of training meat-based deep neural nets to solve problems quickly and confidently, you'll find this is false. If you are seeking a feeling of speed and confidence, embrace repetition.

Perhaps, play https://flexboxfroggy.com/ 10 times.


There are lots of things people can do after being shown once. They'll go a at a measured pace, but need minor or zero help. Sports and marital art practice are all about getting sub-second decisions and extremely quick/smooth movements; none of that's relevant to writing something without feeling like a fool.

Maybe a tool like this necessarily needs a bunch of practice. Or maybe it's badly designed, and the experience should be more like chopping a carrot.


> Sports and marital art practice are all about getting sub-second decisions and extremely quick/smooth movements; none of that's relevant to writing something without feeling like a fool.

Some people expect their brain to answer a question like "I want to make this particular box's children evenly vertically-spaced. What is the name of the css property to google?" with a confident sub-second response. Some people, upon observing that they can't, feel like a fool.

For those people, it is relevant.

--------

> Maybe a tool like this necessarily needs a bunch of practice. Or maybe it's badly designed, and the experience should be more like chopping a carrot.

I'd like to live in a world where every tool thats the best for a job is well-designed.

I'd also like to live in a world every message I try to communicate is one that people pay attention to and understand in the spirit I intended, even if I never edit it.

I'd also like to live in a world where my lumbar region is pain-free, even if I don't regularly do squats.

---------

The author's words about his pain points are still valuable. Systems should be improved. They can't be improved unless problems are made clear. There is much broken in the world and many of us have taken up the call to fix it and we should heed the words of others' frustration.

But there is much broken in the world that won't get fixed anytime soon.


Big fan of flexbogfroggy (and cssgridgarden)!

I've been trying to improve my css lately and have found Kevin Powell's content on YouTube great[0].

Eventually I caved and purchased his course[1]. It was initially just to support him, as he has so much premium, free content out there that had benefitted me, but I'm actually going through it and (at least for me) learning faster than by just passively watching youtube videos.

I'm finding it pretty well structured and a good progression from flexbogfroggy.

[0] https://www.youtube.com/user/KepowOb [1] https://www.kevinpowell.co/courses/


Thats a false equivalence though.

Tools in development are written _by_ people _for_ people. They are crafted to be the way they are, and once you hit a certain level of abstraction above the performance layers I think its assumed that the tool should be easy to use.


yes, tools 'should' be easy to use.

When you're designing tools, this is relevant.

When you're using tools that have been agreed-upon by committee, it is not.


When I was learning Flexbox, I've created a graphical cheatsheet [1] (based on another one) that I've printed out and put next to my computer. It helped me a lot back then.

[1] https://darekkay.com/dev/flexbox-cheatsheet.html


That's the most succinct quick reference I've found on this (I've always had trouble digesting the css-tricks article). Have you thought about making a similar cheatsheet for Grid?


Thanks! I did not, but you might have a look at this cheatsheet: http://grid.malven.co/


Thank you, this is very helpful!

I can never keep align-items vs justify-content vs align-content vs justify-items straight and this helps (although it's missing the last one, maybe that only applies to grids).


Whoa! Nice job.

I wish this existed when I tried flexbox the first few times…


Wow, this is cool!


Firefox Inspector has useful visualizations for flexbox containers: https://developer.mozilla.org/en-US/docs/Tools/Page_Inspecto... And another useful feature that shows indicators why some CSS properties are not working.


Thanks, I use Firefox and didn't know about this. It's interesting, but seems like it'd be most useful if you were actually using flex basis and not that helpful for just basic justification and alignment.


Indeed! I should’ve dropped some of these screenshots or links to FF devtools in the post.


Once flexbox understanding kicks-in, it becomes the most efficient way to create layouts by far.


I’m not sure I’d go quite that far. Flexbox is good for some types of layout, but it’s frustrating how often it gives you most of what you want but then there is no tidy way to get the final details right.

For example, I was recently implementing a “small multiples” layout, showing many small charts of the same type, with the exact number depending on context. This seems like an ideal use case for flexbox: you can make good use of your available screen width, with everything lining up neatly, even spacing, but still wrapping to extra rows as needed.

Alas, it doesn’t always work quite like that. For example, suppose that we have a display that is wide enough to fit five items and we have 16 items to show. I don’t really want a layout with 5+5+5+1 items; using 4+4+4+4 would look much neater, without needing any more space. Unfortunately, while typographers have been wrangling with this sort of problem for a long time, flexbox doesn’t have any awareness of it at all.

OK, so I have to live with 5+5+5+1 for now if I want to use flexbox. In that case, it would be nice to control the justification of the final line, for example having additional items lining up under the left-most columns above them. Unfortunately, this also isn’t something that flexbox supports. With most settings for justify-content, my lonely last item is going in the centre of its row, whether I want it to or not. Even worse, if I add another item, the two on that final row will be correctly spaced according justify-content within their own row in isolation, but that isn’t necessarily going to align at all with the columns of items on the rows above.

These kinds of limitations do significantly reduce the usefulness of flexbox, IMHO. With CSS grids also now widely supported, I find there aren’t actually that many situations where flexbox is the best tool for the job.


> OK, so I have to live with 5+5+5+1 for now if I want to use flexbox. In that case, it would be nice to control the justification of the final line, for example having additional items lining up under the left-most columns above them. Unfortunately, this also isn’t something that flexbox supports.

My understanding of this description may be incorrect. If not, this is supported in flexbox.

This pen is editable so the HTML list can contain 16 items (5+5+5+1) and I think it works for what you're describing. [0] [1]

[0] https://www.w3schools.com/css/tryit.asp?filename=trycss3_fle...

[1] https://imgur.com/a/Cr8WAmY


You’re not really doing any flexing in that example, though, so I’m not sure why you would need flexbox at all there. If you start using the justification options then unfortunately things get more difficult.


> You’re not really doing any flexing in that example, though, so I’m not sure why you would need flexbox at all there.

The items are governed by flexbox and adding, for example

  > align-items: flex-end;
to the container would readily demonstrate this. (Think class added on some user interaction.) The old way of doing this would be using float.

My point is that flex readily handles the use case you describe. Elsewhere in this subthread (5+4+4+4 distribution), you also deem flexbox incapable but I can think of how a frontend developer could make it work.

Perhaps you are unintentionally looking for instances where flexbox cannot do something and then imposing constraints where flexbox is not an appropriate tool. However, if you think in terms of flexbox, some of these scenarios actually have handy and elegant solutions.

YMMV


The items are governed by flexbox

Yes, but since you aren’t using any of the flex-related properties other than flex itself and wrapping, the layout you’re building isn’t substantially different from normal block-based layout and wrapping.

My point is that flex readily handles the use case you describe.

If we took your example and added some flex-specific behaviour, say justify-content:space-around, how could we readily left-align the final items with flexbox here?

Elsewhere in this subthread (5+4+4+4 distribution), you also deem flexbox incapable but I can think of how a frontend developer could make it work.

It’s difficult to discuss that when haven’t shown us what you have in mind. Would you like to elaborate?

Perhaps you are unintentionally looking for instances where flexbox cannot do something and then imposing constraints where flexbox is not an appropriate tool.

I would prefer to say that flexbox would be a more useful tool if it could also handle these finer details. There are numerous blog posts and SO questions about limitations in the current version of flexbox and how to work around them, so I think it’s fair to say that the challenges I’ve described here are not unusual.


> If we took your example and added some flex-specific behaviour, say justify-content:space-around, how could we readily left-align the final items with flexbox here?

I'm trying to think of an example where one would "justify-content:space-around" and want the last line to align left. Curious.

I agree flexbox has limitations but I don't see them in the examples you've provided thus far.

This is not much of an elaboration but the 5+4+4+4 I'm thinking along the lines of changing margin of nth children, or even specifically adjusting the CSS for the fifth child.

When developing front-end, I'm sure you would use the most appropriate tool for the design at hand. Flexbox even with its limitations is sometimes the best choice. I also agree it could use use refinements, but whatever refinements it needs aren't apparent to me in the examples you've described.

This may be a failure of my imagination.


I'm trying to think of an example where one would "justify-content:space-around" and want the last line to align left. Curious.

My original example would suffice. Given a large number of small charts to be displayed, typically all of the same size, it seems quite reasonable to want them to be evenly distributed and to adapt automatically to use the available horizontal space, but for an incomplete final line to fill from the left under the items in rows above. (Please remember that this is what was meant by aligning to the left in this context; we’re not talking about literally aligning on the left margin without reference to the extra space added by flexbox here.) The alternatives available with the current flexbox behaviour tend to be things like putting a single chart in the centre or putting two charts on the far left and far right with a possibly huge space between them, which inevitably leave the items in the last line looking arbitrarily placed and disconnected from the rows above.

This is not much of an elaboration but the 5+4+4+4 I'm thinking along the lines of changing margin of nth children, or even specifically adjusting the CSS for the fifth child.

But how do you know in advance which n you need? The primary advantage of flexbox in this sort of situation is that your many items will use up the available display width while also being neatly spaced. If you know your exact horizontal sizes in advance, you don’t really need flexbox at all for this kind of layout, since again you can just choose suitable margins and/or padding on your items and then rely on simpler layout tools like inline blocks.


Never mind flexbox, what generalized rule would yield 5+4+4+4 instead of 5+5+5+2?

Something like n rows have m items and the total number of items is (n * m) + 1. And you want the first (m+1)th item to be in row 1.

Yes, you’d be wasting your time with flexbox. You’d also be wasting your time complaining flexbox doesn’t support this.

To be clear, I don’t see a spec in any of the exceptions you’re carving, and you’re not providing one, just saying “flexbox can’t do this”.

You’re right. it can’t.


Never mind flexbox, what generalized rule would yield 5+4+4+4 instead of 5+5+5+2?

I’m not sure whether you’ve read my comments elsewhere in this discussion, but the short version is that this is about balancing the number of items in each row while not requiring any extra space compared to the naïve layout. Formally, the goal might be to minimise the maximum pairwise difference between the number of items in the rows, subject to not using more rows than the existing flexbox behaviour and keeping any longer rows earlier in the order. My earlier example assumed all items had the same size, but this isn’t a requirement for flex items and the balancing concept could be generalised by taking into account item sizes and flex settings instead of just looking at the counts.

Good typesetting can vary spacing and possibly hyphenation to give a balanced look to a paragraph, and somewhat complicated algorithms exist to do this well. It doesn’t seem an exotic requirement to have similar attention to detail in laying out flexed content in 2D, and it would certainly allow results that look better than what often happens today.


> Formally, the goal might be to minimise the maximum pairwise difference between the number of items in the rows, subject to not using more rows than the existing flexbox behaviour and keeping any longer rows earlier in the order.

I've not looked at your comments elsewhere in this discussion, but this makes sense as a specification.


I run into this problem constantly, but I've never come to a universal solution that could be standardized for general use as a new flexbox CSS property. It would be nice to be able to indicate that rows should have the same number of items (except the last row), the last row should be as full as possible even if it means using a different size for the other rows, and the items on the last row should be aligned as if the row was filled after them.


For the 5+5+5+1 example, there is a fairly easy way to accomplish that:

Append n dummy items to your list, where n is the maximum number of items you expect on a single line. They should have a height of 0, and the same width / margin as your regular items.

The "2D justification" where items occupy space intelligently would be awesome, but I doubt CSS will ever allow that.


You can also use grid layout with `repeat(auto-fill, size)` it behaves very similar to wrapping in flex box, except when it wraps, the items still conform to the column specification


Sure, there are various workarounds for the left justification problem, but none of the ones I know is attractive. Anything based on adding extra items defeats one of the main advantages of flexbox, which is that you don’t need to know in advance how many items per line will fit and if the user resizes their browser then the layout will automatically adapt. Anything based on using :after to fill the space on the final line only works if you’re left-aligning everything with no space outside.

I think what is really needed here is an extra property specifying how to handle the last row (or column for vertical flex) of the layout that is separate to the normal justify-content property but takes the positions of items in the preceding rows (columns) into account, roughly analogous to the subgrid concept for CSS grids.

I don’t think the “2D justification” problem would be that difficult to solve either. Again, it just needs a single extra property, in this case to specify whether and how to balance item counts across all rows (or columns, depending on flex direction). A simple approach would just repeatedly shorten all of the preceding rows by one item and add the same total number of items to the final row until doing so again would make the last row longer than the rest. Then redistribute the horizontal space throughout according to the normal justification, which at least minimises the difference between the number of items in the final row and the rest without needing any extra space for the overall layout.

A slightly more sophisticated treatment might offer a third option that can shorten more than just the final row, distributing any difference in item counts over multiple rows instead. For example, 5+5+5+2 would become 5+4+4+4. In this way, you would at worst have a set of earlier rows and a set of later rows where the item counts differed by no more than 1. Presumably you would also then apply the final row justification property imagined above to all rows in the later set, if you don’t have the same number of items in all rows.

Maybe in the future we’ll see a Flexbox Level 2 spec that addresses issues like these, just as subgrid is coming with level 2 of the grid layout spec.


I lost a paragraph above. There was supposed to be a final version of the balancing behaviour that considered not just item counts but space used and flex behaviour for each item, adjusting breaks over the whole flex container in a similar way to Knuth-Plass justification of a text paragraph. There was also an observation that this made the layout algorithm much more complicated and might be going too far down the rabbit hole. :-)


Flexbox was a major game-changer for how I get layouts done. SO glad it exists! Can't wait until our customer transitions off of IE so I can learn Flexgrid (yes, IE has Flexgrid, but it's a different syntax and semantics, alas... MS jumped early, and then didn't track the standard, IIUIC).


In one dimension, yes, sometimes. But I find myself having better control with grids, even in a single dimension.


Css grids > flex box.

I don’t ever want to touch flexbox again after learning css grid


But they're good at different things?


CSS-Tricks also has a more practical guide which has been essential for me: https://css-tricks.com/flex-grow-is-weird/


Once I started thinking about flexbox the way I thought about QT GUI's it all started to click for me. Especially flex-grow being basically equivalent to BoxLayout's "stretch" I was able to easily make responsive "GUI-like" programs very quickly.

I don't even bother with justify-content anymore, elements with flex-grow combined with min-width and max-width pretty much cover all my required "layout" use cases.


Yep. Nearly every flex child for me is either

  flex-grow:0;
  flex-shrink:0;
or

  flex-grow:1;
  flex-shrink:1;
And the latter on an empty div makes a really nice "spacer"


Getting CSS layout right can be extraordinarily difficult, borderline impossible, absent the right understanding and set of composable primitives.

As someone who's done web development since the late 1990's, I offer my very highest praise and unreserved recommendation for an extraordinarily thorough, coherent and practical resource I only recently discovered: https://every-layout.dev

Its "Axiomatic CSS" is, finally, a standards-based solution that provides a solid foundation for truly responsive layout and design.


Nice guide, thanks for writing it. I can never remember which directions align/justify impact. The best mnemonic I could think of was justified text. When you click the justify button on a text paragraph in a typical word processor, it impacts the text in the same direction as justify-content in flexbox does.


You just have to remember that if the flex-direction is column, align/justify also flip. Which is partly why it's so confusing.


Defining then relative to the flex direction makes sense, but the choice of which one is with the flow and which is across it is arbitrary, chosen between two words that normally mean with the flow. It'd make more sense if the properties were flex-justify and flex-justify-cross, or flex-align and flex-align-across.


They are the same in relation to the flex-direction. Justify goes with the direction, align goes perpendicular to it. But still I agree, I've now been using flexbox for a long time and I still find myself second guessing a lot.


Reading your comment gave me the mnemonic “a line goes perpendicular to it” which I think will come in handy (for me at least).


Another guide that I found added clarity around flexbox:

https://internetingishard.com/html-and-css/flexbox/

I think often it is about finding a guide by an author who happens to explain things in the way that clicks with you. For me, this one really helped.


For figuring which flexbox options I want, I always use this: https://cvan.io/flexboxin5/ bit of a flexbox editor/explorer


Can't wait for you to try CSS Grids


I sympathize with this. Everytime I want to use flexbox, I end up searching and reading and rereading CSStricks' guide. And then experimenting until I get what I am after. One of these days I'll stick...


The explanations are good, but there's quite a gaping hole when you don't include any "flex-*" properties.


Hey, thanks! I intentionally left out all the other ones. This was a deliberate reductionist view of the feature.


I have been messing around with Flexbox quite a bit at work and this will be a super useful reference, thanks!


Good concise article. Is there a tool to create such figures. They look really neat.


Thanks! As for the images, I drew them in Sketch.


Super useful! Thank you so much for this.


This is a super helpful guide! Thanks!




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

Search: