"display: contents" is coming
Yes, display: contents
is enabled by default in Blink
and WebKit
and it will be probably shipped in Chrome 65 and Safari 11.1.
These browsers will join Firefox that is shipping it since version 37,
which makes Edge the only one missing the feature (you can vote for it!).
Regarding this I’d like to highlight that the work to support it in Chromium was started by Emilio Cobos during his Igalia Coding Experience that took place from fall 2016 to summer 2017.
You might (or not) remember a blog post from early 2016
where I was talking about the Igalia Coding Experience program and some ideas
of tasks to be done as part of the Web Platform team.
One of the them was display: contents
which is finally happening.
What is display: contents
? #
This new value for the display
property allows you to somehow remove
an element from the box tree but still keep its contents.
The proper definition from the spec:
The element itself does not generate any boxes, but its children and pseudo-elements still generate boxes and text runs as normal. For the purposes of box generation and layout, the element must be treated as if it had been replaced in the element tree by its contents (including both its source-document children and its pseudo-elements, such as
::before
and::after
pseudo-elements, which are generated before/after the element’s children as normal).
A simple example will help to understand it properly:
<div style="display: contents;
background: magenta; border: solid thick black; padding: 20px;
color: cyan; font: 30px/1 Monospace;">
<span style="background: black;">foobar</span>
</div>
display: contents
makes that the div
doesn’t generate any box,
so its background, border and padding are not renderer.
However the inherited properties like color
and font
have effect
on the child (span
element) as expected.
For this example, the final result would be something like:
<span style="background: black; color: cyan; font: 30px/1 Monospace;">foobar</span>
Unsupported
Actual
Supported
foobarIf you want more details Rachel Andrew has a nice blog post about this topic.
CSS Grid Layout & display: contents
#
As you could expect from a post from myself this is somehow related
to CSS Grid Layout. 😎
display: contents
can be used as a replacement of subgrids
(which are not supported by any browser at this point) in some use cases.
However subgrids are still needed for other scenarios.
The canonical example for Grid Layout auto-placement is a simple form like:
<style>
form { display: grid; }
label { grid-column: 1; }
input { grid-column: 2; }
button { grid-column: span 2; }
</style>
<form>
<label>Name</label><input />
<label>Mail</label><input />
<button>Send</button>
</form>
However this is not the typical HTML of a form, as you usually want to use a list inside, so people using screen readers will know how many fields they have to fill in your form beforehand. So the HTML looks more like this:
<form>
<ul>
<li><label>Name</label><input /></li>
<li><label>Mail</label><input /></li>
<li><button>Send</button></li>
</ul>
</form>
With display: contents
you’ll be able to have the same layout
than in the first case with a similar CSS:
ul { display: grid; }
li { display: contents; }
label { grid-column: 1; }
input { grid-column: 2; }
button { grid-column: span 2; }
So this is really nice, now when you convert your website to start using CSS Grid Layout, you would need less changes on your HTML and you won’t need to remove some HTML that is really useful, like the list in the previous example.
Chromium implementation #
As I said in the introduction, Firefox shipped display: contents
three years ago,
however Chromium didn’t have any implementation for it.
Igalia as CSS Grid Layout implementor was interested in having support
for the feature as it’s a handy solution for several Grid Layout use cases.
The proposal for the Igalia Coding Experience was
the implementation of display: contents
on Blink
as the main task.
Emilio did an awesome job and managed to implement most of it,
reporting issues to CSS Working Group and other browsers as needed,
and writing tests for the web-platform-tests
repository
to ensure interoperability between the implementations.
Once the Coding Experience was over there were still
a few missing things to be able to enable display: contents
by default.
Rune Lillesveen (Google and previously Opera)
who was helping during the whole process with the reviews,
finished the work and shipped it past week.
WebKit implementation #
WebKit already had an initial support for display: contents
that was only used internally by Shadow DOM implementation
and not exposed to the end users, neither supported by the rest of the code.
We reactivated the work there too, he didn’t have time to finish the whole thing but later Antti Koivisto (Apple) completed the work and enabled it by default on trunk by November 2017.
Conclusions #
Igalia is one of the top external contributors
on the open web platform projects.
This put us on a position that allows us to implement new features
in the different open source projects, thanks to our community involvement
and internal knowledge after several years of experience on the field.
Regarding display: contents
implementation,
this feature probably wouldn’t be available today in Chromium and WebKit
without Igalia’s support, in this particular case through a Coding Experience.
We’re really happy about the results of the Coding Experience and we’re looking forward to repeat the success story in the future.
Of course, all the merit goes to Emilio, who is an impressive engineer and did a great job during the Coding Experience. As part of this process he got committer privileges in both Chromium and WebKit projects. Kudos!
Last, but not least, thanks to Antti and Rune for finishing the work
and making display: contents
available to WebKit and Chromium users.