-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
optimize IE-specific rules by placing them into an IE specific sheet? #664
Comments
Very good idea. However, this may be Sass' job to do this since it's the CSS authoring tool on top of which Compass was built. |
I've had this idea in a number of forms over the past 3 years. I always end up coming back to the fact that having a 1-1 correspondance between input files and output files is an incredibly simple approach that makes it easy for users to reason about how compilation works, etc. But I see a world coming where sass will have to have vendor/feature specific output in order to take advantage of new CSS features, etc. So I think it's time to revisit this concept once again. Off the cuff my idea for how to represent this in Sass would be to allow for arbitrary "targets" to be marked in sass: @mixin first-child {
@target not ie7 {
&::first-child {
@content;
}
}
@target ie7 {
&.first-child {
@content;
}
}
}
.foo {
@include first-child {
color: black;
}
} and then by default sass would generate an output file for each detected target and a CLI option to specify the target could be added. To support new compilation target with special compilation features (like support for variables or Looping in @nex3. |
When thinking about it, we can already output separate stylesheets (one for IE6, one for IE7, one for IE8…) with constants and Here is a quick example I just threw: // _grid.scss
$ie6: false !default;
$ie7: false !default;
@if $ie6 {
body {
text-align: center;
}
}
.column {
float: left;
@if $ie6 {
display: inline;
}
}
.clearfix {
// clearfix rules…
@if $ie7 {
zoom: 1;
}
}
// ie6.scss
$ie6: true;
@import 'grid';
// ie7.scss
$ie7: true;
@import 'grid';
// application.scss
@import 'grid'; Output: // ie6.css
body {
text-align: center;
}
.column {
float: left;
display: inline;
}
// ie7.css
.column {
float: left;
}
.clearfix {
zoom: 1;
}
// application.css
.column {
float: left;
} It's as easy as What do you think about this technique? |
I like your idea Chris, this is actually how I was picturing this in my mind. Keep the code inline and just define to what file you want to output the rules within the block. This would be a major feature that could help us developers work with Vendor features. Also |
I'm with @kaelig on this one: it seems like |
@nex3 no, it's not possible. @kaelig is missing the point completely. What you can do right now with What |
If statements are enough if the compiler behavior is not customizable on a per-target basis, but if the compiler is going to have compilation modes to support new syntax improvements in CSS then I think it makes sense to expose that concept to the stylesheets an leave the mapping of syntax modes and stylesheet tweaks to frameworks like compass. If the goal is to emit a core stylesheet and a per-target auxiliary stylesheet then if statements are not enough. |
Also these huge if/else if blocks scream for a case statement at the very least. |
The correspondence between compiling to calc() and friends and specific browser targets is basically independent of whether we use I'm not sure why you'd want a core shared stylesheet and multiple more-specific stylesheets, as opposed to just having the more-specific stylesheets contain everything a given browser needs. |
The difference between if statements and a dedicated feature is that with if statements compass has to generate starter stylesheet that sets up the conventions and there would be no good way for compass to associate compiler options to stylesheets unless we want to expose option setting within sass files. With a dedicated feature, the targets in use could be deduced via inspection of the sass tree. |
Why can't compass just spin up multiple Sass compilers for the primary entry point, each with different initial variables set and different output locations? |
Seems strange. |
Off topic, but I've wondered before about the possibility of Sass automatically moving all @media rules so the screen sizes aren't declared over and over again. |
Been using the approach Kaelig mentions for some time now and am really pleased about it. Can even push it a bit with an $ie version and target "lower than" versions of explorer: // in _myinclude.scss
$ie: 9 !default;
selector {
@if $ie < 9 {
border: solid 2px #000;
}
@else { // for ie > 9, webkits, ff etc
// fancy CSS3 rules, shadows, radius etc
}
}
// in ie8.scss
$ie=8
@import "myinclude"
// in ie7.scss
$ie=7
@import "myinclude" |
The question here is not whether if statements can be made to work. The question is whether a dedicated feature provides a compelling enough user experience over if-statements to warrant it. |
@chriseppstein Your first response's sample code looks like it would be a pleasure to use. I'd loathe having to riddle my sass with if statements. With this feature, Compass's mixins could be updated to put vendor prefixed properties into their own browser targets. Developers would just need to tell Compass to create multiple css files for each target, maybe through some new configuration option. Their interfaces wouldn't deliver useless styles, and it would be a relatively easy upgrade. |
I should point out that Compass is already set up for this using if statements. Example |
If the primary difference between |
I'm not totally sure the argument is aesthetic only we are talking about 2 things here extending the compiler to have multiple output files for a given stylesheet and a new directive to tell the compiler which file to render the conditional css too. The major difference between |
@scottdavis There's no need to spin up multiple instances of the executable. All you need to do is have multiple entry-point files, each of which defines the variables for its particular compilation profile (e.g. I don't see why it would be more difficult to tell designers to use |
@nex3 my understanding is that Targets would need to be configured using sass options but i think the way im envisioning it has a cleaner use case then smelling up my stylesheets with @if statements all over the place. Being able to target specific areas that need adjusted in ie or print etc would save me tons of time hunting down the selectors and pasting them into the ie file when i start to work on ie bugs. Having this work the same way as How i envisioned target working .foo {
@include clearfix;
.bar {
background-color:red;
float:left;
@target ie {
background-color:blue;
}
}
}
// COMPILED
//screen
.foo {
overflow:hidden;
zoom:1;
}
.foo .bar {
background-color:red;
float:left;
}
//ie
.foo .bar {
background-color: blue;
} now using if's .foo {
@include clearfix;
.bar {
background-color:red;
float:left;
@if $ie {
background-color:blue;
}
}
}
// COMPILED
//screen
.foo {
overflow:hidden;
zoom:1;
}
.foo .bar {
background-color:red;
float:left;
}
//ie
.foo .bar {
background-color:red;
float:left;
background-color: blue;
} We should avoid the unnecessary repetition in the output |
Why can't the IE stylesheet include the same selectors as the normal stylesheet? Why not serve only screen.css to normal browsers and only screen-ie.css to IE? This will decrease both the number of HTTP requests IE needs to do and (slightly) the byte size of the output file. |
in theory, rendering full stylesheets or auxillary stylesheets could both be supported by As I've said before this feature boils down to two things:
In my mind, the Sass engine should have an option for enabling new features like: :targets => {
:moz => {:enable => {:any => :moz, :calc => :moz}},
:opera => {:enable => {:any => true, :calc => :o}}
} The engine would have an argument for |
Note: this is all predicated on the notion that there is some efficiency in having an Engine reused across multiple renders for different targets. If this turns out to be untrue, then there's probably no point in having |
The framework can also set up a convention for multiple renders using
This would require a much tighter binding of target names and specific browsers/versions than I'd want to put in core Sass. Even if we went with
This is doable with
Since we keep a global in-memory cache of parse trees, there wouldn't be a difference between re-using one engine or using multiples. |
You keep saying things can be done. I keep saying that's not the point and has never been disputed by me. The point is whether it's the best way for things to be done. Grepping for I don't see how Regarding the in-memory parse tree storage, it's not global by default, but it can be done by passing the cache_store option to the engine by compass -- we don't currently do that. Still it seems like these would only vary at the CSSize step, so all the results of both check_nesting passes and the perform step could be shared -- this would be some win compared to a new engine for each. |
The proposed |
So this is a optimization that might be out of scope, but as compass does minification already, perf seems to be within scope to some degree..
from @kangax's article on css performance ....
Thoughts on how this could be done?
The text was updated successfully, but these errors were encountered: