[feature request] More intelligent compression #116

Closed
rupert654 opened this Issue Jun 12, 2011 · 111 comments

Comments

Projects
None yet
@rupert654

It would be great if SASS output could be configured to more intelligently compress output. Here are some examples:

# Combine name-spaced selectors
# SASS                             # Preferred Output                 # Current Output
body {                             body{border:3px solid #ccc;}       body{border-width:3px;border-color:#ccc;border-style:solid;}
  border: {
    width: 3px;
    color: #ccc;
    style: solid
    }
}

# Combine multiple declarations
# SASS                             # Preferred Output                 # Current Output
body { border: solid #ccc; }       body{border:3px solid #ccc;}       body{border:solid #ccc;}
body { border-width: 3px; }                                           body{border-width:3px;}

# SASS                             # Preferred Output                 # Current Output
body { color: #ccc; }              body{color:#ccc;cursor:pointer;}   body{color:#ccc;}
body { cursor: pointer; }                                             body{cursor:pointer;}          

# Ignore overridden declarations
# SASS                             # Preferred Output                 # Current Output
body { border: 2px solid #400; }   body{border:3px solid #ccc;}       body{border:2px solid #400;}
body { border: 3px solid #ccc; }                                      body{border:3px solid #ccc;}

This would allow you to more expressively organise stylesheets and partials without sacrificing on output length. For example, you could have color, typography and layout partials which, when compiled, gave the same output as if they had been written all mixed together.

There maybe gotchas with doing this due to the cascading nature of stylesheets and this effectively changes the ordering of declarations. However, I can't immediately think of specifics and the first case at least does not seem to be problematic.

This should also only apply when the compressed output option has been set as the readability of stylesheets may be impacted. For example, in development, it might be useful for the output to indicate that the designer has intended to split declarations in a particular way.

@albeva

This comment has been minimized.

Show comment
Hide comment
@albeva

albeva Jun 13, 2011

I think this should be part of new option to enable / disable optimizations. Another opportunity for optimizations is coalescing common properties:

/* for example: */
.foo { width: 10px; height: 10px; color: red; }
.bar { width: 10px; height: 10px; color: yellow; }
/* would become: */
.foo, .bar { width:10px; height:10px; }
.foo { color: red; }
.bar { color: yellow }

This kind of optimization is not safe however and therefore users should be able to test and see what side effects if any appear.

albeva commented Jun 13, 2011

I think this should be part of new option to enable / disable optimizations. Another opportunity for optimizations is coalescing common properties:

/* for example: */
.foo { width: 10px; height: 10px; color: red; }
.bar { width: 10px; height: 10px; color: yellow; }
/* would become: */
.foo, .bar { width:10px; height:10px; }
.foo { color: red; }
.bar { color: yellow }

This kind of optimization is not safe however and therefore users should be able to test and see what side effects if any appear.

@Anahkiasen

This comment has been minimized.

Show comment
Hide comment

+1

@heygrady

This comment has been minimized.

Show comment
Hide comment
@heygrady

heygrady Apr 17, 2012

This may not be 100% related to this thread but I've seen every other marginally related ticket being closed and referred here.

Specifically for dealing with media queries it would be useful to use some sort of output buffering to stash some css rules for later inclusion. The issue is hinted at in the media queries blog article where trying to correct for media queries inline will result in a number of identical @media declarations that have different rules in them. Output buffering will solve this really well. Each buffer would be named and additive so each time it is invoked, more is appended to the end of it. Once a buffer is output it is flushed.

Buffering is a completely different usecase than a @mixin. Buffers would allow for the creation of a responsive grid plugin that expected specific buffers for specific @media blocks. Additionally it'd be useful for projects that want to create print styles using @print blocks. Currently the only way to manage this is to simply add your additional rules directly to the media queries which is effective but can make the code a little harder to track. Not having buffers also completely removes the capability of using canned media queries baked into a compass extension, making it harder to convert projects like 320 and up into SASS for easy re-use.

Here's a simple example:

.left-column {
  width: 300px; // for browsers that don't support media queries
  @buffer small-devices {
    & { width: 100%; }
  }
  @buffer medium-devices {
    & { width: 150px; }
  }
  @buffer large-devices {
    & { width: 300px; }
  }
}
.main-column {
  width: 660px; // for browsers that don't support media queries
  @buffer small-devices {
    & { width: 100%; }
  }
  @buffer medium-devices {
    & { width: 330px; }
  }
  @buffer large-devices {
    & { width: 660px; }
  }
}


@media only screen and (min-width: 0) {
  @output small-devices;
}
@media only screen and (min-width: 768px) {
  @output medium-devices;
}
@media only screen and (min-width: 992px) {
  @output large-devices;
}
  • buffers are output at the time that @output is called in the natural CSS order. So if you add to a buffer after it's been output, nothing happens.
  • you can easily add more to a buffer using the names.
  • it might be useful to clear a named buffer with something like @clean my-buffer;
  • I don't know if it's possible to use the & symbol in content blocks like in my example but it'd be really useful.
  • It would also be useful to use the bubbling feature similar to how @media works. Something like div { @buffer my-buffer { width: 100px; } width: 200px; }

This may not be 100% related to this thread but I've seen every other marginally related ticket being closed and referred here.

Specifically for dealing with media queries it would be useful to use some sort of output buffering to stash some css rules for later inclusion. The issue is hinted at in the media queries blog article where trying to correct for media queries inline will result in a number of identical @media declarations that have different rules in them. Output buffering will solve this really well. Each buffer would be named and additive so each time it is invoked, more is appended to the end of it. Once a buffer is output it is flushed.

Buffering is a completely different usecase than a @mixin. Buffers would allow for the creation of a responsive grid plugin that expected specific buffers for specific @media blocks. Additionally it'd be useful for projects that want to create print styles using @print blocks. Currently the only way to manage this is to simply add your additional rules directly to the media queries which is effective but can make the code a little harder to track. Not having buffers also completely removes the capability of using canned media queries baked into a compass extension, making it harder to convert projects like 320 and up into SASS for easy re-use.

Here's a simple example:

.left-column {
  width: 300px; // for browsers that don't support media queries
  @buffer small-devices {
    & { width: 100%; }
  }
  @buffer medium-devices {
    & { width: 150px; }
  }
  @buffer large-devices {
    & { width: 300px; }
  }
}
.main-column {
  width: 660px; // for browsers that don't support media queries
  @buffer small-devices {
    & { width: 100%; }
  }
  @buffer medium-devices {
    & { width: 330px; }
  }
  @buffer large-devices {
    & { width: 660px; }
  }
}


@media only screen and (min-width: 0) {
  @output small-devices;
}
@media only screen and (min-width: 768px) {
  @output medium-devices;
}
@media only screen and (min-width: 992px) {
  @output large-devices;
}
  • buffers are output at the time that @output is called in the natural CSS order. So if you add to a buffer after it's been output, nothing happens.
  • you can easily add more to a buffer using the names.
  • it might be useful to clear a named buffer with something like @clean my-buffer;
  • I don't know if it's possible to use the & symbol in content blocks like in my example but it'd be really useful.
  • It would also be useful to use the bubbling feature similar to how @media works. Something like div { @buffer my-buffer { width: 100px; } width: 200px; }
@Anahkiasen

This comment has been minimized.

Show comment
Hide comment
@Anahkiasen

Anahkiasen Apr 17, 2012

Didn't think about an output buffer approach for media queries but I gotta say it doesn't look bad.

Didn't think about an output buffer approach for media queries but I gotta say it doesn't look bad.

@JohanVandeplas

This comment has been minimized.

Show comment
Hide comment
@justnorris

This comment has been minimized.

Show comment
Hide comment
@justnorris

justnorris May 16, 2012

The buffer solution really looks good here...

The buffer solution really looks good here...

@hotmeteor

This comment has been minimized.

Show comment
Hide comment

+1

@behaba

This comment has been minimized.

Show comment
Hide comment
@behaba

behaba May 31, 2012

yeah +1 for the buffer !

behaba commented May 31, 2012

yeah +1 for the buffer !

@auchenberg

This comment has been minimized.

Show comment
Hide comment

+1

@cjcheshire

This comment has been minimized.

Show comment
Hide comment
@cjcheshire

cjcheshire Jun 14, 2012

  • 1 and + 1 for media query squishing!
  • 1 and + 1 for media query squishing!
@nathggns

This comment has been minimized.

Show comment
Hide comment
@nathggns

nathggns Jun 22, 2012

+1 for everything suggested!

+1 for everything suggested!

@ghost

This comment has been minimized.

Show comment
Hide comment
@ghost

ghost Jul 6, 2012

+1 for sure.

ghost commented Jul 6, 2012

+1 for sure.

@simmo

This comment has been minimized.

Show comment
Hide comment
@simmo

simmo Jul 24, 2012

+1 Great solution. Buffer would be a great feature.

simmo commented Jul 24, 2012

+1 Great solution. Buffer would be a great feature.

@joshrives

This comment has been minimized.

Show comment
Hide comment
@joshrives

joshrives Jul 26, 2012

+1 for not repeating "@media screen and" a thousand times in my live file

+1 for not repeating "@media screen and" a thousand times in my live file

@StanAngeloff

This comment has been minimized.

Show comment
Hide comment
@StanAngeloff

StanAngeloff Jul 29, 2012

I've been hacking on a @buffer support in Sass and progress can be seen on StanAngeloff/sass@nex3:master...StanAngeloff:feature/buffers The code is working at the moment, but lacks some features (see further down).

I plan on using this for my own projects, but if there is enough interest and the code is bug-free, I would be happy to submit a pull request for inclusion in core Sass.

The syntax I used is:

$device-size:  small;
$device-width: 640px;

body {
  color: white;
  @buffer #{$device-size}-screen {
    color: black;
  }
}

h1 {
  color: white;
  @buffer #{$device-size}-screen {
    color: black;

    .no-js & { color: red; }
  }
}

@media only screen and (max-width: #{$device-width}) {
  @flush #{$device-size}-screen;
}

Several features can be seen in action in the snippet above:

  • Rule bubbling
  • Interpolations
  • Parent selector (&) support
  • Converting between .scss <=> .sass using sass-convert

There is support for using @buffer within .sass files as well:

$device-size:  small
$device-width: 640px

body
  color: white
  #{$device-size}-screen ->
    color: black

h1
  color: white
  #{$device-size}-screen ->
    color: black

    .no-js &
      color: red

@media only screen and (max-width: #{$device-width})
  <- #{$device-size}-screen

What doesn't work / is missing

  • Error reporting and debugging has not been tested extensively
  • Buffer functions are not provided, e.g., buffer-exists(..) or buffer-empty(..)
  • This one is more for personal use -- ability to write buffers to files, i.e., generating media-specific files so main stylesheet can remain optimised for desktop screens

Try it out

  • Clone the repo

    $ git clone git://github.com/StanAngeloff/sass.git
  • Check out the feature/buffers branch

    $ cd sass
    $ git checkout feature/buffers
  • Build and install the gem

    $ gem build *.gemspec
    $ gem install --local *.gem

Feedback welcomed very much.

I've been hacking on a @buffer support in Sass and progress can be seen on StanAngeloff/sass@nex3:master...StanAngeloff:feature/buffers The code is working at the moment, but lacks some features (see further down).

I plan on using this for my own projects, but if there is enough interest and the code is bug-free, I would be happy to submit a pull request for inclusion in core Sass.

The syntax I used is:

$device-size:  small;
$device-width: 640px;

body {
  color: white;
  @buffer #{$device-size}-screen {
    color: black;
  }
}

h1 {
  color: white;
  @buffer #{$device-size}-screen {
    color: black;

    .no-js & { color: red; }
  }
}

@media only screen and (max-width: #{$device-width}) {
  @flush #{$device-size}-screen;
}

Several features can be seen in action in the snippet above:

  • Rule bubbling
  • Interpolations
  • Parent selector (&) support
  • Converting between .scss <=> .sass using sass-convert

There is support for using @buffer within .sass files as well:

$device-size:  small
$device-width: 640px

body
  color: white
  #{$device-size}-screen ->
    color: black

h1
  color: white
  #{$device-size}-screen ->
    color: black

    .no-js &
      color: red

@media only screen and (max-width: #{$device-width})
  <- #{$device-size}-screen

What doesn't work / is missing

  • Error reporting and debugging has not been tested extensively
  • Buffer functions are not provided, e.g., buffer-exists(..) or buffer-empty(..)
  • This one is more for personal use -- ability to write buffers to files, i.e., generating media-specific files so main stylesheet can remain optimised for desktop screens

Try it out

  • Clone the repo

    $ git clone git://github.com/StanAngeloff/sass.git
  • Check out the feature/buffers branch

    $ cd sass
    $ git checkout feature/buffers
  • Build and install the gem

    $ gem build *.gemspec
    $ gem install --local *.gem

Feedback welcomed very much.

@simmo

This comment has been minimized.

Show comment
Hide comment
@simmo

simmo Jul 30, 2012

@StanAngeloff Very interested by this, it would be great if this was implemented into Sass.

simmo commented Jul 30, 2012

@StanAngeloff Very interested by this, it would be great if this was implemented into Sass.

@GuillaumeSerrat

This comment has been minimized.

Show comment
Hide comment
@nathggns

This comment has been minimized.

Show comment
Hide comment
@nathggns

nathggns Jul 30, 2012

Does anyone have any reasoning for why this wouldn't be possible?

Does anyone have any reasoning for why this wouldn't be possible?

@battaglr

This comment has been minimized.

Show comment
Hide comment
@battaglr

battaglr Aug 7, 2012

+1. Media queries are fundamentals these days, so would be really handy a more efficient way to manage the output to group them. Could be the one suggested by @heygrady —great idea BTW—, or another one, but would be nice to see some changes in the current approach.

battaglr commented Aug 7, 2012

+1. Media queries are fundamentals these days, so would be really handy a more efficient way to manage the output to group them. Could be the one suggested by @heygrady —great idea BTW—, or another one, but would be nice to see some changes in the current approach.

@feross

This comment has been minimized.

Show comment
Hide comment

feross commented Aug 10, 2012

+1

@nex3

This comment has been minimized.

Show comment
Hide comment
@nex3

nex3 Aug 20, 2012

Contributor

@StanAngeloff Please open a separate pull request for your @buffer stuff so we can discuss it further. It's not directly related to this feature request.

Contributor

nex3 commented Aug 20, 2012

@StanAngeloff Please open a separate pull request for your @buffer stuff so we can discuss it further. It's not directly related to this feature request.

@battaglr

This comment has been minimized.

Show comment
Hide comment
@battaglr

battaglr Aug 20, 2012

@nex3 I think that @heygrady should open the separated pull request, since was his original idea and he probably can explain more in deep the matter. It's a really good idea the @buffer stuff. BTW: great work with the hacking @StanAngeloff.

@nex3 I think that @heygrady should open the separated pull request, since was his original idea and he probably can explain more in deep the matter. It's a really good idea the @buffer stuff. BTW: great work with the hacking @StanAngeloff.

@thepuzzlemaster

This comment has been minimized.

Show comment
Hide comment
@thepuzzlemaster

thepuzzlemaster Aug 20, 2012

+1. Would love to see something like this.

+1. Would love to see something like this.

@heygrady

This comment has been minimized.

Show comment
Hide comment
@heygrady

heygrady Aug 21, 2012

@ImBatta I didn't write any code, I was just offering an idea. I couldn't create a pull request without code. But thanks for thinking of me.

@ImBatta I didn't write any code, I was just offering an idea. I couldn't create a pull request without code. But thanks for thinking of me.

@battaglr

This comment has been minimized.

Show comment
Hide comment
@battaglr

battaglr Aug 21, 2012

@heygrady Oh, you're right, I kinda suck in some GitHub stuff yet; sorry for the misunderstood. Hope the @buffer thing end up implemented.

But coming back to the original feature request, I don't think it's a good idea. These kind of compilation will cause many headaches for sure. Anyway, if many people is interested, it could be an optional way to compile.

@heygrady Oh, you're right, I kinda suck in some GitHub stuff yet; sorry for the misunderstood. Hope the @buffer thing end up implemented.

But coming back to the original feature request, I don't think it's a good idea. These kind of compilation will cause many headaches for sure. Anyway, if many people is interested, it could be an optional way to compile.

@pathaksubash

This comment has been minimized.

Show comment
Hide comment

+1

@vieron

This comment has been minimized.

Show comment
Hide comment

vieron commented Sep 2, 2012

+1

@polymetis

This comment has been minimized.

Show comment
Hide comment

+1

@michaelseanbecker

This comment has been minimized.

Show comment
Hide comment
@aaronjensen

This comment has been minimized.

Show comment
Hide comment
@aaronjensen

aaronjensen Sep 21, 2012

@StanAngeloff +1, how close is this to a pull request? This belongs in sass in my unqualified opinion.

@StanAngeloff +1, how close is this to a pull request? This belongs in sass in my unqualified opinion.

@StanAngeloff

This comment has been minimized.

Show comment
Hide comment
@StanAngeloff

StanAngeloff Sep 21, 2012

@aaronjensen: I have actually used my fork for a while now (eat your own dog food-style) and I am not happy with buffers.

I am not 100% convinced they are the best way of tackling the issue with @-media queries. You can already use @-if statements to output different queries to different files for each breakpoint so you don't really need buffers for that. On the other hand, if you want everything in a single file, a simple script file can do that for you on each stylesheet update.

So there's not a lot more left for buffers to solve IMHO.

In terms of a pull request, there have been changes in Sass around variadic functions so a rebase would be difficult. Furthermore, tests are incomplete in my implementation and you can do silly things like flushing a buffer from within the buffer itself causing a recursion and eventually a stack overflow. A lot of the tests are already duplicates of existing ones so there must be a better way of doing things.

@aaronjensen: I have actually used my fork for a while now (eat your own dog food-style) and I am not happy with buffers.

I am not 100% convinced they are the best way of tackling the issue with @-media queries. You can already use @-if statements to output different queries to different files for each breakpoint so you don't really need buffers for that. On the other hand, if you want everything in a single file, a simple script file can do that for you on each stylesheet update.

So there's not a lot more left for buffers to solve IMHO.

In terms of a pull request, there have been changes in Sass around variadic functions so a rebase would be difficult. Furthermore, tests are incomplete in my implementation and you can do silly things like flushing a buffer from within the buffer itself causing a recursion and eventually a stack overflow. A lot of the tests are already duplicates of existing ones so there must be a better way of doing things.

@aaronjensen

This comment has been minimized.

Show comment
Hide comment
@aaronjensen

aaronjensen Sep 21, 2012

@StanAngeloff That's interesting to hear, I guess it makes sense. The only use case I could think of for it was media queries and combining them after the fact seems like it will work as long as you expect it and plan for it.

Thanks for the link to the script. Based of of that and a python version I found I just put together a sprockets processor that combines media queries: https://github.com/aaronjensen/sprockets-media_query_combiner

Maybe some will find it useful if all they want to do is merge media queries

@StanAngeloff That's interesting to hear, I guess it makes sense. The only use case I could think of for it was media queries and combining them after the fact seems like it will work as long as you expect it and plan for it.

Thanks for the link to the script. Based of of that and a python version I found I just put together a sprockets processor that combines media queries: https://github.com/aaronjensen/sprockets-media_query_combiner

Maybe some will find it useful if all they want to do is merge media queries

@jonascarlbaum

This comment has been minimized.

Show comment
Hide comment
@jonascarlbaum

jonascarlbaum Oct 5, 2012

I read through this thread, allthough pretty fast, so could have missed something, haven't read the source code either, so I'm just saying that these are my bare thoughts after trying out Thoughtbot:s fine bourbon-extension neat and being a bit irritated over the duplicated media queries produced.

However, I was thinking about a different solution than the ones discussed here — it would be to implement buffer/rendering in the compiler, by using hashes and tree structures to store(add/appending) the rules, and finally render them instead of the present instant rendering routine — that would result in clean non-duplicated media queries etc.

The only consideration that comes in mind is the rule order, keeping the order in each level (css-rules only comes in two levels — document level and media query level), that could be accomplished by adding a counter for each interpreted sass-rule, and using it as a sort-index value for the interpreted row (rule or comments etc.), so rendering would be in correct order, preserving order for rows (rules and comments) — even in media queries — roughly thinking...

The fine thing in this is that the programmer that is using sass doesn't have to think of advanced buffers and other things, the sass-compiler would just do it right all the time — resulting in happy sass using programmers... ;)

I read through this thread, allthough pretty fast, so could have missed something, haven't read the source code either, so I'm just saying that these are my bare thoughts after trying out Thoughtbot:s fine bourbon-extension neat and being a bit irritated over the duplicated media queries produced.

However, I was thinking about a different solution than the ones discussed here — it would be to implement buffer/rendering in the compiler, by using hashes and tree structures to store(add/appending) the rules, and finally render them instead of the present instant rendering routine — that would result in clean non-duplicated media queries etc.

The only consideration that comes in mind is the rule order, keeping the order in each level (css-rules only comes in two levels — document level and media query level), that could be accomplished by adding a counter for each interpreted sass-rule, and using it as a sort-index value for the interpreted row (rule or comments etc.), so rendering would be in correct order, preserving order for rows (rules and comments) — even in media queries — roughly thinking...

The fine thing in this is that the programmer that is using sass doesn't have to think of advanced buffers and other things, the sass-compiler would just do it right all the time — resulting in happy sass using programmers... ;)

@aaronjensen

This comment has been minimized.

Show comment
Hide comment
@aaronjensen

aaronjensen Oct 5, 2012

@jonascarlbaum I'm not entirely sure what you're describing, but I don't think there is a way to combine media queries and completely preserve the order of all rules if media queries are interleaved with non-media queries. Or am I missing something?

Did you see https://github.com/aaronjensen/sprockets-media_query_combiner ? It combines things without having to think about it. Of course it does put them all at the end of the css, so that changes the order.

@jonascarlbaum I'm not entirely sure what you're describing, but I don't think there is a way to combine media queries and completely preserve the order of all rules if media queries are interleaved with non-media queries. Or am I missing something?

Did you see https://github.com/aaronjensen/sprockets-media_query_combiner ? It combines things without having to think about it. Of course it does put them all at the end of the css, so that changes the order.

@subru77

This comment has been minimized.

Show comment
Hide comment

subru77 commented Oct 10, 2012

+1

@jonascarlbaum

This comment has been minimized.

Show comment
Hide comment
@jonascarlbaum

jonascarlbaum Oct 10, 2012

Thanks @aaronjensen, will check out
https://github.com/aaronjensen/sprockets-media_query_combiner - seems to
achieve what I want to... Sorry for being a bit unclear in my description,
media queries should always be at bottom, the rules with media queries
should appear in top-down order... I have no doubts about this will do it
the right way...

The only tiny thing I believe could go wrong is when combining media
queries this way is when they are defined with overlapping widths inside
other rules, as I remember that Less Framework 4 is defined, that uses
inheritance in the media queries (mobile landscape inherits the mobile
portrait rules). It would be hard to achieve an logical order of the media
queries, when using overlapping media queries inside other rules in sass.

But my thoughts about these combining overlapped width media query issues
is not a real life problem, it just addresses that some people might use
this inside-rule-media-query-syntax the wrong way ... I successfully used
sass and Less Framework 4 about a year ago, defining the media queries the
standard way in the bottom manually, and that is the sensible thing to do
in those cases...

Written on my iPhone

Thanks @aaronjensen, will check out
https://github.com/aaronjensen/sprockets-media_query_combiner - seems to
achieve what I want to... Sorry for being a bit unclear in my description,
media queries should always be at bottom, the rules with media queries
should appear in top-down order... I have no doubts about this will do it
the right way...

The only tiny thing I believe could go wrong is when combining media
queries this way is when they are defined with overlapping widths inside
other rules, as I remember that Less Framework 4 is defined, that uses
inheritance in the media queries (mobile landscape inherits the mobile
portrait rules). It would be hard to achieve an logical order of the media
queries, when using overlapping media queries inside other rules in sass.

But my thoughts about these combining overlapped width media query issues
is not a real life problem, it just addresses that some people might use
this inside-rule-media-query-syntax the wrong way ... I successfully used
sass and Less Framework 4 about a year ago, defining the media queries the
standard way in the bottom manually, and that is the sensible thing to do
in those cases...

Written on my iPhone

@heygrady

This comment has been minimized.

Show comment
Hide comment
@heygrady

heygrady Oct 10, 2012

I would caution that, for Sass to remain successful, answers like, "another tool can do it", should be reviewed carefully. Sass has an issue with how to implement media queries and, more importantly, how to manage them on a significantly complex application.

What are the chances of getting the @buffer work turned into a Sass or Compass plugin? That way it can be installed on top of Sass without having to run a patched version of Sass. I think that is driving down adoption and preventing people from trying out what you've built.

I'm willing to hear that @buffer is more cumbersome in practice than it first appears. It may not make anything easier to work with. However, I worry about relying on 3rd party tools to cover up for the shortcomings of Sass. I would say that a tool like Media-query-combiner is more of a workaround than a long-term solution. I also feel like @bufffer has a broader application that may not even be understood.

The current official-ish solution is not ideal, as you end up with many duplicated media query rules. While a tool like sprockets-media-query-combiner may do the trick, it presupposes that users are on a project that has Sprockets available. Sass has a much broader audience than just Ruby on Rails developers and that means a Sprockets-based solution doesn't actually solve the problem for many users.

I personally see it as an issue that Sass is still so tied to Ruby on Rails. I see a lot of Node.js developers using Less.js instead of Sass because it integrates better with their platform. In my company, we use Sass on all of our projects and we rarely work on Ruby-based projects. We never have Sprockets available, many of our projects are on .NET. We use Compass to manage our real-time Sass compilation and simply forgo server-side, cached compilation that libraries like Sprockets afford.

I've seen threads debating the finer details of Sass vs Less vs Syltus syntax and I tend to agree that Sass is the most full featured and makes the most sense. However, portability is becoming an issue. Projects like libsass are trying to fix that (although I don't know how Compass would work with libsass). Recommending solutions to core issues that rely on platform specific 3rd party solutions is, IMHO, a poor approach.

Perhaps adding the essence of the sprockets-media-query-combiner to Sass is a better approach.

I would caution that, for Sass to remain successful, answers like, "another tool can do it", should be reviewed carefully. Sass has an issue with how to implement media queries and, more importantly, how to manage them on a significantly complex application.

What are the chances of getting the @buffer work turned into a Sass or Compass plugin? That way it can be installed on top of Sass without having to run a patched version of Sass. I think that is driving down adoption and preventing people from trying out what you've built.

I'm willing to hear that @buffer is more cumbersome in practice than it first appears. It may not make anything easier to work with. However, I worry about relying on 3rd party tools to cover up for the shortcomings of Sass. I would say that a tool like Media-query-combiner is more of a workaround than a long-term solution. I also feel like @bufffer has a broader application that may not even be understood.

The current official-ish solution is not ideal, as you end up with many duplicated media query rules. While a tool like sprockets-media-query-combiner may do the trick, it presupposes that users are on a project that has Sprockets available. Sass has a much broader audience than just Ruby on Rails developers and that means a Sprockets-based solution doesn't actually solve the problem for many users.

I personally see it as an issue that Sass is still so tied to Ruby on Rails. I see a lot of Node.js developers using Less.js instead of Sass because it integrates better with their platform. In my company, we use Sass on all of our projects and we rarely work on Ruby-based projects. We never have Sprockets available, many of our projects are on .NET. We use Compass to manage our real-time Sass compilation and simply forgo server-side, cached compilation that libraries like Sprockets afford.

I've seen threads debating the finer details of Sass vs Less vs Syltus syntax and I tend to agree that Sass is the most full featured and makes the most sense. However, portability is becoming an issue. Projects like libsass are trying to fix that (although I don't know how Compass would work with libsass). Recommending solutions to core issues that rely on platform specific 3rd party solutions is, IMHO, a poor approach.

Perhaps adding the essence of the sprockets-media-query-combiner to Sass is a better approach.

@ghost

This comment has been minimized.

Show comment
Hide comment

ghost commented Jan 25, 2014

+1

@rickalee

This comment has been minimized.

Show comment
Hide comment
@rickalee

rickalee Feb 7, 2014

Love the buffer concept as a workaround but compiler could be smarter. +1

rickalee commented Feb 7, 2014

Love the buffer concept as a workaround but compiler could be smarter. +1

@apfelbox

This comment has been minimized.

Show comment
Hide comment
@apfelbox

apfelbox Mar 20, 2014

Contributor

A somehow related issue about better compression (or smarter @extend with placeholder selectors)

_inc.scss

%test { color: red; }

_imp#.scss (# = 1, 2, 3)

@import "inc";
.imp# { @extend %test; } // # = 1, 2, 3

main.scss

@import "imp1";
@import "imp2";
@import "imp3";

Which produces

.imp1, .imp2, .imp3 {
  color: red; }

.imp1, .imp2, .imp3 {
  color: red; }

.imp1, .imp2, .imp3 {
  color: red; }

I would have expected that placeholders are added only once, right before the place they are @extended for the first time.
I know, that technically the placeholder is duplicated, but I would have expected it to be unique in the project.

Contributor

apfelbox commented Mar 20, 2014

A somehow related issue about better compression (or smarter @extend with placeholder selectors)

_inc.scss

%test { color: red; }

_imp#.scss (# = 1, 2, 3)

@import "inc";
.imp# { @extend %test; } // # = 1, 2, 3

main.scss

@import "imp1";
@import "imp2";
@import "imp3";

Which produces

.imp1, .imp2, .imp3 {
  color: red; }

.imp1, .imp2, .imp3 {
  color: red; }

.imp1, .imp2, .imp3 {
  color: red; }

I would have expected that placeholders are added only once, right before the place they are @extended for the first time.
I know, that technically the placeholder is duplicated, but I would have expected it to be unique in the project.

@aaronjensen

This comment has been minimized.

Show comment
Hide comment
@aaronjensen

aaronjensen Mar 20, 2014

I know, that technically the placeholder is duplicated, but I would have expected it to be unique in the project.

different problem. You're looking for: https://github.com/chriseppstein/compass/tree/master/import-once

I know, that technically the placeholder is duplicated, but I would have expected it to be unique in the project.

different problem. You're looking for: https://github.com/chriseppstein/compass/tree/master/import-once

@rvinay88 rvinay88 referenced this issue in zurb/foundation-sites Mar 24, 2014

Closed

Media queries for reveal #4780

@maxshearer

This comment has been minimized.

Show comment
Hide comment

+1

@jaicab

This comment has been minimized.

Show comment
Hide comment
@jaicab

jaicab Apr 21, 2014

+1 for buffer, really nice and neat solution

jaicab commented Apr 21, 2014

+1 for buffer, really nice and neat solution

@makaiser

This comment has been minimized.

Show comment
Hide comment
@makaiser

makaiser Apr 24, 2014

+1 for buffer

+1 for buffer

@robwierzbowski

This comment has been minimized.

Show comment
Hide comment
@robwierzbowski

robwierzbowski May 15, 2014

Contributor

CSSO solves a lot of these problems and has a Ruby wrapper. It might be worth adding a dependency to get most of this issue for free.

Contributor

robwierzbowski commented May 15, 2014

CSSO solves a lot of these problems and has a Ruby wrapper. It might be worth adding a dependency to get most of this issue for free.

@jaydenseric

This comment has been minimized.

Show comment
Hide comment
@jaydenseric

jaydenseric May 23, 2014

I like @lunelson's idea of applying @buffer to mixins: #116 (comment).

It should group mixin @flush dumps by matching mixin arguments. For example:

@mixin breakpoint($width) {
    @media (min-width: $width) {
        @content;
    }
}
@buffer breakpoint(700px) {
    h1 {
        color: red;
    }
}
@buffer breakpoint(700px) {
    p {
        color: blue;
    }
}
@buffer breakpoint(900px) {
    p {
        color: purple;
    }
}
@flush breakpoint;

Should output:

@media (min-width: 700px) {
    h1 {
        color: red;
    }
    p {
        color: blue;
    }
}
@media (min-width: 900px) {
    p {
        color: purple;
    }
}

I like @lunelson's idea of applying @buffer to mixins: #116 (comment).

It should group mixin @flush dumps by matching mixin arguments. For example:

@mixin breakpoint($width) {
    @media (min-width: $width) {
        @content;
    }
}
@buffer breakpoint(700px) {
    h1 {
        color: red;
    }
}
@buffer breakpoint(700px) {
    p {
        color: blue;
    }
}
@buffer breakpoint(900px) {
    p {
        color: purple;
    }
}
@flush breakpoint;

Should output:

@media (min-width: 700px) {
    h1 {
        color: red;
    }
    p {
        color: blue;
    }
}
@media (min-width: 900px) {
    p {
        color: purple;
    }
}
@maranomynet

This comment has been minimized.

Show comment
Hide comment
@maranomynet

maranomynet Jun 10, 2014

+1 for @append

@append is a much cleaner, and more broadly applicable solution to the problem @buffer tries to solve.

(LESS has additive mixin declarations, which can be a real pain, but also proves incredibly powerful at times.)

+1 for @append

@append is a much cleaner, and more broadly applicable solution to the problem @buffer tries to solve.

(LESS has additive mixin declarations, which can be a real pain, but also proves incredibly powerful at times.)

@trabuccocampos

This comment has been minimized.

Show comment
Hide comment
@shankarcabus

This comment has been minimized.

Show comment
Hide comment
@shankarcabus

shankarcabus Nov 4, 2014

+1 to use the css-condense logic.

+1 to use the css-condense logic.

@apipkin

This comment has been minimized.

Show comment
Hide comment

apipkin commented Dec 11, 2014

👍

@kevinSuttle

This comment has been minimized.

Show comment
Hide comment
@kevinSuttle

kevinSuttle Dec 11, 2014

Late to the party, but to me, an extension to Sass based on @stoyan's CSSShrink would be fantastic for intelligent compression. I do understand the challenges there though. Not trivial at all. http://cssshrink.com/velocity/

Late to the party, but to me, an extension to Sass based on @stoyan's CSSShrink would be fantastic for intelligent compression. I do understand the challenges there though. Not trivial at all. http://cssshrink.com/velocity/

@tatemz tatemz referenced this issue in zurb/foundation-apps Feb 6, 2015

Closed

CSS Minification/Optimization #440

@esjosemartinez

This comment has been minimized.

Show comment
Hide comment

+1 for buffer

@Jakobud

This comment has been minimized.

Show comment
Hide comment
@Jakobud

Jakobud Mar 10, 2015

For anyone who is using gulp, just use https://www.npmjs.com/package/gulp-combine-media-queries

It will combine your media queries together for you after compilation is complete. Works perfectly.

Jakobud commented Mar 10, 2015

For anyone who is using gulp, just use https://www.npmjs.com/package/gulp-combine-media-queries

It will combine your media queries together for you after compilation is complete. Works perfectly.

@mariendries

This comment has been minimized.

Show comment
Hide comment
@mariendries

mariendries Jun 16, 2015

+1 for buffer

+1 for buffer

@webbower

This comment has been minimized.

Show comment
Hide comment
@webbower

webbower Jul 27, 2015

+1 for buffer. Being able to nest related CSS and then control where it gets output seems like a generally useful tool. Something like:

@buffer("label") {
  // SCSS code
}

@flush("label");

Then...

// Mobile First BABY!!
.box {
  margin: 20px 10px;

  @buffer("tablet") {
    margin-left: 20px;
    margin-right: 20px;
  }

  @buffer("desktop") {
    margin-top: 40px;
    margin-bottom: 40px;
  }
}

// elsewhere

@media (min-width: 600px) {
  @flush("tablet"); // Outputs .box overrides and anything else in "tablet" buffer
}

@media (min-width: 900px) {
  @flush("desktop"); // Outputs .box overrides and anything else in "desktop" buffer
}

+1 for buffer. Being able to nest related CSS and then control where it gets output seems like a generally useful tool. Something like:

@buffer("label") {
  // SCSS code
}

@flush("label");

Then...

// Mobile First BABY!!
.box {
  margin: 20px 10px;

  @buffer("tablet") {
    margin-left: 20px;
    margin-right: 20px;
  }

  @buffer("desktop") {
    margin-top: 40px;
    margin-bottom: 40px;
  }
}

// elsewhere

@media (min-width: 600px) {
  @flush("tablet"); // Outputs .box overrides and anything else in "tablet" buffer
}

@media (min-width: 900px) {
  @flush("desktop"); // Outputs .box overrides and anything else in "desktop" buffer
}
@juliankoehn

This comment has been minimized.

Show comment
Hide comment
@juliankoehn

juliankoehn Sep 27, 2015

+1 for buffer

+1 for buffer

@robsonsobral

This comment has been minimized.

Show comment
Hide comment
@robsonsobral

robsonsobral Oct 26, 2015

Hi!

I saw this discussion is really old, but I think there's something new to be considered: HTTP/2.

Soon, the good practice concerning requests will be "it depends". On HTTP/2 is better to split the CSS by media query and to reduce the file size. So, maybe it's better to keep every @media on its own file and to import or not on a screen widt basis; or we could @flush content buffered on another file... I don't know. I'm new to SASS. What I know is that the situation is changing from when this discussion began.

Thanks!

robsonsobral commented Oct 26, 2015

Hi!

I saw this discussion is really old, but I think there's something new to be considered: HTTP/2.

Soon, the good practice concerning requests will be "it depends". On HTTP/2 is better to split the CSS by media query and to reduce the file size. So, maybe it's better to keep every @media on its own file and to import or not on a screen widt basis; or we could @flush content buffered on another file... I don't know. I'm new to SASS. What I know is that the situation is changing from when this discussion began.

Thanks!

@musamamasood

This comment has been minimized.

Show comment
Hide comment

+1

@semisedlak

This comment has been minimized.

Show comment
Hide comment

+1

@matovas

This comment has been minimized.

Show comment
Hide comment
@matovas

matovas Jan 23, 2016

hi,
I wrote an article about the targeting of styles in Sass
http://www.matov.pro/blog/adaptivity-targeting-styles
it is realy now

matovas commented Jan 23, 2016

hi,
I wrote an article about the targeting of styles in Sass
http://www.matov.pro/blog/adaptivity-targeting-styles
it is realy now

@Falven

This comment has been minimized.

Show comment
Hide comment

Falven commented Apr 9, 2016

+1

@dswwsd

This comment has been minimized.

Show comment
Hide comment

dswwsd commented Jun 7, 2016

+1

@dmitry

This comment has been minimized.

Show comment
Hide comment
@dmitry

dmitry Jun 7, 2016

Please use emoji, instead of +1. Use comments for something really helpful for the issue.

dmitry commented Jun 7, 2016

Please use emoji, instead of +1. Use comments for something really helpful for the issue.

@Herokid

This comment has been minimized.

Show comment
Hide comment
@Herokid

Herokid Jun 7, 2016

Ok, sorry for that.

El 7/6/16 a las 12:10, Dmitry Polushkin escribió:

Please use emoji, instead of +1.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
#116 (comment), or
mute the thread
https://github.com/notifications/unsubscribe/ABPv4mkrDCIZf3Tni8KwSE3hvHq0tLe9ks5qJUOjgaJpZM4AAU9t.

David Saenz / david@herokidstudio.es mailto:david@herokidstudio.es /
www.herokidstudio.es http://www.herokidstudio.es / 93 320 90 90 ·
Pamplona 89, 3 · 08018 Barcelona

_Herokid Studio_™

Herokid commented Jun 7, 2016

Ok, sorry for that.

El 7/6/16 a las 12:10, Dmitry Polushkin escribió:

Please use emoji, instead of +1.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
#116 (comment), or
mute the thread
https://github.com/notifications/unsubscribe/ABPv4mkrDCIZf3Tni8KwSE3hvHq0tLe9ks5qJUOjgaJpZM4AAU9t.

David Saenz / david@herokidstudio.es mailto:david@herokidstudio.es /
www.herokidstudio.es http://www.herokidstudio.es / 93 320 90 90 ·
Pamplona 89, 3 · 08018 Barcelona

_Herokid Studio_™

@pwnsdx

This comment has been minimized.

Show comment
Hide comment

pwnsdx commented Nov 23, 2016

@nex3

This comment has been minimized.

Show comment
Hide comment
@nex3

nex3 Apr 4, 2018

Contributor

These optimizations are no longer planned. Sass does what it can to eliminate extra whitespace and choose the smallest possible representation for values, but it's primary focus is being the best preprocessing language it can be rather than the best CSS compressor. Other tools exist that are focused on maximal optimization, and those are a better place for features like this.

In addition:

  • Combining namespaced selectors requires a lot of knowledge about the semantics of specific CSS property names, which is against Sass's design policy. Baking that knowledge into the language increases the amount of effort we as maintainers have to put in to keeping on top of the latest CSS specifications, and makes Sass more brittle to future CSS changes.

  • Ignoring overridden declarations is not generally safe. It's possible to use overridden declarations intentionally to provide fallback styles for browsers that don't support recent features. As above, we don't want to have to keep Sass up-to-date with which properties may or may not be safe to eliminate.

Contributor

nex3 commented Apr 4, 2018

These optimizations are no longer planned. Sass does what it can to eliminate extra whitespace and choose the smallest possible representation for values, but it's primary focus is being the best preprocessing language it can be rather than the best CSS compressor. Other tools exist that are focused on maximal optimization, and those are a better place for features like this.

In addition:

  • Combining namespaced selectors requires a lot of knowledge about the semantics of specific CSS property names, which is against Sass's design policy. Baking that knowledge into the language increases the amount of effort we as maintainers have to put in to keeping on top of the latest CSS specifications, and makes Sass more brittle to future CSS changes.

  • Ignoring overridden declarations is not generally safe. It's possible to use overridden declarations intentionally to provide fallback styles for browsers that don't support recent features. As above, we don't want to have to keep Sass up-to-date with which properties may or may not be safe to eliminate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment