Skip to content

Loirooriol/css-contents

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 

Repository files navigation

CSS ::contents pseudo-element proposal

All non-replaced elements have a ::contents pseudo-element, which wraps all the contents inside the element, not including ::marker nor the contents generated by ::before and ::after, if any.

::contents pseudo-elements must act as if they were assigned display: contents via a rule in the UA origin. Therefore, they do not generate any boxes and are treated as if they had been replaced with their children. This must be possible to override via display, so they do generate boxes if desired.

Note This is consistent with slots in a shadow tree.

A ::contents pseudo-element can be styled exactly like any normal document-sourced element in the document tree.

When its display property does not compute to contents nor none, the pseudo-element generates boxes as if it was an immediate child of its originating element, and the actual contents of the originating element generate boxes as if they were immediate children of the pseudo-element.

When its display property computes to none, the pseudo-element and the actual contents of the originating element generate no boxes. ::marker, ::before and ::after pseudo-elements generate boxes as ausual, according to their display and content properties.

When attached to a replaced element, the ::contents pseudo-element has no effect.

Issue: What about "kinda-replaced" elements?

Example

The fictional tag sequence for this HTML fragment with the following rules

div::before { content: 'A'; }
div::contents { display: inline; }
div::after { content: 'C'; }
<div>B</div>

is:

<div>
  <div::before>A</div::before>
  <div::contents>B</div::contents>
  <div::after>C</div::after>
</div>

Example

Defining margins that only apply between flex-items (issue 592) can be easily done as follows:

.flex-container {
  overflow: hidden;
}
.flex-container::contents {
  display: flex;
  margin: -25px;
}
.flex-container > .flex-item {
  margin: 25px;
}

Example

The ::before and ::after pseudo-elements generate content inside an element. For example,

div { /* border, margin, ... */ }
div::before { content: 'A'; }
div::after { content: 'C'; }
Previous
<div>B</div>
Following

produces the following fictional tag sequence:

Previous
<div>
  <div::before>A</div::before>
  B
  <div::after>C</div::after>
</div>
Following

However, sometimes it is desirable to generate content outside the element. This can be accomplished by adding

div { display: contents; }
div::contents { display: block; /* border, margin, ... */ }

resulting in

Previous
<div::before>A</div::before>
<div::contents>B</div::contents>
<div::after>A</div::after>
Following

Inheritance and the ::contents Pseudo-element

A ::contents pseudo-element inherits from its originating element.

A child element or text node inherits inherited properties from the ::contents pseudo-element originated by the parent element.

For non-inherited properties, inheritance is directly from the parent element.

Note This is consistent with how ::first-line affects inheritance (issue 1097), but for ::contents there is no need to blacklist custom properties.

Issue: Alternatively, inheritance could be from ::contents for all properties, and assign all: inherit; unicode-bidi: inherit; display: contents to ::contents in UA origin.

Interaction with Selectors

The ::contents pseudo-element selector can be used to select the ::contents pseudo-element.

Other selectors are not affected. ::contents is inserted between an element and its children in the CSS element tree, but DOM-based relationships represented for example by the child combinator (>) remain unaltered.

The ::contents pseudo-element can be pseudo-classed by pseudo-classes that can pseudo-class ::before and ::after.

The ::contents pseudo-element does not define any internal structure.

Interaction with the CSS Generated Content Module

Issue: This section intends to explain the magic behind ::contents in terms of the content property. But Tab said that contents was not supposed to affect inheritance, and that it will probably be dropped anyways.

As a tree-abiding pseudo-element, the content property applies to ::contents.

  • normal

    For elements and ::contents pseudo-elements, this computes to contents.

    Issue: Should normal compute to none on ::contents pseudo-elements in case the computed value of the content property of the originating element does not include contents?

    For ::before and ::after pseudo-elements, this computes to none.

  • none

    On elements, this inhibits the creation of the ::contents pseudo-element, as if that pseudo-element had display: none.

    Note: Inhibiting the ::contents pseudo-element also prevents the actual contents of the element from being rendered, unless ::before or ::after include contents in the computed value of their content property.

    On ::contents pseudo-elements, this inhibits the actual children of the originating element from being rendered as children of this pseudo-element, as if the element was empty.

    Issue: Should content: none on ::contents completely inhibit it? This would be more consistent with other pseudo-elements, but less useful, because this would be equivalent to using content: none on the originating element.

    On other pseudo-elements, this inhibits the creation of the pseudo-element as if it had display: none.

  • <content-replacement>

    Makes the element or pseudo-element a replaced element, filled with the specified <image>. Its normal contents are suppressed and do not generate boxes, as if they had display: none.

    Note: Replaced elements do not have ::before, ::after or ::contents pseudo-elements; the content property replaces their entire contents.

  • <content-list>

    On elements, this replaces the ::contents pseudo-element with one or more anonymous inline boxes corresponding to the specified values, in the order specified. Unless contents appears in the <content-list>, the ::contents pseudo-element is suppressed and does not generate boxes, as if it had display: none.

    On pseudo-elements, this replaces the pseudo-element’s contents with one or more anonymous inline boxes corresponding to the specified values, in the order specified. Its normal contents are suppressed and do not generate boxes, as if they had display: none.

  • contents

    On elements, this allows the creation of the ::contents pseudo-element. It is useless to include contents twice in a single content property, because the second occurrence simply has no effect, as there can only be a single ::contents pseudo-element.

    On pseudo-elements, this makes the contents of the pseudo-element be the actual contents of the originating element. It is useless to include contents more than once in a single content property, or use contents in multiple pseudo-elements, because only the first occurrence has an effect, as the actual contents of the originating element cannot be duplicated.

    When used in multiple pseudo-elements, the first occurrence is searched in the following order:

    1. In the ::contents pseudo-element, but only if contents appears in the computed value of the content property of the originating element.
    2. In the ::before pseudo-element
    3. In the ::after pseudo-element

About

CSS ::contents pseudo-element proposal

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published