Can you explain the expected behavior of the ::before and ::after pseudo-elements when used with the <details> element?

I observed that the <details> element is rendered differently in Chrome and Firefox. Take a look at the code sample below.

According to the HTML Standard:

The first summary element child of the details element represents the summary or legend of the details. If there is no child summary element, the user agent should provide its own legend (e.g. "Details").

The content of the details element after the summary represents additional information or controls.

The open attribute is a boolean attribute. When present, it indicates that both the summary and additional content are shown. If absent, only the summary is displayed.

As per CSS specifications outlined in the CSS Standard:

Pseudo elements like ::before and ::after generate boxes that appear as immediate children of their originating element, with content specified by the pseudo-element's 'content' property.

The ::before pseudo-element comes before the actual content of the element, while the ::after pseudo-element follows the actual content.

In Chrome and Chromium-based browsers, ::before and ::after are displayed respectively before and after the <summary>, regardless of the presence of the open attribute on the <details> element. It seems that <summary> is considered part of the details content, even if not explicitly defined but generated by the browser.

On Firefox, ::before and ::after appear after the <summary> and around the additional information when the open attribute is present. When the open attribute is absent, only the summary is shown. This behavior suggests that <summary> might not be included in the details content. This aligns with the behavior seen in <fieldset>, where ::before appears after <legend>. However, one would expect these pseudo-elements to always remain visible since the <details> element is still visible when closed.

What do you think should be the correct behavior?

details::before {
  content: "before";
  color: red;
}

details::after {
  content: "after";
  color: green;
}
<details>
  <summary>Closed details</summary>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
    Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
    Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
</details>
<details open>
  <summary>Open details</summary>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
    Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
    Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
</details>

Answer №1

After analyzing the quotes provided, it appears that Chromium may be breaching HTML requirements by showing content when details are closed, while Firefox may not be adhering to CSS rules with ::before being positioned incorrectly relative to the summary.

However, considering the rendering guidelines specified in the HTML specification for details/summary:

The details element should render as a block box and contain an internal shadow tree with two slots. The first slot is meant for the initial summary element child, if present, while the second slot is for the rest of the details element's descendants.

With only two slots available, one designated for the summary element, any additional content, including pseudo-elements like ::before and ::after, would naturally fall into the remaining slot. This design aligns more closely with Firefox's behavior based on this description.


Update: It has come to light that the previous assessment was inaccurate, according to Chrome developers - Refer to the bug report for details.

Evidently, pseudo-elements do not play a role in the slotting process, likely due to slotting being a DOM operation exclusively within a shadow DOM. Therefore, at the point of slotting, pseudo-elements generated through styling do not exist and cannot undergo slotting. They are later incorporated around the already slotted structure during the rendering phase, validating Chromium's approach.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Styling with CSS: Making a div's height fit within another div, including padding

Looking at the image, there seems to be a div with a width of 100% and no defined height. Instead, the height adjusts based on the content, with top and bottom padding in percentages. The issue arises when trying to place navigation buttons on the right si ...

Expanding iFrame width in Drupal 7

I'm grappling with how to create a full-width page in my Drupal 7 website. This specific page contains an embedded form. Initially, there were two blocks on the page that I removed in hopes of getting the iframe to expand to fill the space. The cur ...

Images are failing to show up in the iPhone design

Encountering issues with displaying images on an iPhone? You can replicate the problem by minimizing your browser window horizontally. Here is a link showcasing the problem: here. To temporarily fix this, try zooming out the browser (Ctrl+-). You can see a ...

Deciphering click event parameters in an AngularJS application

Currently, I am in the process of improving a feature in an existing application that has already been deployed. Unfortunately, all the JavaScript code is minified, and I only have access to the HTML files. I need to implement a function that triggers when ...

Navigating into iframe can be tricky when the previous iframe is not properly closed in Selenium Webdriver. Here

One issue we are facing is the excessive use of iframes in HTML. It has become troublesome to locate elements as some are buried within multiple layers of iframes. I'm trying to access an element inside the outermost iframe (the second one), but I&ap ...

Designing a drop-down menu that appears visually above its parent

As I design a menu positioned at the bottom using position:absolute; bottom:0, I want the submenu items to align perfectly above their parent. Each li should appear above the ul itself. The trick to achieving this is by applying a negative margin. However ...

Utilize PHP to include attachments and information within an email form

This is my PHP code In the HTML form below, I aim to retrieve data from the name, email, phone number fields, and file attachment. When attempting to get the attached file (without any other information entered) in a live server environment, I'm exp ...

Is it possible to decrease the size of a div by scrolling both vertically and horizontally?

Can a div's height and width both be reduced at the same time while scrolling down a page? Let's say that as the user scrolls, the size of the div changes from 400px by 400px to 200px by 200px, all while remaining centered on the page. I've ...

Retrieve the selected options from the checkbox and transfer them to the input text field

In the following example, I am attempting to extract all values of the inputs once they are checked and display them in a text input that will be sent via email. However, I am facing an issue where only the last option is being printed in that input instea ...

Bug with the button and text input feature in Firefox

I am facing a strange issue where the button and input have the same CSS (except for the background), but Firefox is displaying them differently. This problem does not occur in IE or Chrome. #searchInput { width: 80%; margin: 0 auto; display: ...

Establishing the primary language on a multi-language website

I am currently in the process of developing a website and I intend to offer support for both English and French languages. Up to this point, I've been following the primary solution outlined in this question: How to localize a simple HTML website pag ...

Could you assist me in setting up a loop for this Slideshow that times out and then resets back to the beginning?

Currently, I am in the process of developing a slideshow using jQuery. My main struggle lies in creating a loop that will timeout the slideshow for a specific duration, say 10 minutes, before it reappears and resumes indefinitely. Unfortunately, my attempt ...

Unable to access content in the mail body of Outlook webmail via mailto

I have successfully created a mailto URL for Outlook (web version), but now I am facing challenges with implementing it on the web version OWA. Here is the URL that I am struggling with: <a href='https://company.domain.com/owa/?ae=Item&a=New& ...

What are the top methods for interacting between Server APIs and Client-Side JavaScript?

Presently, I am utilizing setTimeout() to pause a for loop on a vast list in order to apply some styling to the page. For example, For example: How I utilize setTimeOut: I use setTimeout() to add images, text and css progress bars (Why doesn't Prog ...

Acquiring Twitter updates for a dynamic Bootstrap carousel display

I've been trying to load multiple tweets from the stream into the slideshow, but I can only get one to show up. I believe it has to do with the placement of the <div id="feed"> element, but I can't seem to figure out what I'm missing. ...

The scrolling content is positioned beneath the primary header and navigation bar

I'm currently in the process of designing a website where, upon clicking a navigation button, part of the page scrolls while the top header & nav bar remain fixed. Although I've managed to get the scrolling functionality to work and keep the top ...

Tackling the sticky header problem with in-browser anchoring and CSS dynamic height restrictions

I am experimenting with a unique combination of a Pure CSS in-page anchoring solution using scroll-behavior: smooth and scroll-margin-top settings, along with a sticky header for in-page navigation. By utilizing IntersectionObserver, I can identify when t ...

I am trying to verify my code, but the messages are not displaying under the username. They only appear under the password field. I am not sure where I have made a mistake

Having trouble with my login form validation using jQuery. Can someone help me fix it? $(document).ready(function() { $("#form1").validate({ rules: { username: { required: true, minlength: 6 }, password: { ...

What is the best way to position an image beside a jquery dialog box?

Apologies for not finding a suitable topic to discuss. Is it possible to place an image next to a jQuery dialog, similar to the following example? If so, how can this be achieved? ...

Tips for preventing <v-layouts> from impacting one another

I'm currently working on a dynamic link box for a homepage website, which can be viewed at . Inside this link box, I have included a button that allows the creation of buttons that function as links. Interestingly, the layouts of both the options but ...