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-content][css-pseudo][css-cascade] Does content:contents in pseudo affect inheritance? #1195

Closed
Loirooriol opened this issue Apr 9, 2017 · 12 comments

Comments

@Loirooriol
Copy link
Contributor

CSS Content allows to move the actual contents of an element into the ::before or ::after pseudo-element.

How does this affect inheritance? Do the actual contents of the element still inherit from the element, or do they inherit from the pseudo-element?

For example:

div {
  content: none;
  color: red;
}
div::before {
  content: contents;
  color: green;
}
<div><span>Foo</span></div>

Should Foo be green or red? On the one hand, CSS Cascade says

Note: Inheritance follows the document tree and is not intercepted by anonymous boxes, or otherwise affected by manipulations of the box tree.

so maybe the span should inherit from the div and be red. On the other hand, CSS Pseudo says

these pseudo-elements generate boxes as if they were immediate children of their originating element, and can be styled exactly like any normal document-sourced element in the document tree.

Personally I would expect green, like if I had used content: "Foo" instead of content: contents.
As far as I know, there is no implementation of this to test.

@tabatkins
Copy link
Member

Each pseudo-element defines what its originating element is; that's what it inherits from. Nothing inherits from a pseudo-element (unless/until we allow nesting pseudo-elements).

content: contents is not defined anywhere near sufficiently to actually be implemented, but the way it would have to work to be sane is to just reparent the child boxes from the originating element to the pseudo-element. Inheritance happens long before box construction, so the "Foo" text will definitely be red, as it inherits its color from the span, which inherits it from the div.

(The contents value needs to get dropped anyway; it only existed to enable the footnoting machinery; you'd move the contents of the element into a pseudo with content: contents, then do something with a property that I believed was called move-to, which has been removed, and leave behind a footnote marker with the ::marker pseudo. Since most of the machinery has been dropped, the contents value no longer does anything useful.)

@Loirooriol
Copy link
Contributor Author

Loirooriol commented Apr 10, 2017

Thanks, makes sense. However, it's not true that nothing inherits from a pseudo-element, there is ::first-line:

During CSS inheritance, the portion of a child element that occurs on the first line only inherits properties applicable to the ::first-line pseudo-element from the ::first-line pseudo-element.

Precisely, there are some problems with this, please see #1097.

Anyways, it's sad contents will be dropped, seemed so useful to me. This makes me more convinced there is a need for a nesting pseudo-element which wraps the actual contents of an element.

@bradkemper
Copy link
Contributor

I don't think that's the only reason it should exist. What happened to using it as an alternative to sub-grids, for example?

@bradkemper
Copy link
Contributor

Sorry, I was thinking of 'display: contents'.

@bradkemper
Copy link
Contributor

One use case for having 'content:contents' on a pseudo (and 'content:none' on the original element), is that it turns the original element into a wrapper box, which can be useful sometimes. For instance, just of the top of my head, it would allow you to have two borders: one on the element, and one on the pseudo containing the content.

@Loirooriol
Copy link
Contributor Author

And also interesting things like using content:contents in a pseudo-element and display:contents in the element, in order to separate the other pseudo-element from the actual contents. For example, this way both pseudo-elements (the one which contains the actual contents and the generated one) can be different flex items of the same flex container. It would be like generating a pseudo-element outside the element.

@tabatkins
Copy link
Member

One use case for having 'content:contents' on a pseudo (and 'content:none' on the original element), is that it turns the original element into a wrapper box, which can be useful sometimes.

That's a hack, tho - it only allows you to add a single wrapper, and it removes your ability to add ::before/::after to it. This isn't a reasonable justification for the value.

@bradkemper
Copy link
Contributor

That reasoning is true for all pseudo-elements. For instance, '::after' only lets you add a single box at the end of an element's content, and removes your ability to use ::after for some other purpose. One could also argue that most actual use of ::before and ::after are hacks.

The "hacks" described above would be nearly as useful as ::before and ::after, in a wide variety of circumstances.

@tabatkins
Copy link
Member

Multiple ::afters has been discussed before. It's been rejected only for lack of strong use-cases; it's not seen as anything bad.

I... don't think it's defensible to claim that the mentioned technique isn't a hack? It's abusing two completely unrelated abilities to achieve a third unrelated thing, and has a number of arbitrary limitations/drawbacks, not intrinsically linked to the thing being achieved, as a result. That's more or less the definition of a hack.

@bradkemper
Copy link
Contributor

Labeling it as a hack doesn't change the fact that most of what ::before and ::after are used for fit the same definition you give above, and they are also incredibly useful nonetheless.

What you call "abuse" because it wasn't part of the original intent, I would call atomic capabilities that can be applied to a much wider set of design problems, where changing the markup to add elements isn't a practical alternative.

@frivoal
Copy link
Collaborator

frivoal commented Apr 13, 2017

I think the biggest problem with multiple ::afters was not the lack of use cases, but the problem of ordering.

  • if they are numbered ::afters, they cascade poorly and clash, as different parts of the stylesheet are not necessarily aware of what other parts are trying to do with ::after. Also, this sort of encourages authors to use "BASIC line numbering", and go 10 by 10 or some such, to leave gaps between each after, so that they can put another one in between later on.
  • An alternative is to name them instead of numbering them, so if you've got ::after(clearfix), ::after(decoration), it's much easier to work with and avoid conflicts, but you've now got to worry about ordering them.

I don't think this is an unsolvable problem, but I seem to remember that bumping into it showed that multiple afters was not as straightforward as previously expected, and that decrease people's enthusiasm for it enough that we've not touched it since.

Am I misremembering?

@bradkemper
Copy link
Contributor

I think multiple "::after" pseudos is something authors want. But my point was that "only allows you to add a single [::after], and it removes your ability to add [another] ::after to it" has not stopped::after from being incredibly useful in a wide range of situations, and the same could be said about 'content:contents' and 'content:none' to create wrappers and/or siblings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants