This question already has an answer here:
Customizing the output of Compass sprites
(1 answer)
Closed 7 years ago.
Now if we generate sprite image using compass
#import "imgs/*.png";
#include all-imgs-sprites;
we ill gate in our .css classes like this
.imgs-<imagename>
is it possible to delete "imgs" part? I need only .<imagename>
In that case don't use the magical all. It's not as convenient, but works fine. Just #import the sprite and #include the individual images in custom classes:
#import "imgs/*.png";
.circle {
#include imgs-sprite('circle');
}
.square {
#include imgs-sprite('square');
}
Make your life simpler by DRYing it up:
#each $file in circle, square {
.#{$file} {
#include imgs-sprite($file);
}
}
Related
This question already has answers here:
Sass - Manipulate inherited property?
(4 answers)
Closed 7 years ago.
I have the following mixin:
#mixin rhombus() {
#include transform(rotate(45deg));
}
and another one:
#mixin centerVertically() {
#include transform(transform(0, -50%));
position: absolute;
top: -50%
}
Now I would like to use them both on the same element and of course it will fail because the last called will be a winner.
There is a similar question for LESS but I could not find any solution for SASS.
Don't stick to the code above, this is just an example. I don't ask how to center the element or how to rotate it; I also know the order of transformation can matter, but still, is there any way to make the transform property be merged?
EDIT
the question is marked as a duplicate, but the question is totally different (and answer is not covering my question as well). I am asking about sharing the properties within a single block:
div {
#mixin rhombus;
#mixin centerVertically;
}
The attached question is asked about accessing inherited properties and same level properties. My case is different and I believe the answer can be different as well. I don't search for manipulating the inherited property. I search for the way to merge the property values into one. And I already found an answer although the 'duplicate' question does not have the one which solves the problem.
I've made some research and found the following feature request on a SASS'es repo which describes exactly this case.
Yes, there is no nice solution for that SASS-wise. But there is a workaround by mahdaen which might be really helpful. The code below is fully belonging to this good guy
$tmp-box-shadow-value: none;
#mixin box-shadow($value, $append: false) {
#if ($tmp-box-shadow-value == none) {
$tmp-box-shadow-value: $value !global;
}
#else {
$tmp-box-shadow-value: ($tmp-box-shadow-value, $value) !global;
}
#if ($append == false) {
#include prefixer(box-shadow, $tmp-box-shadow-value, true);
$tmp-box-shadow-value: none !global;
}
}
with usage like
.shadow-elem {
// Appending values.
#include box-shadow(0 0 1px #ccc, true);
#include box-shadow(0 0 1px #ddd, true);
// Append and write the style.
#include box-shadow(0 0 1px #eee);
}
Although it may seem dirty in somebody's eyes, I really like it as after small adaptions it fully solves my problem.
I'd like to know if there is a way to include a mixin (compass or my own) by a value of a specific variable.
Currently I have the following mixin (which works)
#mixin aligned-top-bottom-border($size, $side){
#if $side == "left"{
#include border-top-left-radius($size);
#include border-bottom-left-radius($size);
}
#else{
#include border-top-right-radius($size);
#include border-bottom-right-radius($size);
}
}
I'd like to turn it to something like the code below (or any other alternative that is shorter and more readable)
#mixin aligned-top-bottom-border($size, $side){
#include border-top-#{side}left-radius($size);
#include border-bottom-#{side}-radius($size);
}
I'm using Sass 3.4.5 (Selective Steve)
Sass documentation has this to say about interpolation:
You can also use SassScript variables in selectors and property names
using #{} interpolation syntax
Nothing about using them in mixins or functions. But there is nothing stopping you from adding your own vendor loop to the mixin instead of using the compass mixin. Like this:
#mixin aligned-top-bottom-border($size, $side){
#each $vendor in ('-webkit-', '-moz-', '-ms-', '-o-', ''){
#{$vendor}border-top-#{$side}-radius: $size;
#{$vendor}border-bottom-#{$side}-radius: $size;
}
}
It gets a bit DRYer but a lot bigger in final output. But it possible.
For some reason my grid is only showing the mobile (3 column) grid at all screen sizes. I am using the values below and don't understand what I am doing wrong. Any suggestions would be most welcome
#include add-grid(3);
#include add-grid(6 at 320px);
#include add-grid(12 at 740px);
#include add-gutter(1/3);
I am using the gems below
Using sass 3.3.14
Using breakpoint 2.5.0
Using singularitygs 1.2.1
It is not enough to define grid context.
In order for your responsive grids to work, you have to explicitly use them, e. g.:
#import "breakpoint";
#import "singularitygs";
#include add-grid(3);
#include add-grid(6 at 320px);
#include add-grid(12 at 740px);
#include add-gutter(1/3);
#include add-gutter(0.25);
.foo {
background-color: deeppink;
min-height: 10em;
// Mobile grid
#include float-span(1);
// Medium grid
#include breakpoint(320px) {
#include float-span(1);
}
// Large grid
#include breakpoint(740px) {
#include float-span(1);
}
}
Note that spans leak from smaller breakpoints into larger ones, and, unless overridden, they will mess your layout. In order to avoid that, set media queries with both min-width and max-width. Refer to Breakpoint documentation for details.
Is it possible to break out/return early of a Sass mixin? I'd like to do something like this:
#mixin foo($bar: false) {
#if $bar {
// return early without applying any of the styles below
}
color: red;
}
Edit: Please keep in mind that this example is the simplest thing I could come up with that illustrates my problem. In the real world, my code is much more complex and the use case for this is clear.
Sass doesn't really have the concept of "break", but an #if/#else will get you pretty close:
#mixin foo($bar: false) {
#if $bar {
color: green;
}
#else {
color: red;
}
}
From the Lead Sass developer at https://github.com/nex3/sass/issues/378:
The issue is that the more seldom-used control structures exist in
Sass, the harder it is for something with only passing familiarity
with the language to read stylesheets that use those control
structures. That's why it started out with the bare minimum set of
structures needed to do anything: because in many cases it makes sense
to skew towards a smaller surface area of the language rather than
optimal semantics for writing complex code.
I still thinking that #if/#else statements is the easiest and best solution to deal with your problem in Sass but I've created two different breakout mixins to help you and as a challenge:
Play with this mixin first
Breakout mixin without #includes (link)
#include breakout($styles)
$style should be a list of styles separated by spaces, here are the allowed values:
Styles
Common CSS styles separated by spaces and without colon or semicolons, lists of values should be wrapped by brackets:
#include breakout(
color blue // <property> <value>
width (100 * 20px) // <property> <operation with values>
border (1px solid #fff) // <property> <list of values>
box-shadow (0 0 10px 4px #0000FF , 0 0 20px 30px #008000) // <property> <nested list of values>
)
Breaks
Breaks are styles that are compiled if its condition is true, also when the condition is true the mixin ends without returns all styles after the break value
$foo: true;
#include breakout(
break (false color red) // break (<condition> <property> <value>
break ((3 < 2) border (1px solid #fff)) // breaks also support list and nested lists
break ($foo width 10px) // This breaks is compiled because condition is true
color blue // This style isn't compiled because the $foo break ends the mixin
)
Note that the order of the mixin argument list is important because it determines the compiled and not compiled styles if a break condition is true
Breakout mixin with #includes (link)
This mixin is similar to the above but it introduces mixin values for $styles, break-mixin mixin and #content into the breakout mixin to allow use of #includes.
Mixins
If you want to use other mixins into breakout mixin you need to add some code into $styles and add each mixin into a break-mixin mixin.
#include breakout(
mixin foo // mixin <name of the mixin declared into break-mixin arguments>
mixin bar // mixin name should match break-mixin argument
mixin foobar
) {
#include break-mixin(foo) { // Here your mixin or mixins for mixin foo }
#include break-mixin(bar) { #include mixin1; #include mixin2; #include mixin3}
#include break-mixin(foobar) { #include foobar}
}
Mixin breaks
Now you can also use mixin into breaks. Here the order is still important:
$foo: true
#include breakout(
mixin foobar
mixin bar
break ($foo mixin foo) // This breaks is compiled because condition is true
color blue // This style isn't compiled because the $foo break ends the mixin
) {
#include break-mixin(foo) { // Here your mixin or mixins for mixin foo }
#include break-mixin(bar) { #include mixin1; #include mixin2; #include mixin3}
#include break-mixin(foobar) { #include foobar}
}
So for your specific case copy the Breakout mixin without #includes (link) to your scss file or use it as a partial and then add this to your code;
#include breakout(
break ($bar property value) // The break out statement
color red // If $bar != false this will be compiled if not it won't
);
I'm surprised that the #error statement has not been mentioned yet. According to the documentation (emphasis mine):
When writing mixins and functions that take arguments, you usually want to ensure that those arguments have the types and formats your API expects. If they aren't, the user needs to be notified and your mixin/function needs to stop running.
That said, #error may not be suitable for every situation, because it will stop the Sass compilation completely. This makes it unfit for mixins where breaking out is an expected end intended scenario.
Example from the Sass documentation:
#mixin reflexive-position($property, $value) {
#if $property != left and $property != right {
#error "Property #{$property} must be either left or right.";
}
$left-value: if($property == right, initial, $value);
$right-value: if($property == right, $value, initial);
left: $left-value;
right: $right-value;
[dir=rtl] & {
left: $right-value;
right: $left-value;
}
}
.sidebar {
#include reflexive-position(top, 12px);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Error: Property top must be either left or right.
}
Is there a standard way to scale all the sprites created by compass? That is, have a image which is double the resolution I need and I wish to have all sprites from that image be have the size. Currently I can do this by iterating over the loaded sprites and setting the background-size and modifying the background-position.
For clarity, by example, if I were using normal sized sprites I'd just do this:
#import "settings/*.png";
#include all-settings-sprites;
But to get the double sized sprites I have to do this:
#import "icons/*.png";
#include retina-sprites($icons-sprites); // retina sprites
#mixin retina-sprites($map) {
$base-class: sprite-map-name($map);
.#{$base-class}-all-retina-sprites {
background-image: sprite-url($map);
#include background-size(ceil(image-width(sprite-path($map)) / 2) auto);
}
#each $sprite in sprite-names($map) {
.#{$base-class}-#{$sprite} {
#extend .#{$base-class}-all-retina-sprites;
$position: sprite-position($map, $sprite);
background-position: nth($position, 1) nth($position, 2) / 2;
}
}
}
I'm hoping there's an easier or standard way to do this. The problem gets worse as I try to include individual sprites in the CSS file elsewhere since I can't use any of the standard definitions.