Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Modern CSS One-Line Upgrades (moderncss.dev)
242 points by thm on Jan 29, 2024 | hide | past | favorite | 29 comments


> The other value of pretty specifically addresses preventing orphans and can be more broadly applied. The algorithm behind pretty will evaluate the last four lines in a text block to work out adjustments as needed to ensure the last line has two or more words.

This is very, very badly wrong. `text-wrap-style: pretty` is explicitly not about orphans and does not have a defined algorithm. It’s about prettiness, a subjective thing that will have different interpretations in different browsers and over time, and this is extremely deliberate. What the author has described is what Chromium has implemented at this time.

All the spec says is <https://www.w3.org/TR/css-text-4/#valdef-text-wrap-style-pre...>, that `text-wrap-style: pretty` “Specifies the UA should bias for better layout over speed, and is expected to consider multiple lines, when making break decisions. Otherwise equivalent to auto”.

TAG review of the feature requested that implementers use at least two heuristics, “to avoid authors using it as a proxy for a more specific thing” <https://github.com/w3ctag/design-reviews/issues/864#issuecom...>.

For total clarity: ‘pretty’ is not necessarily any different from ‘auto’, and ‘auto’ is permitted to do exactly the same thing as ‘pretty’ does, and I hope and expect that browser makers will eventually go that direction for most contexts (contenteditable/<textarea> being the main exception, and maybe lower-powered platforms). If you explicitly want a greedy/first-fit technique, use `text-wrap: stable`. Firefox has had a bug open for 13 years where shifting in this direction and using Knuth–Plass almost everywhere has been seriously contemplated <https://bugzilla.mozilla.org/show_bug.cgi?id=630181>, long before text-wrap-style.


How long does the standards committee think it can continue this approach to developing CSS? While these new properties are undoubtably useful I can't help thinking they point to a fundamental flaw in the design of CSS. Take `margin-inline` for example. This is only necessary because CSS provides insufficient means of abstraction. If the designer could themselves define something like

   margin-inline(width) = margin-left(width) margin-right(width)
(Ignoring text direction for simplicity) the problem goes away. I think the CSS committee should be focused on providing means of abstraction and composition, so that CSS users can create their own abstractions, instead of adding more and more properties to CSS.


CSS Houdini is a set of apis aimed at what you mention (create your own CSS abstractions)


I think you’ve taken a bad example if you wish to show your point. You’ve actually simplified the answer for why it is how it is right out of it!

Consider margin-inline’s actual grammar (<'margin-top'>{1,2}) in a somewhat more functional notation (all still pseudocode):

  margin-inline(start = <length-percentage> | auto, end? = <length-percentage> | auto)
    = margin-inline-start(start)
    + margin-inline-end(end else start)
Are margin-{inline,block}-{start,end} the primitives? If you want them to be composed, oh boy, have fun (I’m not even going to try to show this all, and I don’t even want to know the sort of execution model that could make this work, but it’s vastly more complex than all the rest of CSS syntax put together):

  _inline-start = match (WRITING_MODE, DIRECTIONALITY, TEXT_ORIENTATION) {
      (…, …, …) => left,
      (…, …, …) => right,
      (…, …, …) => top,
      (…, …, …) => bottom,
  }

  margin-inline-start = margin-${_inline-start}
You could replace that margin-inline composition with margin-${_inline} composition. Et cetera ad tedium et a good deal of nauseum. It gets messy. Really messy. No, I don’t think it’s sensible to have Logical Properties be anything but a new set of primitives alongside top, left, right and bottom.

But now I want to show that there’s actually absolutely nothing wrong with margin-inline specifically:

It’s a shorthand. Just a perfectly ordinary shorthand for margin-inline-{start,end}, like background-position is shorthand for background-position-{x,y}, and background shorthand for background-{color,image,repeat,size,position,…}.

(Not all hyphens are hierarchical; margin-inline-start is margin→inline→start and background-size background→size, but box-sizing is not box→sizing, and text-decoration-thickness is only text-decoration→thickness, and I’m just going to close my eyes against the mistake that is border-{top,bottom}-{left,right}-radius. But where the hyphens are hierarchical, CSS philosophy just about demands corresponding shorthands.)

In fact, this specific one corresponds to something that was missing in the old order of things, which should really have been added but maybe wasn’t because there it wouldn’t have been a regular shorthand of X → X-* properties: margin-{horizontal,vertical}. See, the two- and three-value syntaxes of the margin shorthand get to express left and right margin in one value. Do you know how often people have accidentally clobbered top or bottom margin because they just wanted to specify left and right margin in one line, but wrote `margin: 0 auto` since there was no `margin-horizontal: auto;` and they didn’t like writing `margin-left: auto; margin-right: auto`? It’s more than a few. This is something that should have been present in the past, but wasn’t, and if CSS had had something like you describe for abstracting or composing it wouldn’t have helped because people certainly wouldn’t have used it for such cases; instead we just need CSS to include the right thing, like it does now:

  margin: vertical horizontal;
  /* Becomes, typically: */
  margin-block: vertical;
  margin-inline: horizontal;

  margin: top sides bottom;
  /* Becomes, typically (you could also merge the two block lines into `margin-block: top bottom`): */
  margin-block-start: top;
  margin-inline: sides;
  margin-block-end: bottom;
Really, something like margin-inline just falls out very neatly from CSS’s shorthand scheme. There’s nothing special or bad-abstractiony about it, and I hope CSS keeps on doing things like this.

Now then, abstraction and composition. Frankly, CSS properties have never been a place for this, beyond shorthands themselves. It’s just not a design goal at all, and a few attempts at bringing something like it in (e.g. @apply) have failed for various reasons, not least of which is they just don’t fit into CSS. Even in the case you’ve described, you had to (or maybe only chose to?) simplify the most important part of it out of existence.

My personal summary: you see a problem in CSS’s fundamental design, I don’t see it as a problem but a deliberate feature and I don’t think anyone’s suggested any alternative yet that’s actually workable and would be used and wouldn’t damage CSS.


> Now then, abstraction and composition. Frankly, CSS properties have never been a place for this, beyond shorthands themselves. It’s just not a design goal at all

It’s actually an anti goal; the W3C are intentionally avoiding making CSS more powerful. The rule of least power has been an explicit design principle for the World-Wide Web since the early days. If they wanted a more powerful language, they would have selected JSSS as the style language for the web, not CSS.

https://www.w3.org/DesignIssues/Principles.html

https://www.w3.org/2001/tag/doc/leastPower.html


The core of CSS layout, as I understand, is a few different layout algorithms (flex, columns, normal blocks, etc.) Properties are knobs to customize these algorithms. Internally I assume it's a constraint solving problem.

The kind of language I would be interested in would expose the constraint solving directly. So it would be much more like Prolog than, say, Rust.

You seem to working from the basis of reproducing CSS as it currently exists, and keeping design principles of CSS. This is reasonable POV, but these are not assumptions I share in my musing here.


Some parts of layout are constraint solving, but not all, not by a long shot. And CSS is about a lot more than layout. And most of the rest of CSS is absolutely nothing to do with constraint solving. So even though you can do layout as an exercise in constraint solving, you couldn’t just replace CSS with a constraint solver. And even if you did switch to some foundation of constraint solving, you’d just be replacing one form of complexity with another—one that’s more complex in the base case, more flexible in certain unusual cases, and generally has worse performance traps. Houdini, as mentioned by another, is an interesting concept that could blend the two worlds profitably.

(By the way: your original comment implied nothing whatsoever to me about a change in foundation toward constraint solving. That does make it a more interesting proposition, but also fairly firmly unachievable for the web.)


They should expose a simple, low-level layout API like GTK has had for 30 years.


I thought I am up to speed with modern CSS but I did know about scroll-behavior: smooth but did not know about scroll-margin-top at all. I use self written JS solution to work around headings stick below my fixed navbar this that I can get rid of now. That is awesome.

I generally, even without navbars think the scroll to position should have the headings a bit more down towards the middle of the page not the exact top, never liked that behavior. Glad there is a thing for that now, makes so much sense.


> but did not know about scroll-margin-top at all

I used hidden links with `position: relative` and a negative offset to achieve this before. `scroll-margin-top` is a much better solution.


Yesterday I was reaching for the JS I have used in the past for smooth scrolling to anchor links, until I discovered that `scroll-behavior: smooth;` exists.


Thank god. Most if not all “smooth scrolling” suck on devices that already offer smooth scrolling natively. I tried contributing solution back but they just didn’t care.


Native smooth-scrolling is one area where Safari is actually really good and Chrome is bizarrely awful.


Won’t you still need some smooth-scrolling JS for cases where you’re scrolling to an element dynamically? Like when updating a route without a full page load or click.


Nope!

    Element.scrollIntoView({ behavior: 'smooth' });
https://developer.mozilla.org/en-US/docs/Web/API/Element/scr...


> width: fit-content

Wow I didn't know about this one. Seems super useful, especially in a multilingual context where you kind of guess a size that will work for anything.


`text-underline-offset: 0.25em;`


This is nice. Now, we no longer need to replace `text-decoration` by removing it and adding a `border-bottom`.


I don’t get why people want to control this. My experience is that it’s almost always a mistake when they do it, or that they were working around a bug in one specific platform/browser/font combination, at the cost of others. I don’t deny that legitimate uses exist, not quite, but it’s seldom a good idea.


The accent colour one is awesome


I was excited about these but turns out most of them don't work on Firefox Mobile for me.


That doesn't stop you using them. 'responsive design' and 'progressive enhancement' are about delivering the best possible experience for the user using the capabilities of their device. That means not giving everyone the same experience. Make it better where you can.


I would honestly rather not make any user's Chrome experience better than Firefox given the curtent marketshares. It would not feel ethical to me to partake in helping Google seize more power on browsers.


In my experience, it's Chrome that usually lags behind in implementing new standardized features (subgrid, for example).


I’m primarily a safari user but spent a few months with Firefox and Brave and now recently with Arc. I always feel like whichever rendering engine I’m not using atm is lagging so far behind.

To me that means realistically there’s probably a pretty healthy amount of technical competition in the industry, and just too much for any one team to tackle.

I do think safari takes a little bit too much heat though (but I’m biased :D)


Modern-day IE does need some heat though.


On Android? You must be on an ancient version then. All of these things—except for the new `word-wrap: pretty` property value—are supported in Firefox for Android.


"text-wrap: balance;" works, only "pretty" is not yet supported


Huh? Which ones? I also use Firefox Mobile and they all seem to work.




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

Search: