Proposing ::contents pseudo-elementūū

Hi www-style,

I had an idea which I think it would be amazing if it were standardized. Currently lots of CSS layouts need non-semantic elements. With this proposal we could get rid of lots of them.

**Proposal**

All non-replaced elements would have a `::contents` pseudo-element. Alternatively, it could be named `::inner-wrapper` or something like that. (`::content` may be problematic because it might be confused with the old name of `::slotted`).

That pseudo-element would wrap all the contents inside the element, except contents generated by `::before` and `::after`.

By default there would be no difference compared to now because initially `::contents` would have `display: contents`.

**Example 1**: Overflow in table cells

Since `height` is treated as a minimum height and the effect of `max-height` on table cells is undefined, an usual way to let the content of a table cell overflow is taking it out-of-flow by using an inner wrapper element:

<td class="element">
  <div class="inner"></div>
</td>
.element {
  position: relative;
  height: /*...*/; width: /*...*/;
}
.inner {
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  overflow: auto;
}

With `::contents`, that non-semantic element wouldn't be needed:

<td class="element"></td>
.element {
  position: relative;
  height: /*...*/; width: /*...*/;
}
.cell::contents {
  display: block;
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  overflow: auto;
}

**Example 2**: Styling anonymous child elements.

Some layouts generate anonymous child elements in some cases. Those can't be selected and thus can't be styled.

For example, in flexbox, contiguous runs of text are wrapped in an anonymous flex item. Although some properties can be set to the container (e.g. the initial `align-self: auto` computes to parent’s `align-items`), others can't (e.g. `flex-grow`).

Currently the solution is avoiding the anonymous element by using a real one, which can be selected.

<div class="element">
  <div class="inner">Text text text</div>
</div>
.element { display: flex; }
.inner { /* some flex-item styles */ }

`::contents` would allow to style the anonymous child without altering the DOM.

<div class="element">Text text text</div>
.element { display: flex; }
.element::contents { display: block; /* some flex-item styles */ }

**Example 3**: Generating content before and after an element, but outside it:

Currently, this can be achieved by placing the element in a wrapper:

<div class="wrapper"><div class="element"></div></div>
.wrapper { display: contents; }
.wrapper::before { content: 'foobar'; }
.element { /* some styles */ }

With `::contents`:

<div class="element"></div>
.element { display: contents; }
.element::before { content: 'foobar'; }
.element::contents { display: block; /* some styles */ }


Do you think my idea makes sense? It may need some refinement, of course.

Oriol 		 	   		  

Received on Saturday, 10 October 2015 19:25:14 UTC