Rego’s Everyday Life

A blog about my work at Igalia.

"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

foobar

Actual

foobar

Supported

foobar
Unsupported vs actual (in your browser) vs supported output for the previous example

If 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>

A simple form formatted with CSS Grid Layout A simple form formatted with CSS Grid Layout

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.