Sass - Create custom control directive (like #if or #for) - sass

I'm wondering whether Sass provides a way to create custom control directive which is the "#" command like #if or #for.
I want to make media query syntax looks simpler like:
#below 800px {
...
}
#above 480px {
...
}
Currenly I'm using mixin for this which make the code longer:
#mixin below($size) {
#media only screen and (max-width: $size) { #content; }
}
#include below(800px) {
...
}
So does Sass support this custom control? I can't seem to find solution online.
Note: I don't want to modify the source code.
Thanks

No. Sass does not allow you to create custom control directives. You would have to modify the Sass parser if you wish to do so or continue using mixins as you are currently already doing.

Related

SASS add ampersand to mixin output

I'm trying to use an Angular Material mixin with a custom scope. I want to generate my theme like this:
.material-green-theme.mat-mdc-<selector> {
// content
}
However my compiled CSS turns out to be this:
.material-green-theme .mat-mdc-<selector> {
// content
}
This is my code:
.material-green-theme {
#include mat.slide-toggle-color($green-theme);
}
I've tried adding #at-root among other things to make it connect however I can't get it work; nor can I modify the mixin since it's from the Angular Material package. Is there a way for me to somehow make this work?

Sass 3.5's new content-exists() function just doesn't work

After checking out the latest updates on the Sass Change Log, I got very exited about the new content exists function.
I'm using their own example, which doesn't work. And I've tried the following...
#mixin check-for-content {
#if content-exists() { background:green; }
#if not content-exists() { background:red; }
#content;
}
body {
background:blue;
#include check-for-content;
//#include check-for-content { test:block };
}
It doesn't matter if I pass parameters, add a block, don't add a block, add an empty block, etc... it always thinks content-exists() is true (and gives me a green background).
Am I missing something? Do I need to update anything else locally besides Sass?
If you use LibSass or NodeSass, then you can't use RubySass syntax.
Function content-exists() included the latest Sass 3.5.

SASS / Compass - Overwrite | Delete | Unset Mixins / Include

I'm trying to set up a mobile-first workflow with SASS and Compass.
Therefore I want to define for the navigation an ul>li horizontal-inline-list via http://compass-style.org/reference/compass/typography/lists/horizontal_list/
I included:
nav.mainnav ul {
#include horizontal-list(1rem);
}
Everything is working fine so far. But how can I get rid of this include when I'm targeting my breakpoint for larger screens?
#include breakpoint($large){
nav.mainnav ul {
// I want to delete the include here
}
}
Is there a simple way to do this or do I have to override the styles manually?
In this instance, mobile first is not your best option.
#media (max-width: 20em) { // whatever your desired breakpoint is
nav.mainnav ul {
#include horizontal-list(1rem);
}
}
Now you don't need to override the styles.

SASS Placeholder for media query?

I found this method to easily add #media block using mixin:
#mixin phone() {
#media only screen and (max-width: 480px) {
#content;
}
}
To use it, just simply type something like this:
p {
#include phone { ... }
span {
#include phone { ... }
}
}
But the problem lies in the real CSS output:
#media only screen and (max-width: 480px) {
p { ... }
}
#media only screen and (max-width: 480px) {
p span { ... }
}
It duplicates the #media ... part which will bloat the CSS.
Is there a way to make the mixin act like placeholder? So it will combine all #content and put it under the same #media ... block.
So the result will be like
#media only screen and (max-width: 480px) {
p { ... }
p span { ... }
}
I know I can just put the #include phone at the end of the file and write all the necessary styles in that block.
But writing the media-query style right besides the original one makes it easier to read and organize.
Thanks
Sass does not have that functionality at this time. Your only option is to manually group your styles within a single media query (or use a 3rd party CSS compressor that has that functionality).
https://github.com/nex3/sass/issues/116
You just have to adjust your nesting. Because the mixin will place all your content within the media-query, you only want to use the mixin once and place all relevant styles within it (to avoid multiple media-queries).
#include phone {
p {
span { ... }
}
}
If you are trying to combine styles for <p> and <span> for various media-queries, you will inevitably end up with some separation of styles, either in your preprocessed or output code.
For example:
p {
...
span { ... }
#include phone {
...
span { ... }
}
}
Hope that helps. Even if you end up with output that feels 'less efficient', it shouldn't actually slow down browser rendering, so I'd say prioritize writing code that feels maintainable to develop.
SASS can not combine extends with media queries**, so duplicate media queries are currently inevitable when you adopt this code style.
You could structure your code with media queries at the top level (i. e. group code by media queries), but this is generally a bad idea. Eric Meyer, one of the CSS gurus here, says (and many other front end enthusiasts would agree) that you should never do that. I have tried this approach myself on one project and i confirm that the larger your project gets, the more painful this code structure appears. SMACSS and other code structure methodologies also advise against it.
Where this code structure is widely used is in CMS base themes (theme templates aka starter kits). But they are aimed to allow users quickly override default styles rather than build from scratch.
The matter is that the duplicate media queries don't really matter. Though #cimmanon might not agree with me, only the readabiliy and maintainability of your source code (SASS) should matter, because every modern web server provides compression (gzip) for CSS code which is read only by machine.
Of course, there are many ways of ruining your CSS by making it unreasanably huge. Using a non-semantic CSS framework is one of them. Wisely applying a lot of local media query blocks is not.

Is it possible with compass to loop through a folder and generate css classes of the files within? [duplicate]

I'm using sass and compass and I am trying to create css classes for images matching a given pattern.
The intended/resulting css mostly looks like this:
.class1 { background-image: url(class1.png); }
.class2 { background-image: url(class2.png); }
While it might be possible to use the compass sprite functionality ( http://compass-style.org/help/tutorials/spriting/ ) it is inconvenient (as it will generate new files) in my case as the images are already spritesheets themselves.
So being able to do something like
#each $clazz in listFiles("images/*") {
.#{$clazz} {
background-image: url('#{$clazz}.png');
}
}
would be great.
Is there a more or less easy way to do so?
You can accomplish this by supplementing the builtin SASS/Compass functions with your own custom Ruby function. (See the section titled "Adding Custom Functions" in the SASS reference here.) Just define a Ruby file (say, "list-files.rb") with your custom code like so:
module Sass::Script::Functions
def listFiles(path)
return Sass::Script::List.new(
Dir.glob(path.value).map! { |x| Sass::Script::String.new(x) },
:comma
)
end
end
Then, you can include this file from your compass configuration file (say, "config.rb"):
require File.join(File.dirname(__FILE__), 'list-files.rb')
And access it in your SASS stylesheet just like you want to:
#each $clazz in listFiles("images/*") {
.#{$clazz} {
background-image: url('#{$clazz}.png');
}
}
You can then compile using compass compile -c config.rb, as normal.

Resources