Re: [cssom][css-display][css-cascade] revisiting "default display"

Mike Sherov
Chief Technologist
SNAP Interactive, Inc. | Ticker: STVI
http://snap-interactive.com | http://ayi.com

On Sep 6, 2013, at 8:14 PM, "Tab Atkins Jr." <jackalmage@gmail.com> wrote:

> On Fri, Sep 6, 2013 at 4:41 PM, Mike Sherov <mike.sherov@gmail.com> wrote:
>> On Fri, Sep 6, 2013 at 3:08 PM, Tab Atkins Jr. <jackalmage@gmail.com> wrote:
>>> Getting the initial value *kinda*
>>> helps *today*,
>>
>> I'm not talking about "initial value",
>
> Apologies, I was using words imprecisely.  I'm also talking about
> "default value" - it would be pretty silly of me to be discussing the
> use-cases for "initial value" when we already have a keyword that does
> exactly that.
>
>>> because most people still use either display:block or
>>> display:inline for everything, but that's it.  As flexbox and grid
>>> become more popular, elements will commonly be intended to use those
>>> displays, and then the "default value" is worthless.
>>
>> I don't think so. I'm talking about "default value" which is different than
>> "intended" value. I'm not sure why you think any author would expect calling
>> .show() on a hidden div to result in grid or flexbox? Authors expect calling
>> .show() on a div results in display:block. I know because they reported bugs
>> on this when it doesn't do this right.
>
> Think about what I'm saying again.  Yes, *today*, calling .show on a
> <div> means I probably want it to be display:block, *because that's
> the most reasonable display value for a <div> in today's technology*.
> Sure, occasionally you'll use a <div> for inline-block or table, but
> that's rare.
>
> *Tomorrow*, that will no longer be the case.  Flexbox and grid, when
> they penetrate sufficiently to be generally reliable, will hit *hard*
> and wide.  They'll be used *constantly*, for all sorts of things,
> *particularly* JS-using apps, and any "significant" container in the
> page (which is the sort of thing I expect .show() to usually be called
> on). Making .show() default to "block" when it can't figure anything
> else out might still be what you have to do, but only because there's
> nothing else you *can* do, because you can't figure out the right
> display value without understanding the page as only a human can.
> Finding a default value for .show() will be something you do for minor
> convenience, not something that's actually good and useful a majority
> of the time.
>
> Thus, I'm perfectly okay with it remaining slightly annoying to figure
> out the default value of display, at least given only this use-case.

Sure, that's reasonable to say. Saying this use case isn't strong
enough to warrant "default value" is reasonable, and I can accept
that.

>
>>> I'm curious why jQuery uses an iframe hack.
>>
>> So we don't have to keep a large list of elements. It's smaller, code wise,
>> to do the hack and is future proof as you mention.
>
> I don't really understand - I'd suspect the code weight would be
> roughly the same, within tens of characters.  You literally just have
> an object-map with tagnames as keys and display values as values, and
> when someone calls .show() on an element, you feed its tagname through
> the object, defaulting to "inline" if it's not found.  Definitely
> higher performance and lower memory weight than creating a whole
> iframe (which presumably sticks around between calls), creating an
> inserting an element into it, then asking it for its computed style
> and checking 'display'.

Surprisingly, no. gzip is a cruel mistress ;) higher performance, sure.

>
> Its only downside, as mentioned, is that when HTML adds a new
> block-level element, the behavior will be wrong until someone fixes
> it, or an author manually adds the new tagname to the map.

There isn't a 1:1 mapping of tagname to default display. <input
type=hidden> for example.

>
>>> Is it just to be
>>> future-proof?  Just keeping around an array of default-block element
>>> names should be sufficient if you're not trying to be robust against
>>> future element additions (and if it's exposed, authors can just add to
>>> it in that case until jQuery updates).
>>
>> Requiring developers to have to add their element to a large array? It's
>> easier for them to fix the "div {display:none;}" declaration than to have to
>> manipulate an array (which presupposes they are serving their own copy of
>> jQuery). It's also easier for them to just do .css('display', 'block').
>
> I think you must have misunderstood my suggested simpler workaround -
> see above for the description.  This wouldn't involve someone actually
> modifying jQuery source code, just at run-time adding a key to an
> object hanging off of something.

Oh, duh. Right! Still, authors shouldn't have to know.

>
>> But
>> your suggestion presupposes they are aware of the issue. I'm trying to make
>> it something that devs don't ever have to even think about. jQuery already
>> provides them a solution so they don't have to think about this problem. I'm
>> just asking for the spec to provide this functionality in a declared API.
>>
>>> The only way to actually let an element be hidden by default and then
>>> show with the correct display type is for authors to use "box: none;"
>>> in the first place, rather than "display:none".
>>
>> I agree. Unfortunately, I'm a library developer, not an end author. I'm not
>> saying we shouldn't have box:none either, though. I agree we need it as
>> well, specifically for the use case of .hide(). It allows the library to
>> just apply "box:none;" and remove it on .show().
>
> You can continue using your existing iframe-based workaround or my
> suggested tagname-to-value workaround just fine; authors never have to
> think about it.

Yup, looks like we'll have to.

>
> The relevant question, as always, is not "how simple is it?", but
> rather "how useful is it?".  From what I can tell, it's slightly
> useful now, will decrease to only marginally useful in the near
> future, and in any case has easy workarounds.
>
>>> "display:none" is
>>> just a pernicious legacy mistake.
>>
>> Calling "display:none" "legacy" is about 5-10 years too early.
>> window.getDefaultComputedStyle() is a backwards compatible solution that
>> works today in Firefox and doesn't require any intervention from the author.
>
> I don't understand what you mean by "too early".  display:none was a
> mistake, full stop.  It's not a display type at all.  It's a
> conflation of layout management and box construction which is
> defensible from a theoretical standpoint, but not a practical one.
> We've known this for many years, but it hasn't been sufficiently
> important for anyone to fix yet.
>
>>> So I still don't think it's worthwhile to add back default values.  It
>>> simply doesn't help this use-case sufficiently to be worthwhile imo.
>>
>> But it does. I believe I've shown how it does, and how it sufficiently
>> addresses the problem. You haven't shown me how it doesn't solve the
>> problem, except mentioning that some people may expect a default to flexbox
>> or grid. I don't believe that's a good counterargument, but perhaps I've
>> missed something.
>
> You're attempting to argue that the value of a property after applying
> the UA stylesheet, but before applying author stylesheets, is a useful
> guess for the value the author intends anyway, which helps a function
> like .show() to function.  This relies on the assumption that authors
> don't usually change the value of a given property from the
> UA-supplied default - whenever they use a <div>, they keep it as
> display:block most of the time.  My argument was pointing out that no,
> the author will increasingly override the UA-provided default in the
> cases you're arguing for as we move into the future.

I apologize. I haven't explained .show() well. .show() accounts easily
for authors overwriting the default, just not for "none".

>
>> BTW, if you need another use case for this, it also solves the problem for
>> when someone tries to accidentally call .show() on an element that has
>> default "display:none", like a <input type=hidden>. You may think that's
>> non-sensical, but all an author has to do is $('form').children().show(),
>> and you're accidentally showing hidden inputs.
>
> This is why the idea maintains at least marginal value (it is indeed
> rare to change the 'display' value from the default on default-hidden
> elements), but again, either of the workarounds discussed in this
> thread so far are quite simple and handle this case well.

Sure, workarounds already work. And again, you're arguing that the use
case is not compelling enough. That's fine.
>
> Note, though, a case where this will fail - calling .show() on a <div
> hidden>, using solely the "default value" semantics", will keep it
> hidden.  You have to special-case this logic anyway for some elements.
>
> ~TJ

All in all, I'm fine if, given the fact that workarounds already work
for the provided use case, default value isn't deemed compelling
enough.

Is it compelling enough, however, for the box property to have a value
called "default" as a special case? That way anything that has
{display:none;} can be transformed to:
{display-outside:default;box:none;}?

Received on Saturday, 7 September 2013 01:03:31 UTC