Compass sprite images across multiple style sheets - compass-sass

Is there a way to get compass to generate a sprite sheet from images across different style sheets?
The tutorial talks about generating sprites from a bunch of images in the folder and then using it in 1 style sheet. But to me, it seems counter intuitive to have to use the following in all my stylesheets that uses the sprite sheet:
#import "icon/*.png";
#include all-icon-sprites;
I would prefer to have different images set for each sprite sheet, and then some how mark them for sprite generation so that compass can collect them into a sprite and then update the css to reflect that.

Compass only generates one sprite per directory. That's good because it can be cached by browsers eliminating the need to fetch it if you use it on multiple pages. You can use that sprite over and over even selectively using Selector Control which is covered in the tutorial you referenced.
Imagine that in your image folder there are four icons:
images/icon/apple.png
images/icon/banana.png
images/icon/basketball.png
images/icon/football.png
In a stylesheet called fruits.sass, you import all the icons and only use the apple and banana icons.
#import "icon/*.png";
.fruits
.banana
+icon-sprite(banana)
.apple
+icon-sprite(apple)
In a stylesheet called sports.sass, you import all the icons and only use basketball and football icons.
#import "icon/*.png";
.sports
.football
+icon-sprite(football)
.basketball
+icon-sprite(basketball)
When you compile, one sprite named something like icon-sjargon1.png will be generated in images.
images/icon/apple.png
images/icon/banana.png
images/icon/basketball.png
images/icon/football.png
images/icon-sjargon1.png
Your generated fruits.css will look something like:
.icon-sprite,
.fruits .banana,
.fruits .apple { background: url('/images/icon-sjargon1.png') no-repeat; }
.fruits .banana { background-position: 0 -20px; }
.fruits .apple { background-position: 0 0; }
Your generated sports.css will look like:
.icon-sprite,
.sports .football,
.sports .basketball { background: url('/images/icon-sjargon1.png') no-repeat; }
.sports .football { background-position: 0 -60px; }
.sports .basketball { background-position: 0 -40px; }

You can also separate sprites putting images in separate folders.
For example:
#import "themeOne/*.png";
#include all-themeOne-sprites;
#import "themeTwo/*.png";
#include all-themeTwo-sprites;
This is useful when your site has many sections and a maybe specific section must have a different theme.
One last thing...
I'm not a fan of adding ALL the sprite images with #include all-themeOne-sprites;, I prefer to do so:
#import "themeOne/*.png";
.somebox .icon {
#include themeOne-sprite(anyIcon);
}
And if you want the .somebox .icon to be sized as the anyIcon image, you can add the true parameter after the icon name, like so:
.somebox .icon {
#include themeOne-sprite(anyIcon, true);
}
I hope it helps!

Related

Is there a better way to use SASS variables flexibly in media queries?

I've set up some variables in SASS as follows:
// fundamental layout variables
$raw-layout-var-1: 60px;
$raw-layout-var-2: 200px;
// calculated layout variables
$calc-layout-var-1: #{$raw-layout-var-1} + #{$raw-layout-var-2};
I am attempting to use these variables with media queries so I can do something like the following, and have the calculated variables and the rest of the stylesheet update when the relevant criteria are met. I would like to be able to override the fundamental or calculated variables as I need.
#media only screen and (min-height: 500px) {
$raw-layout-var-1: 120px;
#media only screen and (min-width: 500px) {
$raw-layout-var-2: 100px;
}
Currently I have a workaround where all updates to variables use the !global keyword to update them globally, but this results in a somewhat complex setup where the fundamental variables, calculated variables, and the main css sheet are placed in mixins, to be called in each individual media query:
#mixin reset-raw-vars() {
$raw-layout-var-1: 60px !global;
$raw-layout-var-2: 200px !global;
}
#mixin update-calc-vars() {
$calc-layout-var-1: #{$raw-layout-var-1} + #{$raw-layout-var-2} !global;
}
#mixin add-main() {
div {
width: $calc-layout-var-1;
height: $raw-layout-var-1;
}
}
#media only screen and (min-width: 500px) {
#include reset-raw-vars(); // resets the raw variables in case these were changed globally in a previous media query
// here you can change any fundamental variables you need
#include update-calc-vars(); // recalculates calculated variables
// here you can override how any calculated variables are made
#include add-main(); // update the rest of the stylesheet with new layout
}
Even worse, if I have a pair of media queries such as those shown in the second code block, I have to manually create a hybrid with both min-height and min-width in order to apply both sets of conditions. Clearly this isn't DRY and could get seriously out of control with even slightly complex responsive pages. I can see from Using Sass Variables with CSS3 Media Queries that SASS doesn't have this functionality - is there a better way than I've outlined above?

Iterate over theme-variable files in SCSS

I want to create different css-themes for a WordPress theme by using theme setup files. The setup (simplified) would be as following:
/themes/_theme1.scss
/themes/_theme2.scss
/components/_file1.scss
/components/_file2.scss
/theme.scss
The idea is to enable easy theming by adding a class to the body of the document like .theme-theme1 or .theme-theme2. In the files _theme#.scss I want to define variables like text colour, font sizes and so on. In _file#.scss the actual styles are defined.
My question now is, how to iterate over the theme setup files while filling up the files.scss.
Sample idea, Background colour:
body {
###foreach themefile###
&.theme# {
background-color: $background-color;
}
###/foreach###
}
I know how to do this with only one theme available in the resulting CSS file, but I want to make ALL themes available in the resulting CSS. Feel free to ask more details as I am not sure if I explain me right.
Is there a way to create this stylesheet via some kind of foreach loops through variables in theme files or does it have to be done with extra scss-rules per theme file?
This is somewhat possible using a combo of #import with a #mixin to generate the styles. This method should produce minimal repeated code.
Here's how we'll setup the files.
- scss
- themes
- _theme1.scss
- _theme2.scss
- _theme.scss
- styles.scss
The _ prefix on some of the files prevent them from being compiled into CSS to keep our build nice and clean. Now let's go through the contents of the files:
_theme1.scss
$theme-name: 'theme1';
$primary-color: red;
$primary-font-size: 24px;
_theme2.scss
$theme-name: 'theme2';
$primary-color: blue;
$primary-font-size: 12px;
This is an oversimplified example but should give the basic idea. Each theme file will contain only variables.
_theme.scss
#mixin themestyle() {
body.#{$theme-name} {
p {
color: $primary-color;
font-size: $primary-font-size;
}
.bordered {
border: 3px solid $primary-color;
}
}
}
The themestyle mixin will contain all the styles for each theme, using the variables from the /themes/_theme*.scss files. The body.#{$theme-name} will create a selector like body.theme1 or body.theme2, depending on the current value of the $theme-name variable.
In this demo I'm styling on a p tag but this could easily be extended to all elements/selectors for your site. The important thing to remember is all styles need to be inside the body.#{$theme-name} selector.
Now the final, and least DRY part. The styles.scss file will import each theme file then call the themestyle mixin to generate the styles for each theme.
styles.scss
#import 'themes/theme';
/* Theme 1 Styles */
#import 'themes/theme1';
#include themestyles();
/* Theme 2 Styles */
#import 'themes/theme2';
#include themestyles();
The repeated #import/#include is required because it's not possible to #import within a loop or mixin, or this could be optimized a bit more.
Once styles.scss is compiled the output will be:
/* Theme 1 Styles */
body.theme1 p {
color: red;
font-size: 24px; }
body.theme1 .bordered {
border: 3px solid red; }
/* Theme 2 Styles */
body.theme2 p {
color: blue;
font-size: 12px; }
body.theme2 .bordered {
border: 3px solid blue; }
These themes can now be implemented by adding a class to the body tag, like <body class="theme1"> or <body class="theme1">.
Here's a Cloud9 project showing the setup.

SASS code structure for media queries

I'm using SASS to create a responsive site. At the moment, my code is structured into a number of partials:
Some default colours and sizes
Overall Layout
Partial for each element
As a result of this organisation I'm finding that I'm ending up with the media queries being declared numerous times through the resulting CSS - it just feels messy. As a result I've been working with a few ideas to keep the current structure, but end up with a simpler resulting code.
My idea goes something like this:
A variable contains a list of the partials to #import
A variable contains a list of the media query sizes (always using min-width, therefore this list is nothing more than a string of numbers)
Each partial (_footer.scss, _header.scss) would then contain a #mixin titles something like - content-footer, content-header, etc
Those #mixin's would take a single variable relating to the media-query and output the appropriate code for that condition.
style.scss would #import each partial from the list,
then cycle through each media-size and partial respectively, calling the function and media size.
The above process would result in something like this being effected...
#import 'footer';
#import 'header';
#include content-footer(0);
#include content-header(0);
#include content-footer(320);
#include content-header(320);
#include content-footer(640);
#include content-header(640);
etc..
My question is this - how do I call the dynamically titled #mixin? Something like content-#{$partial} seems like it should work, but doesn't.
I suppose if this doesn't work, then I could re-import the partial each time, but this seems overkill...
#import 'footer';
#include content(0);
#import 'header';
#include content(0);
#import 'footer';
#include content(320);
#import 'header';
#include content(320);
#import 'footer';
#include content(640);
#import 'header';
#include content(640);
Personally I find comfort in declaring media queries at many places throughout the document. It feels object oriented and it's really easy to keep track of what's actually going on. I'm usually interested in editing one module in particular, not the entire layout, so it makes more sense to me.
I have a mixin that looks something like this:
$mq-small: 30em;
$mq-medium: 50em;
$mq-large: 70em;
#mixin mq($size) {
#if $size == small { #media only screen and (min-width: $mq-small) { #content; } }
#else if $size == medium { #media only screen and (min-width: $mq-medium) { #content; } }
#else if $size == large { #media only screen and (min-width: $mq-large) { #content; } }
}
Which allows me to write media queries like this:
.element {
// generic rules
#include mq(medium) {
// size-specific rules
}
}
Which creates this output:
.element {
// generic rules
}
#media only screen and (min-width: 50em) {
.element {
// size-specific rules
}
}
Then, when the project is ready to be deployed, I merge the media queries manually in the output CSS into one place to remove bloat.
It's not perfectly clean, but it's also not necessary and the workflow is awesome. Last I heard, this merging is supposed to happen automatically in future versions of SASS. Perhaps that's just a rumor, though, but it would be nice.

Can I avoid duplicated css with Zurb Foundation 4?

Im using ZF4 and I recently noted how big my css files are. On one page in particular I have 10 lines of sass, that uses the grid mixins, so I "optimized" my imports, and got to this
#import "settings";
#import "foundation/components/global"; // *always required
#import "foundation/components/grid";
.tag-list-filter {
#include grid-row('nest-collapse');
.sub-nav {
#include grid-column(6);
margin: 0;
}
.date-in-filter {
#include grid-column(4,true);
label {
display: inline;
}
input[type="text"] {
display: inline;
width: 50%;
}
}
}
The two imports gives me an overhead of 700 lines of CSS!!!. And Im more than glad to add those 700 lines in my app.css, given that I have lots of pages that uses the grid system, but why should I have that much duplicated css in all my pages?
Is there a way I can avoid that?
#Cimmanon advice was right, and adding this solved my problem:
#import "settings";
$include-html-grid-classes: false;
$include-html-classes: false;
$include-print-styles: false;
#import "foundation/components/global"; // *always required
#import "foundation/components/grid";
Every component probably haves it's own variable to control whether to print styles or not.
By the way, Zurbs documentation could use a "Performance tips" section and include this tip in it. And also the don't include foundation as a whole in each page.

Why is the gutter of my semantic.gs grid always zero?

I am using semantic.gs to create a grid for a webpage. I noticed that whatever I do, I never have any "gutter", meaning in CSS the margin is calculated to 0, despite leaving the default to 20px.
So I took a step back and tried to reproduce this very simple official example:
http://semantic.gs/examples/fixed/fixed.html
The output of my attempt is here:
http://jsfiddle.net/QXpcq/
As you can see, again there is no gutter. The markup is the same, the output CSS is not. My output CSS always shows a margin of 0. You would think this is perhaps due to my input being different from the example, but as far as I can see, it's not. I'm using SCSS, as follow:
#import 'compass';
#import 'grid';
// Specify the number of columns and set column and gutter widths
$columns: 12;
$column-width: 60;
$gutter-width: 20;
// Uncomment the definition below for a percentage-based layout
// $total-width: 100%;
////////////
// LAYOUT //
////////////
// center the contents
div.center {
width: 960px;
margin: 0 auto;
overflow: hidden;
}
// header
header#top {
#include column(12);
margin-bottom: 1em;
}
// main and sidebar
#maincolumn {
#include column(9);
}
#sidebar {
#include column(3);
}
I have snipped the reset CSS code and the CSS that styles the colors and such in the demo. Trust me, they are an exact copy and paste of the official demo as you can see in the fiddle.
The "grid" import is the official download of the grid mixins. I didn't change it. The big mystery here is why with the same markup and SCSS I get different results?
Could it be due to my compilation process? I'm using the Scout app to monitor my SCSS folder. It picks up any change to it and compiles it to CSS.

Resources