Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[css-values] hem: font-relative unit, relative to host element font-size #7613

Closed
jonathandewitt-dev opened this issue Aug 17, 2022 · 9 comments
Labels
css-values-4 Current Work

Comments

@jonathandewitt-dev
Copy link

jonathandewitt-dev commented Aug 17, 2022

For better CSS encapsulation using Shadow DOM, it would be nice to enable relative sizing without coupling styles to the HTML structure.

The em Problem:

2em at the browser default 16px becomes 32px. Children of that element now interpret 1em as 32px. This makes it very difficult to keep track of sizes going down the tree, and it tightly couples the styles to the HTML structure. It would be better to have a common base size shared between all elements.

The rem Problem:

1rem is always relative to the document root, and not the shadow root. This means the component's scale can't be adjusted unless a global change is made. It would be preferable to instead provide a base size for each component, independently from the document root.

The Proposed hem Solution:

1hem could be equivalent to the component's :host element font-size.

<x-calendar></x-calendar>
x-calendar {
  --size: 0.5rem; /* by default, this will be 8px */
}
/* inside x-calendar's Shadow DOM */
:host {
  font-size: var(--size);
}
.calendar-wrapper {
  width: 50hem; /* this will be 400px, as 1hem is equal to 0.5rem (8px) as defined above. */
}

Alternative:

If it makes more sense to do so, we could perhaps consider allowing styles on the shadow root via :root, and just use rem as we usually would.

Link to the spec:

https://www.w3.org/TR/css-values/#font-relative-lengths

@SebastianZ SebastianZ added the css-values-4 Current Work label Aug 17, 2022
@jonathandewitt-dev
Copy link
Author

I wonder if this would have any crossover impact on the spec for Shadow DOM also.

@Que-tin
Copy link

Que-tin commented Aug 19, 2022

While reading and thinking about this, I wonder if there is a good amount of use cases for something like cem (Container em) in the future. Could be useful if you are creating design systems at scale, which's components are being used across multiple different website with different layouts and behaviour.

@jonathandewitt-dev
Copy link
Author

jonathandewitt-dev commented Aug 19, 2022

I wonder if there is a good amount of use cases for something like cem (Container em)

Interesting thought, I take it you're referring to the container property? I can get on board with that.

@tabatkins
Copy link
Member

Hm, I believe something like this would work today?

@property --hem {
  syntax: "<length>";
  initial: 1em;
  inherits: true;
}
:host {
  --hem: 1em;
}
.in-the-shadow {
  font-size: calc(2 * var(--hem));
}

When the property is registered like this, it'll process its value using standard computed-value rules, so the 1em will turn into a px length based on the font-size of the element it's set on (the host element, here).

And once Variables 2's custom units are in, it can be used directly as a unit, like font-size: 2--hem;.

@jonathandewitt-dev
Copy link
Author

Nice! This is actually pretty similar to what I ended up doing as a work-around, but I wasn't aware of custom units. That ought to be a really handy addition. :)

I guess my next question is, would you classify the custom unit as the standard approach? Or is it more like a custom workaround for the lack of a native unit? I'm a little torn on that still. What are your thoughts?

@jonathandewitt-dev
Copy link
Author

I guess, if I think about it, the custom unit might be a little too flexible in a team setting. There's no guarantee that --hem will be exclusively set only in :host selectors. Not unless there's some way you can set a rule to enforce that, preferably without linters or build tools.

I do like that we could flexibly use custom units to address both web component scale and container scale mentioned by @Que-tin. I can imagine I'll find other uses for them also, you gave me something new to look forward to!

@tabatkins
Copy link
Member

Yeah, variables can be used in all sorts of unexpected ways, but since you can get this information in this (fairly simple) way, it lessens the potential need for us to add a new CSS feature for it instead.

I guess my next question is, would you classify the custom unit as the standard approach? Or is it more like a custom workaround for the lack of a native unit?

I'd call it "given the infinite variety of potential needs, we're constrained in what we can actually address, and prefer to only add new features for things that are either difficult/impossible, or very common". ^_^ If something is relatively less common and/or has a fairly easy way to achieve it by hand, it's usually best to leave it to userland.

@jonathandewitt-dev
Copy link
Author

given the infinite variety of potential needs ... [we] prefer to only add new features for things that are either difficult/impossible, or very common

That's fair, I'm satisfied with that solution to be honest. Just wanted to give it a fair discussion!

@jonathandewitt-dev
Copy link
Author

jonathandewitt-dev commented Aug 21, 2022

I'll go ahead and close this issue, as it sounds like it will be a no-go for the foreseeable future. If anyone else winds up here from Google in search of a solution, I want to point out that @jonathantneal made a PostCSS plugin for support of the variable unit syntax. I opened an issue to add a native PostCSS plugin for this, but as of 8/21/2022 it is still too early to adopt.

If your project is small enough, you could always parse the CSS at runtime, though I would recommend a build step if possible. Here's a little experiment of mine, trying to polyfill a vanilla project.

Finally, just for archive purposes, here's the discussion on variable units.

Thanks to all for hearing me out!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
css-values-4 Current Work
Projects
None yet
Development

No branches or pull requests

4 participants