This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 24574 - The choice over open="" seems counterintuitive.
Summary: The choice over open="" seems counterintuitive.
Status: RESOLVED WONTFIX
Alias: None
Product: WHATWG
Classification: Unclassified
Component: HTML (show other bugs)
Version: unspecified
Hardware: Other other
: P3 normal
Target Milestone: Unsorted
Assignee: Ian 'Hixie' Hickson
QA Contact: contributor
URL: http://www.whatwg.org/specs/web-apps/...
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-02-07 09:47 UTC by contributor
Modified: 2014-02-21 21:11 UTC (History)
3 users (show)

See Also:


Attachments

Description contributor 2014-02-07 09:47:20 UTC
Specification: http://www.whatwg.org/specs/web-apps/current-work/multipage/interactive-elements.html
Multipage: http://www.whatwg.org/C#the-details-element
Complete: http://www.whatwg.org/c#the-details-element
Referrer: http://www.whatwg.org/specs/web-apps/current-work/multipage/index.html

Comment:
The choice over @open seems counterintuitive.

Posted from: 84.220.197.15 by master.skywalker.88@gmail.com
User agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36
Comment 1 Andrea Rendine 2014-02-07 11:14:24 UTC
I was trying some CSS alternatives to standard HTML5-elements behavior for legacy browsers and I had some hard time on this one. In order to achieve the hiding effect with CSS, I thought about {display:none;} property. But for assigning it, one must either use:
 - the :not selector, in the form of details:not([open]). This is a CSS3 selector, and therefore not recognized by older user agents (i especially mean versions older than 9 of one specific desktop browser, of course...). This is useless because older versions don't recognize neither the effect nor the fallback.
 - a more complex selector. If I stick to the default behavior, I must state something like:
details>*{display:none;}
details>summary{display:block;}
This way, in order to show the content back I must define other rules. In order to reassign it correctly I can't simply state
details[open]>*{display:block;}
because even children of <details> could be either (default) inline elements or elements for which my stylesheet states other values for display. The new display state must repeat either previous statements in the stylesheet or the default value provided by user agents. It must be evaluated on a per-case basis so it can't be provided via reset stylesheet.
 - the alternative is grouping all the content of <details> after <summary> in a <div> and work on it. This implies that the stylesheet author has the control on markup or must rely on scripts (here this is unnecessary at all!).
In my opinion, the point in this problem is that the default state in this element is "closed", while the default behavior for html elements a display property whose value is different from "none". It is as if the default type for <input> were  "hidden", or as if visibility were defined through a @visible attribute rather than @hidden. Sounds strange.
Even if the spec is rather advanced in development, this element still isn't widespread according to the implementation status. I wonder if something in this attribute can still be changed to achieve the same result:
 * the first option would be substituting @open with a boolean attribute at the opposite, i.e. @closed, whose presence would mean that UAs must not display the content of <details> other than <summary>
 * otherwise, in order to keep @open, it could become an enumerated attribute with two possible states, "open" and "closed", while "open" is the default (I'd rather have used @state but if this can't be changed any more...).
One final note: if <details> contains a table of contents, a Wikipedia-style index or so on, it can be useful for normal users but even more useful for impaired users (e.g. those browse the page through a screen reader). Even if not esplicitly stated, the expression "If the attribute is absent, only the summary is to be shown" is to be read as "no user agents have to expose the content of <details> if not instructed to do so". The interface is already a problem for impaired users, maybe the default behavior should be friendlier towards them.
The fact is, whatever method is good as far as the "open" state is default. The rule in HTML content (not meta) elements, for what I know, is "display unless stated otherwise". Here this would become a golden rule to ensure backwards compatibility, general coherence and easy visual implementation.
Comment 2 Ian 'Hixie' Hickson 2014-02-07 17:47:33 UTC
This has shipped, so it's probably too late to consider changing it.
Comment 3 Andrea Rendine 2014-02-07 19:05:44 UTC
"probably too late" means "WHATWG is too polite to tell you that nobody will spend a second considering it any more" or "Well we have potentially missed something so it would be worth a second thought"? Because I really think that something is missing here.
Anyway, if there's a public discussion related to the choice of using the boolean @open, maybe I could see what I've missed. What were the reasons behind that attribute?
P.S. although the most recent versions of browsers implement <details> somehow, IE10 still doesn't. If you think it's worth thinking, here it's also about accessibility. Finally, what is the mechanism expected to be implemented by user agents to show/hide the <details> content?
Comment 4 Ian 'Hixie' Hickson 2014-02-07 22:10:53 UTC
"probably too late" means "please don't get your hopes up, to change it we'd need a _really_ compelling argument". (I haven't yet studied your comments above to see if they're compelling, hence the bug still being open.)
Comment 5 Ian 'Hixie' Hickson 2014-02-08 00:43:17 UTC
(In reply to Andrea Rendine from comment #1)
> I was trying some CSS alternatives to standard HTML5-elements behavior for
> legacy browsers and I had some hard time on this one.

If you want to support legacy browsers with <details>, the easiest way, I believe, is to put a <div> around the non-<summary> contents of the element, and style those, as follows:

  <details open>
    <summary onclick="fakeOpen(this.parentNode)">...</summary>
    <div>
      ...
    </div>
  </details>

  // CSS
  details, summary { display: block; }
  details > div { display: none; }
  details[open] > div { display: block; }

  // HTML
  function fakeOpen(node) {
    if (!('open' in node) {
      if (open.hasAttribute('open'))
        node.removeAttribute('open');
      else
        node.setAttribute('open');
    }
  }


>  - the alternative is grouping all the content of <details> after <summary>
> in a <div> and work on it. This implies that the stylesheet author has the
> control on markup or must rely on scripts (here this is unnecessary at all!).

Well, you can't really implement <details> without _some_ script.


> In my opinion, the point in this problem is that the default state in this
> element is "closed", while the default behavior for html elements a display
> property whose value is different from "none". It is as if the default type
> for <input> were  "hidden", or as if visibility were defined through a
> @visible attribute rather than @hidden. Sounds strange.

The most common case should be the case with no attributes specified, and the most common case for a disclosure widget is for it to not be disclosing the content. (Otherwise, why use it?) Hence why the default is closed, and open="" is required to override it.


> Even if the spec is rather advanced in development, this element still isn't
> widespread according to the implementation status.

It's widespread enough that we probably can't change it without a really compelling reason, at this point.


>  * the first option would be substituting @open with a boolean attribute at
> the opposite, i.e. @closed, whose presence would mean that UAs must not
> display the content of <details> other than <summary>

I don't see how this makes any difference to the legacy markup story.
It certainly makes using the element in the future harder, since you'd always have to remember to set the attribute.


>  * otherwise, in order to keep @open, it could become an enumerated
> attribute with two possible states, "open" and "closed", while "open" is the
> default (I'd rather have used @state but if this can't be changed any
> more...).

I can't work out why that would be an improvement at all. As far as legacy support is concerned, it would just make the required CSS or script more complicated, since you'd now have four cases to deal with, instead of two (the cases being attribute absent, attribute present with value open, attribute present with value closed, and attribute present with some other value, vs the current cases of just attribute present vs attribute absent).


> One final note: if <details> contains a table of contents, a Wikipedia-style
> index or so on, it can be useful for normal users but even more useful for
> impaired users (e.g. those browse the page through a screen reader). Even if
> not explicitly stated, the expression "If the attribute is absent, only the
> summary is to be shown" is to be read as "no user agents have to expose the
> content of <details> if not instructed to do so". The interface is already a
> problem for impaired users, maybe the default behavior should be friendlier
> towards them.

I'm not sure I follow. The point of this element is to hide content by default. I don't understand why it would be more of a problem for "impaired" users (impaired in what sense?). Having said that, nothing stops a UA from having a user interface control that expands all <details>, or indeed, that expands them all automatically, should that actually help users (I don't see how it could).


> The fact is, whatever method is good as far as the "open" state is default.
> The rule in HTML content (not meta) elements, for what I know, is "display
> unless stated otherwise".

No, the rule is "do the most commonly wanted thing by default".


> Here this would become a golden rule to ensure
> backwards compatibility,

I don't see how it impacts backwards compatibility one way or the other.


> general coherence

Not sure what you mean here.


> and easy visual implementation.

Not sure how it would impact implementations.
Comment 6 Andrea Rendine 2014-02-08 20:26:16 UTC
I catch the issue of the element support being quite implemented as of now, so asking to change it is hard to achieve. I won't request anything more about it, I just want to give you my answer just for completeness.
Using a <div> to wrap the non-summary content could be a pointless change in the markup. And if you had wanted a structure with a required sibling for <summary> you would have created it in that way (ideally, as a <dl><dt><dd></dl> structure: a definitory element and an explanatory element. Here it is not the case). Moreover, stylesheet designers can have limited control over the document structure. With an opposite choice (a @closed boolean attribute), a style could be applied to non-summary children of <details> having such an attribute, and everything would have been fine. In fact, for what I see in my browser is something "internally" implemented (let me know if I am wrong). They chose not to do it via default CSS stylesheet (of course).
With the fact of "scripts" i intended wrapping the content via script, sorry for the lack of detail. I don't like using scripts for changes in the DOM parent-child structure. Of course via script the attribute can be inserted for rendering process, and I admit that a boolean in this case is far better than an enumerated, also because it has no margin of error.
Generally speaking, in HTML5 the rule is "choose an element for what it means, not for what it does". So if I choose to put a <details> in my document I do it because I have some kind of details for the following section(s) AND I want to provide it in a disclosure widget, not because I want to hide its content by default. The spec itself says not to use it for footnotes, while if I had to choose only on the basis of the show/hide behavior I could do that. In addition to this, hiding a part of the explicit content in a document is merely presentational and could be achieved by any webdesigner thanks to CSS and a checkbox input without even using scripts. The most commonly wanted thing for a <details> should be to markup the details for a document and give the choiche whether to disclose it or not. Hiding it by default is a completely different issue and totally arbitrary.
Hence my consideration about backward compatibility. When a brand-new element is introduced, in my opinion it should be visible by default. Because usually elements are visible. The <menu>'s first purpose was to enable a context menu of some sort. But its default is the toolbar state (unless it's descendant of a menu in a popup state). For <details> (and for <dialog>, but that's another story) it had to be the same. With the addition of an attribute that could change the state if needed.
Finally. What I meant by talking about impaired users is mainly those who have to use screen readers. If the default state is "closed", this must be implemented via {display:none;} in a reset stylesheet, but this property makes the element disappear from any form of rendering, included audio. I don't know how many designers will think about it and implement a rule for aural user agents to always enable the reading of the details. And I don't know how a screen reader can enable the opening mechanism in order to make the content available for those users, who could greatly have an advantage from a table of contents or a brief about a long page (possible uses of <details>). Of course this can be said for the opposite case: if the status were defined by a @close, how to display the content of a <details@closed> element? 
But in that case all the behavior would have been governed by css. Now if I simulate the behavior with a reset css, I also do it for blind users and the element disappears without a mechanism to override this case.
I end here. I know I am verbose and I also know that I'm out of the group of people who oversee the changes of web language. But I believe that present-day HTML features should be transparent, devoid of presentational considerations, making a web page more like an XML document, where elements describe content, script acts and CSS renders, applying new rules whenever an element has to do special things.
Comment 7 Ian 'Hixie' Hickson 2014-02-10 21:57:30 UTC
> Using a <div> to wrap the non-summary content could be a pointless change in
> the markup.

Well, it's a semantically-neutral change, but it's not pointless — its point would be to enable styling a subpart of the element for legacy UAs, since CSS doesn't yet support a way to capture a subset of an element's children, nor to target text node children. (Even if it did, the legacy UAs don't support that so that would be moot.)


> And if you had wanted a structure with a required sibling for
> <summary> you would have created it in that way (ideally, as a
> <dl><dt><dd></dl> structure: a definitory element and an explanatory
> element. Here it is not the case).

It's not needed for modern UAs, or for the semantics. It's just a trick to enable the element to be used in down-level UAs.


> Moreover, stylesheet designers can have
> limited control over the document structure. With an opposite choice (a
> @closed boolean attribute), a style could be applied to non-summary children
> of <details> having such an attribute, and everything would have been fine.

If you show me the styles you would use with closed="", I can show you how to get the exact same effect with open="".


> In fact, for what I see in my browser is something "internally" implemented
> (let me know if I am wrong). They chose not to do it via default CSS
> stylesheet (of course).

Not sure what you mean here, but if you mean that <details> is implemented natively rather than purely via CSS, then yes, that's the idea. Things that can be done just using CSS don't need to be natively supported in the markup, by and large.


> With the fact of "scripts" i intended wrapping the content via script, sorry
> for the lack of detail.

Not sure what you mean here.


> Generally speaking, in HTML5—

(Note that we just call it "HTML" now, not "HTML5".)


> — the rule is "choose an element for what it means, not for what it does".

Specifically, elements should be used based on their semantics, not their presentation. The semantics of <details> are "a disclosure widget from which the user can obtain additional information or controls". The key here is "can obtain additional information", which implies that that information is, by default, not shown.


> So if I choose to put a <details> in my
> document I do it because I have some kind of details for the following
> section(s) AND I want to provide it in a disclosure widget, not because I
> want to hide its content by default.

All information on the Web is "details". The <details> element isn't for "details", it's for "a disclosure widget from which the user can obtain additional information or controls".


> The spec itself says not to use it for
> footnotes, while if I had to choose only on the basis of the show/hide
> behavior I could do that.

It's not appropriate for footnotes because it's flow content, not phrasing content, so you can't put it in the middle of a sentence.


> In addition to this, hiding a part of the explicit
> content in a document is merely presentational and could be achieved by any
> webdesigner thanks to CSS and a checkbox input without even using scripts.

That'd be a bit of a hack, but yeah, you could. This provides a cleaner solution.


> The most commonly wanted thing for a <details> should be to markup the
> details for a document and give the choice whether to disclose it or not.

It seems to support this.


> Hiding it by default is a completely different issue and totally arbitrary.

Well, most of this is arbitrary in some sense, sure. The thinking here is that there's no point having a disclosure widget if things usually start off pre-disclosed.


> Hence my consideration about backward compatibility. When a brand-new
> element is introduced, in my opinion it should be visible by default.

<details> is not alone amongst new elements in hiding its contents from new UAs. <video>, <audio>, <canvas>, <datalist>, <menu type=popup>, <progress>, <meter>, <template>, <dialog>... they all hide their contents by default.

In fact, hiding contents from new UAs but showing it to old UAs is a big part of how some of these elements expect to be used in the transition period.


> Because usually elements are visible. The <menu>'s first purpose was to
> enable a context menu of some sort.

<menu> originally was just about showing a list of options, like <ul>. The context menu feature is the new feature.


> But its default is the toolbar state
> (unless it's descendant of a menu in a popup state).

The toolbar state is the old state from HTML2 or earlier.


> For <details> (and for
> <dialog>, but that's another story) it had to be the same. With the addition
> of an attribute that could change the state if needed.

Why?


> Finally. What I meant by talking about impaired users is mainly those who
> have to use screen readers. If the default state is "closed", this must be
> implemented via {display:none;} in a reset stylesheet, but this property
> makes the element disappear from any form of rendering, included audio. I
> don't know how many designers will think about it and implement a rule for
> aural user agents to always enable the reading of the details.

Why would this be different for AT users and non-AT users?


> And I don't
> know how a screen reader can enable the opening mechanism in order to make
> the content available for those users, who could greatly have an advantage
> from a table of contents or a brief about a long page (possible uses of
> <details>).

Seems like it'd be the same as for non-AT keyboard users.


> Of course this can be said for the opposite case: if the status
> were defined by a @close, how to display the content of a <details@closed>
> element? 
> But in that case all the behavior would have been governed by css. Now if I
> simulate the behavior with a reset css, I also do it for blind users and the
> element disappears without a mechanism to override this case.

I don't understand how it would differ.
Comment 8 Andrea Rendine 2014-02-10 23:42:12 UTC
If elements are going to be natively supported at the point that CSS has no control over them, then I missed the point. And the discussion about default CSS is pointless, so it's not worth talking about how default CSS will handle this element in AT UAs. It's just a matter of excluding screen readers from reset stylesheet for some rules.
But I still suggest to give some CSS hints for these behaviors, relying upon user agents support is fun ...as far as user agents support! When they don't, well, it's still a matter of the frontend developer to make older UAs behave the same than newer ones.
Anyway I know how to achieve it with an auxiliary div:

details > div {display:none;}
details[open] > div {display:block}

Doing it without a "reverting rule" is impossible in legacy browsers without a div and in a generic manner so that it can be inserted in a reset stylesheet:

details:not([open]) > * {display:none;}

This was my idea if the boolean had been @closed

details[closed] > * {display:none;}

If it were done via stylesheet it could open with a transition rather than abruptly (I have no examples because I haven't studied the case yet, it's pointless). Maybe user agents find it difficult to implement natively the hiding behavior without CSS. I used to know that Safari supported <details> but the later version seems to ignore it (and display the content).
Anyway, I'll stick with the rules and see what I can do with it if I have occasion and I'll confront pro and cons. Thank you.
Comment 9 Ian 'Hixie' Hickson 2014-02-11 00:19:11 UTC
(In reply to Andrea Rendine from comment #8)
> If elements are going to be natively supported at the point that CSS has no
> control over them, then I missed the point.

CSS is still useful to style <details> and other form controls, it's just that the browser does stuff above and beyond what CSS can do. We're slowly working on addressing this (e.g. with Web Components).


> And the discussion about default
> CSS is pointless, so it's not worth talking about how default CSS will
> handle this element in AT UAs. It's just a matter of excluding screen
> readers from reset stylesheet for some rules.

I don't really understand how ATs are special here.


> But I still suggest to give some CSS hints for these behaviors, relying upon
> user agents support is fun ...as far as user agents support! When they
> don't, well, it's still a matter of the frontend developer to make older UAs
> behave the same than newer ones.

What do you mean by "these behaviours" here?


> Anyway I know how to achieve it with an auxiliary div:
> 
> details > div {display:none;}
> details[open] > div {display:block}
> 
> Doing it without a "reverting rule" is impossible in legacy browsers without
> a div and in a generic manner so that it can be inserted in a reset
> stylesheet:
> 
> details:not([open]) > * {display:none;}

I agree that without a <div> you can't make it work in legacy browsers, but that's because you can't target text nodes, mainly.


> This was my idea if the boolean had been @closed
> 
> details[closed] > * {display:none;}

You can do this with [open], too:

   details > * { display: none; }
   details[open] > * { display: block; }

Or, if you have a mixture of block, inline, etc, boxes (but no text) as children of the details, you can be more explicit, by listing those that are block, say:

   details > * { display: none; }
   details[open] > * { display: inline; }
   details[open] > p,
   details[open] > ol,
   details[open] > ul { display: block; }
   details[open] > table { display: table; }


> If it were done via stylesheet it could open with a transition rather than
> abruptly (I have no examples because I haven't studied the case yet, it's
> pointless).

Yeah, for elaborate things like transitions on opening/closing you really need something like Web Components.

(But that's true regardless of whether we use open="" or closed="", so it's probably out of scope for this bug.)
Comment 10 Ian 'Hixie' Hickson 2014-02-21 21:11:05 UTC
Please reopen if the arguments above are not sufficiently compelling.