- From: Tab Atkins Jr. <jackalmage@gmail.com>
- Date: Fri, 6 Sep 2013 17:14:37 -0700
- To: Mike Sherov <mike.sherov@gmail.com>
- Cc: "www-style@w3.org" <www-style@w3.org>
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. >> 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'. 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. >> 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. > 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. 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. > 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. 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
Received on Saturday, 7 September 2013 00:15:25 UTC