I’m using summary/details html gadget for show a series of events.
Here is a simplified code (removed all rails/erb logic)
.eventscreen {
display: flex;
flex-direction: column;
width: 100%;
margin: 1em;
padding: 1em;
gap: 1em;
details {
justify-self: center;
table {
display: inline;
table-layout: auto;
width: 70%;
}
td {
border-right: 1px solid;
text-align: center;
}
}
summary {
font-style: italic;
}
details[open] {
padding: 0.5em;
}
details[open] summary {
border-bottom: 1px solid #733030;
margin-bottom: 0.5em;
}
}
<div class="eventscreen">
<details class="box">
<summary>
<table>
<tr>
<th>name</th>
<td>address</td>
<td>date</td>
</tr>
</table>
</summary>
<div>
descr
</div>
</details>
<details class="box">
<summary>
<table>
<tr>
<th>name</th>
<td>address</td>
<td>date</td>
</tr>
</table>
</summary>
<div>
descr
</div>
</details>
</div>
Also I want to replace the arrow with a PNG icon. I tried removing it with this, but it has no affect (in Chrome):
summary::-webkit-details-marker {display: none;}
2
In reality the marker is centered vertically to the element:
but the display
property is not correct. Changing it to inline-block
and setting vertical-align: middle
in the same selector will make the marker centered vertically:
.eventscreen {
& details {
table {
display: inline-block; /* changed from inline */
vertical-align: middle; /* added */
table-layout: auto;
width: 70%;
}
}
}
To hide the marker and replace it with an image you can do the following:
summary {
font-style: italic;
list-style: none;
}
summary::before {
content: '';
display: inline-block;
vertical-align: middle;
width: 1em;
height: 1em;
background: url(https://www.gravatar.com/avatar/b94f537e4af21b0458d60f69003c7d58?s=48&d=identicon&r=PG);
background-size: contain;
}
.eventscreen {
display: flex;
flex-direction: column;
width: 100%;
margin: 1em;
padding: 1em;
gap: 1em;
details {
justify-self: center;
table {
display: inline-block;
vertical-align: middle;
table-layout: auto;
width: 70%;
}
td {
border-right: 1px solid;
text-align: center;
}
}
summary {
font-style: italic;
list-style: none;
}
summary::before {
content: '';
display: inline-block;
vertical-align: middle;
width: 1em;
height: 1em;
background: url(https://www.gravatar.com/avatar/b94f537e4af21b0458d60f69003c7d58?s=48&d=identicon&r=PG);
background-size: contain;
}
details[open] {
padding: 0.5em;
}
details[open] summary {
border-bottom: 1px solid #733030;
margin-bottom: 0.5em;
}
}
<div class="eventscreen">
<details class="box">
<summary>
<table>
<tr>
<th>name</th>
<td>address</td>
<td>date</td>
</tr>
</table>
</summary>
<div>
descr
</div>
</details>
<details class="box">
<summary>
<table>
<tr>
<th>name</th>
<td>address</td>
<td>date</td>
</tr>
</table>
</summary>
<div>
descr
</div>
</details>
</div>
To center the arrow on the line, you can just give your tr element display:flex;
.eventscreen {
...
tr {
display: flex;
}td {
border-right: 1px solid;
text-align: center;
}}
}
To remove the details marker in Chrome you can set the list-style to none (your definition works for safari). Or use list-style-type to replace it with a custom character.
summary {
font-style: italic;
list-style: none;
/* or: list-style-type: "+"; */
}
If you want to replace the marker with an image, you can define a background-image for the summary.
1
- You current issue is related to
font-size
ofmarker
. To solve the issue, you can adjust themarker
size to center the arrow relative to the surrounding text content like the below.
.eventscreen {
display: flex;
flex-direction: column;
width: 100%;
margin: 1em;
padding: 1em;
gap: 1em;
details {
justify-self: center;
table {
display: inline;
table-layout: auto;
width: 70%;
}
td {
border-right: 1px solid;
text-align: center;
}
}
summary {
font-style: italic;
&::marker {
font-size: 1.5em;
}
}
details[open] {
padding: 0.5em;
}
details[open] summary {
border-bottom: 1px solid #733030;
margin-bottom: 0.5em;
}
}
<div class="eventscreen">
<details class="box">
<summary>
<table>
<tr>
<th>name</th>
<td>address</td>
<td>date</td>
</tr>
</table>
</summary>
<div>
descr
</div>
</details>
<details class="box">
<summary>
<table>
<tr>
<th>name</th>
<td>address</td>
<td>date</td>
</tr>
</table>
</summary>
<div>
descr
</div>
</details>
</div>
- You can remove the default marker and use a
png
file orbefore
instead of the marker.
.eventscreen {
display: flex;
flex-direction: column;
width: 100%;
margin: 1em;
padding: 1em;
gap: 1em;
details {
justify-self: center;
table {
display: inline;
table-layout: auto;
width: 70%;
}
td {
border-right: 1px solid;
text-align: center;
}
}
summary {
list-style: none;
display: flex;
align-items: center;
}
summary::before {
content: "▶";
margin-right: 0.5em;
transition: transform 0.3s ease;
font-style: normal;
}
details[open] {
padding: 0.5em;
}
details[open] summary::before {
content: "▼";
}
details[open] summary {
border-bottom: 1px solid #733030;
margin-bottom: 0.5em;
}
details[open] summary::before {
content: "▼";
}
}
<div class="eventscreen">
<details class="box">
<summary>
<table>
<tr>
<th>name</th>
<td>address</td>
<td>date</td>
</tr>
</table>
</summary>
<div>
descr
</div>
</details>
<details class="box">
<summary>
<table>
<tr>
<th>name</th>
<td>address</td>
<td>date</td>
</tr>
</table>
</summary>
<div>
descr
</div>
</details>
</div>
Note: To remove the default marker
, you can use list-style: none;
Markers and Issues
The arrow on <summary>
elements is a ::marker
pseudo-element, which generates for list-item
display properties. But working with markers is difficult for multiple reasons (non-exhaustive list):
- Markers aren’t fully styleable yet
- It is difficult to center in flow layout, which a
list-item
display property enforces; this is<summary>
‘s default and required for markers - Using images with markers is more difficult than with other elements
Alternative: Pseudo-Elements
Instead you should use ::before
pseudo-elements:
summary {
list-style-type: none;
}
summary::before {
/* Example: Black Right-Pointing Triangle */
content: "25b6";
}
<details>
<summary>
<table>
<tr>
<th>header cell</th>
<td>data cell</td>
</tr>
</table>
</summary>
<div>Description</div>
</details>
Not using ::marker
s means we aren’t limited to display property combinations with list-item
. For example we may now use display: flex
, which will make centering simpler:
summary {
display: flex;
/* No list-style-* properties needed without list-item */
}
summary::before {
content: "25b6";
}
<details>
<summary>
<table>
<tr>
<th>header cell</th>
<td>data cell</td>
</tr>
</table>
</summary>
<div>Description</div>
</details>
When using pseudo-elements like ::before
, you can use images with the content
or (my preference) background-image
property:
summary {
display: flex;
}
summary::before {
/* Example: 8x8 image */
background-image: url(https://picsum.photos/id/7/8/8);
content: ""; /* 'content' must still be specified! */
/* You may have to (or want to) specify sizes explicitly */
width: 8px;
height: 8px;
}
<details>
<summary>
<table>
<tr>
<th>header cell</th>
<td>data cell</td>
</tr>
</table>
</summary>
<div>Description</div>
</details>
As mentioned before, centering with flex layout is simple:
summary {
display: flex;
}
summary::before {
/* Set cross-axis (default: vertical) alignment to center */
align-self: center;
content: "";
width: 8px;
height: 8px;
background-image: url(https://picsum.photos/id/7/8/8);
}
<details>
<summary>
<table>
<tr>
<th>header cell</th>
<td>data cell</td>
</tr>
</table>
</summary>
<div>Description</div>
</details>
Note: You can use absolute positioning to simulate a list-style-position
of outside
.
Here, the advantage of flex layout over flow layout for <summary>
is, that its children (like <table>
) are layed out as specified by the parent, instead of combinations of the parent’s internal and the children’s outside display property.
Tables are meant to display tabular data. A “half” table is not useful, and cannot be properly done in HTML. A (full) table usually contains detailed data, which can be summarized. A more fitting markup would thus be as follows:
<details>
<summary>... (table summary)</summary>
<table><!--... (table data)--></table>
</details>
This allows people to judge by the summary whether they are interested in taking a more detailed look at your table, while others can skip the conveniently closeable element with ease.
Based on your comment, it may look as follows:
<details>
<summary>Events with location and date</summary>
<table>
<thead>
<tr>
<th>Name</th>
<th>Location</th>
<th>Date</th>
</tr>
</thead>
<tbody>
<tr>
<td>Game Awards 2024</td>
<td>Peacock Theater in L.A., CA, USA</td>
<td>December 12, 2024</td>
</tr>
<tr>
<td>Lights All Night 2024</td>
<td>Dallas Market Hall in Dallas, TX, USA</td>
<td>December 28-29, 2024</td>
</tr>
<tr>
<td colspan="3" style="text-align:center">...</td>
</tr>
</tbody>
</table>
</details>
Note: You may want to provide a better summary than my “events …” (unless your webpage provides sufficient context!).