Hacker News new | past | comments | ask | show | jobs | submit login

How is CSS like trial and error?



Because, compared to some modern layout systems, it takes longer (to put it lightly) to internalize the exact logic behind the implementation of all CSS properties and be able to simulate how they interact in complex UIs in your head.


Can you provide some examples of modern layout systems? I’d be curious to see what’s on offer.

I have experience with various iterations of UIKit’s auto layout, Yoga, as well as CSS and some Swift UI. I’ve found CSS to be considerably easier to work with, particularly when using flexbox and grid.


Ok, then please implement the following in CSS:

   Outer
   +---------------------------------+
   |                                 |
   | Left        Middle        Right |
   |                                 |
   +---------------------------------+
Everything should be vertically centered. Left should stick to the "left" of the outer div, "middle" should be centered, "right" should stick to the right. Left/middle/right can have different widths and heights.

In AutoLayout this is achieved by 6 constraints:

- left.left = outer.left

- left.centerY = outer.centerY

- middle.centerX = outer.centerX

- middle.centerY = outer.centerY

- right.right = outer.right

- right.centerY = outer.centerY

I'd like to see how you implement it in CSS. (note: extra wrapper divs are not allowed)


Assuming your div has a class of outer it’s:

.outer { display: flex; justify-content: space-between; align-items: center; }

…and that’s it. (This is assuming your items are of equal width of course. It gets a little bit more complicated if not.)


I've literally told you the items can be of arbitrary width and height. `space-between` won't keep the middle item centered.


Chrome just added CSS Anchor Positioning this year. The other browsers also expressed interest in implementing it, with Firefox having announced an Intent to Implement. The feature would likely be available on all major browsers sometime next year.

So here's how your example would work using it:

.outer { width: 100%; height: 400px; background: aliceblue; anchor-name: --outer; }

.left { width: 100px; height: 100px; background: white; position: absolute; position-anchor: --outer; left: anchor(left); align-self: anchor-center; }

.center { width: 150px; height: 200px; background: pink; position: absolute; position-anchor: --outer; justify-self: anchor-center; align-self: anchor-center; }

.right { width: 160px; height: 150px; background: gray; position: absolute; position-anchor: --outer; right: anchor(right); align-self: anchor-center; }

Source: https://developer.chrome.com/blog/anchor-positioning-api


Cool! Is it going to be the sixth or the seventh positioning system in CSS?


.parent { display: grid; grid-template-columns: 50px 200px 80px; justify-content: space-between; align-items: center; }

An interesting thing you can do with grid is align the tracks.

I wrote about this here:

https://cssprinciples.com/3/grid/#justify-and-align


No. You're hardcoding the item widths in `grid-template-columns`. The left/middle/right items should be self-sizing. E.g. consider three divs with arbitrary text content.


Grid allows minmax(a, b) to specify the bounds of tracks. Possible values can be the remaining free space in the parent (fr), or the size of the content in the child.

There is also fit-content:

E.g: grid-template-columns: fit-content(150px) …


Sorry, but I don't understand what you're describing. Can you maybe show it in jsfiddle?


I am just saying the columns of the grid can be dynamically sized depending on their contents.

Tracks is a grid term for rows or columns, as it works in both dimensions.


I'd like you to demonstrate your approach with this jsfiddle: https://jsfiddle.net/nbdowrcm/

As you can see, the middle element is not centered.


I see.

https://jsfiddle.net/Lah5g3vb/

Changes:

- each col is now 1fr (3 cols, 33% each)

- the child elements align inside the col using `justify-self: start | center | end`


Not good, because now the elements are limited to 33% width of the container.

See: https://jsfiddle.net/e0un5Lxk/

The middle content is unnecessarily wrapped into two lines, even though there's plenty of space available.


You can also use `minmax(min-content, max-content)` for the center col: (https://jsfiddle.net/y193p2b6/).

But this does not keep the center col exactly centered, but it does allow the content to take the free white space and then wrap when needed.

In your original post with Swift, what happens?

I am not familiar with auto layout so I do not know the exact behaviour vs CSS. Do you have a few screen shots of how it would handle different sized content?


But now you just added `whitespace: no-wrap` to the middle element, with `overflow: visible`, to force it into a single line. That's hardly a generic solution, because it makes assumptions about the contained items... i.e. applying `whitespace: no-wrap` and `overflow: visible` will typically break the appearance of things.

Regarding AutoLayout: the six constraints from my original comment, don't say anything about the relationship between the left/middle/right items, so they will simply overlap if there isn't enough space. This can be remedied by adding two extra constraints:

1. left.right < middle.left

2. middle.right < right.left

It's just a bunch of equations. No weird tricks, no special cases, no hacks. You describe what you want with equations, and the solver spits out the solution.


Do you have an email? I am thinking of doing a blog post comparing css/auto layout, and would like your input?


Sure: gvjjdcnohdt@protonmail.com


Yeh, I edited my reply, I realised what you meant afterwards.

Auto layout does sound neat.


Either put left, right as absolute (like the following) and leave middle in the flex, or do the opposite. One may decide which option to use based on whether the centre or the left/right is more semantically important in the layout.

We did have to use some CSS "tricks" (transform for absolute centring), but once you've learnt those then CSS is indeed quite sane.

  outer {
          flex-direction: row;
          justify-content: center;
          align-items: center; }
  left, right {
          position: absolute;
          top: 50%;
          transform: translateY(-50%); }
  left {
          left: 0; }
  right {
          right: 0; }
(This kind of layout, which is common in eg top nav bars, is slightly deceptive. robin_reala's solution does not conform to requirements that left and right can be different widths, which would cause middle to be not centred under simple justify-content: space-between.)


Yes, this is the correct solution.

Which underlines the original point, that CSS is a hodgepodge of different ideas with no overarching system behind them. A simple task like this needed 3 different positioning systems:

1. flexbox for positioning the middle item

2. absolute positioning for left/right

3. and the translateY(-50%) trick for vertically positioning the absolute positioned items


Touché. Indeed, CSS forces one to recognise layouts that may not conform to a layout 'flow' in boxes.

In its defence, I suppose recognising this is important, as to make potential box overlaps explicit (which is typically unwanted).

CSS also handles a whole lot of things other than layout, which I'm not well informed of layout constraint systems being able to handle. Being a hodgepodge is an advantage, comparable to how its a great advantage that one can invoke any hodgepodge systems task from bash, as one single tool.


Maybe something like this, which relies solely on flex box for layout.

    .outer { 
      display: flex;
      justify-content: space-between;
      align-items: center;
    }

    .left {
      flex: 1;
      display: flex;
      justify-content: flex-start;
    }

    .middle {
      flex: 1;
      display: flex;
      justify-content: center;
    }

    .right {
      flex: 1;
      display: flex;
      justify-content: flex-end;
    }


Wrong. `flex: 1` will cause the items to have a max-width of 1/3rd the container width. E.g. if the left and right items are small icons, and the middle one is a longer text, then the text will be forced to wrap into multiple lines as soon as it tries to grow beyond 1/3rd of the available space, even though there's tons of wasted space on the left/right.


In this specific example, I am pretty sure margin-right: auto on left and margin-left: auto on right in a flex-box does what you want.


Wrong. The middle item will be misaligned from the center if "left" and "right" have different widths: https://jsfiddle.net/hxe8pcuf/


Does anybody know how you'd solve this in tex (not latex, tex) or in some other constraints-based layout system like Cassowary?




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

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

Search: