RE: @import -- allow at any place in stylesheet.


[Marat Tanalin:]
> 
> 18.01.2012, 02:57, "Tab Atkins Jr." <jackalmage@gmail.com>:
> > On Tue, Jan 17, 2012 at 2:54 PM, Ambrose LI <ambrose.li@gmail.com>
> wrote:
> >
> >>  2012/1/17 Tab Atkins Jr. <jackalmage@gmail.com>:
> >>>  We only really care about the web, since the vast vast majority of
> >>>  pages using our tech are web pages.  Making choices that are bad
> >>> for
> >>>  the web but offer a minor benefit to non-web usage isn't a good
> >>>  tradeoff.
> >>  If we cared “only about the web” then we can throw a whole bunch of
> >>  W3C initiatives out of the window. As it is, CSS is now caring about
> >>  things that even some professional typesetting systems are unable to
> >>  currently do.
> >
> > Personally, I agree - we *should* throw out a whole bunch of W3C
> initiatives.
> >
> > That's irrelevant to my point, though - CSS, specifically, is designed
> > around the needs of the web.  (We do take on some responsibility for
> > print publishing via epub, Antenna House, Prince, etc., but we've made
> > decisions against them in favor of the web before.)
> 
> By the way, Windows 8 is expected to be deeply integrated with HTML/CSS
> used for creating whole interface of applications.
> 
Please leave Windows 8 out of this argument. Thank you :) 

While there are some perf benefits to the current design given current implementations, 
why would we force this at the top? I honestly hadn't thought much about it before but 
I'll give it a shot.

In terms of feature design, it is compatible with the import feature of many languages 
that require imports to be first (Java comes to mind). It thus at least aligns with the 
mental model and habits of many developers. Honoring the principle of least surprise is 
often helpful. As such Ambrose's point about this restriction making the language more 
complicated should maybe be qualified with: for whom? And even if lifting the restriction 
made the language harder, it's also possible it will result in apps that are much harder
to understand and work with. 

Requiring @import at the top means the rules of the importing stylesheet always
'win' over those of the imported one(s). (Yes, the imported stylesheet can abuse !important 
but that's the point: it has to take extra steps to try and have the last word). 
Thus one straightforward way to adapt an existing design is to import the current stylesheet 
and override the relevant rules in the importing stylesheet. Some sites and tools use this 
pattern for debugging i.e. the 'regular' stylesheet gets imported into a CSS file with a 
bunch of rules meant to show extra info using outlines and hover rules, hiding some elements
etc.

So @import really defines a dependency. The importing stylesheets depends on its imports 
because their rules cascade before its own; and the imported stylesheet(s) cannot depend 
on the rules of the importing stylesheet. (Not without doing awful things, at any rate) 
Once @import is allowed anywhere, this simple assumption no longer holds. 

If I can add an @import in the middle of my stylesheet then it can depend on what precedes
it in the importer i.e. not only can the 'caller' of @import depend on the imported .css but
the latter *can* also depend of the content of its importer. Enabling circular dependencies 
does not sound like a helpful developer feature. So if we have a main.css like this:

selector1 {
}
.
.
.
selector20 {
}

@import "helper.css";

selector21 {
}

Then helper.css can depend on any of the rules that come before it...and selector21 can depend
on a rule in helper.css. Now if a rule in helper.css extends/decorates selector20 (by defining 
a :hover version of it, say) then updating selector20 in main.css without updating the corresponding 
rule(s) in helper.css will cause bugs. 

Ideally, the developer will realize his mistake and fix helper.css accordingly. In the real world 
he's as likely to end up doing:

selector1 {
}

.
.
selector20-new {
}
@import "helper.css";
selector21 {
}
selector20-new:hover {
 /* this is the foobar rule from helper.css updated to work with selector20-new*/
}

(Claims that "this would never happen" will be met with overwhelming disbelief)

The end result being that: 
1. The helper.css import depends on what comes before it in the stylesheet
2. What comes after the import has a dependency on helper.css. 

So main.css depends on helper.css and the latter depends on main.css. It's not so 
obvious why one is better off having more cross-dependencies and increasing the risk 
of bugs on top of paying the cost of extra loads (CD, EPUB, intranet: @import will have
a non-zero cost).

So the challenge now is to come up with a scenario where the ability to produce this
kind of pattern is a good thing. Or, alternatively, a scenario where risking this mess 
all over web - and in Windows 8... - is worth the benefits it will produce somewhere,
maybe.

Ultimately, this demands real use-cases: not just made-up arbitrary samples just like
the one above, not ill-defined claims about what intranets, CDs or EPUBs might, maybe, 
want. We need real-world problems that can be *better* solved by enabling this. And then 
we'll be able to decide whether the benefits are worth the costs. Strenuous, repeated and 
unsubstantiated claims that web developers know best add very little to the discussion. 
(If only because there is no shortage of evidence that relatively few do).

Received on Wednesday, 18 January 2012 01:19:27 UTC