details element seems to ignore display flex or grid?

Viewed 1727

This seems quite bizarre to me. You can see that we have a simple details element which should by all rights run horizontal. But it does not. grid also seems to not work.

Why? I am not seeing anything in the spec about the layout model being any different for these elements.

details {
 display: flex;
 flex-direction: row;
}
<details open>
 <summary>foo</summary>
 <div>bar</div>
 <div>baz</div>
</details>

3 Answers

You cannot overide the display behavior of a details element, but if the idea is to get children on a single line , then you can use display or float on the children :

a few example to test through different browsers before use.

borders, colors and background added for visual testing purpose

details {clear:both;margin:2em;border:solid;color:red;}
details.flkid {overflow:auto;/* to deaal with floatting children*/}
summary {background:yellow;}
details > *{padding:0 1em;color:green}
details.flkid > *{float:left;}
details.ib > *{display:inline-block;}
details.tbcl > *{display:table-cell;}
/* and so on with inline-table,inline-flex,inline-grid */
<details class="flkid" open>
  <summary>foo</summary>
    <div>bar</div>
    <div>baz</div>
</details>
<details class="ib" open>
  <summary>foo</summary>
    <div>bar</div>
    <div>baz</div>
</details>
<details class="tbcl" open>
  <summary>foo</summary>
    <div>bar</div>
    <div>baz</div>
</details>

Disclaimer : the following snippets stands here only for the fun and should NOT be seen as a solution even if it seems to work in a few browsers :

div {
  display: grid;
  grid-template-columns: repeat(5, auto);
}

details {
  display: contents/* removed from the flow, so the grid div becomes the parent */
}

div {
  border: solid;
  margin: 2px
}

details[open]> :not(summary) {
  /* hide them from the flow except for summary */
  position: absolute;
  right: 100%;
}

div[class] {
  grid-row:  span 2;
}
<div>
  <details><!-- attribute open removed you can add it if you want it closed at first :( -->
    <summary>foo</summary>
    <div>bar</div>
    <div>baz</div>
    <div>bar</div>
    <div>baz</div>
    <div>bar</div>
    <div class>bazbazbazbazbazb</div>
    <div>bar</div>
    <div>baz</div>
    <div>bar</div>
    <div>baz</div>
    <div>bar</div>
    <div>baz</div>
  </details>
</div>

You can solve it by adding the solution below.

.flex {
  display: flex;
  flex-direction: row;
}

.flex>* {
  padding: 5px;
}
<details open>
  <summary>foo</summary>
  <div class="flex">
    <div>bar</div>
    <div>baz</div>
  </div>
</details>

Despite this question is quite old, I found some quite hacky workaround to place summary and dropdown content into one horizontal axis. The caveat is the width of <summary> element should be fixed, but in my case (<summary> is an iconic button that is 24px in width and height) it works perfectly. So you apply position: absolute to <summary> and adjust all the other things by paddings. My case below, maybe it helps someone.

/* .panel is my <details class="panel"> */
.panel { 
  position: fixed; /* just my case, may be relative or absolute */
  left: 0;
  top: 100px;
  padding: 34px 10px 10px 34px; /* top and left padding are 10px + <summary>'s size */
  background: #ddd;
}

.panel summary {
  margin: 0;
  padding: 0;
  width: 24px;
  height: 24px;
  cursor: pointer;
  position: absolute; /* this is the trick */
  left: 10px; /* imitate padding */
  top: 10px; /* imitate padding */
}

.panel summary::marker,
.panel summary::-webkit-details-marker {
  display: none;
  content: none; /* remove triangle (my case, it is button-like) */
}

.panel[open] {
  /* the 2nd part of the trick
   * remove button's size from top padding when details are open,
   * hence left padding remains the same.
   * so visually it looks like placed into one horizontal row
   * with details' dropdown content. 
   */
  padding-top: 10px;
}
Related