Re: [css-values-4] inherit(<integer>)

On Tue, Jul 9, 2013 at 5:34 PM, Lea Verou <lea@w3.org> wrote:
> I would like to propose an inherit(<integer>) function, akin to the inherit
> keyword, but inheriting from a higher up ancestor than just the parent.
> inherit(1) would be equivalent to the inherit keyword, inherit(2) would
> inherit from the grandparent and so on. If the parameter is larger than the
> current element’s levels of nesting, it could:
>
> a) resolve to `initial` OR
> b) be clamped to the levels of nesting that correspond to targeting :root OR
> c) be invalid
>
> I think (b) is more useful, but not sure about implementability.
>
> 0 would resolve to `initial`. Negative parameters would make it invalid.

I understand your use-cases, but I'm afraid of this exact solution.  I
believe it will encourage brittle practices, where adding an extra
wrapper into your html will break a lot of styling that was depending
on inheriting from something exactly N levels up.  I think we can
probably address your use-cases in a more targetted manner.

> Use cases
> ---------------
>
> - A generated content pseudo-element inheriting from the parent element.
> This is especially useful for background effects. Relevant: [1]

This sounds quite useful, but could be addressed in a more limited
manner, such as by adding an additional keyword that means "inherit
from the parent element" on pseudo-elements, and just "inherit" on
normal elements.

> - Inheriting background and other colors from any ancestor could be a good
> alternative to variables for certain cases when loose coupling is desired
> (e.g. components that are dropped in an environment where their ancestors
> are controlled by different developers)

Can you expand on this?  I'm not sure what you mean here.  I think
perhaps you're saying that the outside world doesn't know the
component exists (and so can't set variables for it), but the inside
wants to use values inherited into the component (but which might be
blocked by some wrapper inside the component)?

If this is the case, I think this can be addressed more directly by
allowing custom properties to be set to the inherited values of other
properties.  This has been requested for some time, and I plan to
explore something like it in Variables 2.

> - Inheriting a font-size and/or line-height from the grandparent when the
> parent’s font-size/line-height are set to 0 (common for accessible text
> hiding) or any other absolute value.

Hm, interesting.  Why would you be putting something visible inside of
something doing a11y-text-hiding?

If this is legit, I think it would actually be clearer to address it
in an inverted manner - put something on the parent that says that you
ignore its value for inheritance, and instead propagate its parent's
value.  That way *anything* below it gets the grandparent value.

> - I've needed this personally many times for a number of different use
> cases, that escape me now. I will update this thread as I remember them (if
> anyone else can remember use cases too, even better!) , but I wanted to get
> implementor feedback first about whether this is feasible at all.

I'd be glad to hear more!

> Furthermore, this will eliminate the need for toggle() [2], which is
> currently at-risk and not implemented anywhere AFAIK. For example, the use
> case of lists in the spec [2] could be written like this with the inherit
> function:
>
> ul { list-style-type: disc }
> ul ul { list-style-type: circle }
> ul ul ul { list-style-type: square }
> ul ul ul ul { list-style-type: box; }
> ul ul ul ul ul { list-style-type: inherit(4); }
>
> Yes, it’s significantly more code, but:
> a) it’s easier to understand
> b) it degrades more gracefully for UAs not supporting the inherit function
> c) the use cases for toggle() aren't that common to need a shortcut, they
> just need to be *possible* with a finite amount of code.
> d) it's more flexible

Nope, this doesn't work, and is a good example of why I think this
particular idea is too fragile.  ^_^  You're assuming that the <ul>s
are directly nested inside of each other with parent-child
relationships, but that's not *ever* true for valid HTML - there's
always *at least* an <li> between one <ul> and the next, and sometimes
more.  Even if you changed it to inherit(7), it would fail as soon as
you did something like wrap a <div> around one of the inner <ul>s.

Further, this goes very wrong as soon as you start mixing <ul> and
<ol> - your <ul> might inherit a numeric list-style!

Finally, this definitely doesn't work for other toggle() use-cases,
like the italic/normal switching.  In general, this is just not
actually useful for replacing toggle() in any but the most constrained
cases.


So, to sum up, I think the use-cases are valuable to solve, but I
think we can do them in better, more robust ways.

~TJ

Received on Wednesday, 10 July 2013 03:33:49 UTC