Home > OS >  'Display: contents' does not work with tree-structure pseudo-classes (:first-child,: last-
'Display: contents' does not work with tree-structure pseudo-classes (:first-child,: last-

Time:07-17

My question: is this intentional? I can't find any literature or conversation about it.

The selector spec says it's for inclusive siblings - https://www.w3.org/TR/selectors/#child-index - but doesn't display: contents in effect simulate the contents as belonging to the grandparent element?

Per docs, the element is entirely removed from the accessibility-tree, and a grandparent flex will treat the removed element's children as its own (thus as siblings to its own). However, tree-structure pseudo-classes, such as :last-child, do not recognize the children's adoption, and instead operate as if they were still children of the removed element.

I suppose this is because the element is not removed from the actual DOM tree, and the pseudo selectors only operate upon the concrete DOM?

My use case is along the lines of:

<Accordion>
  <form style={{ display: contents }}>
    <Accordion.Section />
    <Accordion.Section />
  <form>
  <Accordion.Section />
</Accordion>

... In which I was expecting the form would display its children into the Accordion and I could select the last child.

CodePudding user response:

OP Question:

but doesn't display: contents in effect simulate the contents as belonging to the grandparent element?

No, here's a quoted explanation from here

display: contents makes that the div doesn’t generate any box, so its background, border and padding are not rendered. However the inherited properties like color and font have effect on the child (span element) as expected.

Also good reading on display: contents:


The display property doesn't change how the DOM is rendered just style it, so a last-child it always be a last-child no matter the display you use (even using display: none)

As you can see in the snippet below the properties belonging to box-model don't get inherit by children when parent is display: contents

.section {
  margin: 10px
}

form {
  background: lightblue;
  border: 10px solid red;
  padding: 10px
}

.section:first-child {
  box-shadow: 0 0 0 5px green;
}

.section:last-child {
  box-shadow: 0 0 0 5px blue;
}
<Accordion>
  <form style="display: contents">
    <div >first child of form</div>
    <div >last child of form</div>
  </form>
  <div >first and last child of Accordion</div>
</Accordion>

<hr />

<Accordion>
  <form style="display: flex">
    <div >first child of form</div>
    <div >last child of form</div>
  </form>
  <div >first and last child of Accordion</div>
</Accordion>

<hr />

<Accordion>
  <form>
    <div >first child of form</div>
    <div >nth child 2 of form - even if last child is display:none</div>
    <div  style="display: none">last child of form</div>
  </form>
  <div >first and last child of Accordion</div>
</Accordion>

  • Related