Scaling all compass sprites - sass

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.

Related

SASS - Complement function on a variable from another scope

I have two separate SASS files among many, on a ReactJS repository, such as _main.sass and _partials.sass. They are combined using #use on a separate file named index.css.
The SASS package as a dependency is just sass via npm.
_main.sass and all of its variables can be accessed by _partials.sass, thanks to #use "./main" as *.
I have the following code on _main.sass which detects OS preference for dark mode:
#media (prefers-color-scheme: light)
body
background-color: $white
color: $black
#media (prefers-color-scheme: dark)
body
background-color: $dark
color: $light
All of these color variables are defined and they're working well.
But the problem is that I need to use complement() function on the background-color which is currently active, in _partials.sass.
The main issue seems to me that when I assign a variable e.g. $accent on both ends of the media queries, the variable does not get picked up by the remote file. I could not wrap my head around to do it in such way, since I'm only a beginner at coding SASS.
Unfortunately, I need the plain CSS #media query implementations for automatically detecting the preference. But any suggestion is appreciated in case it is impossible to keep it like that and achieve what I wanted.
Thank you!
I've found the solution myself.
So, I was trying to make a light/dark theme compliant SASS implementation.
What complement function does is that it rotates the color in the input for 180deg on the RGB hue. I needed this to get corresponding inverted-like colors for each color, for better dark-mode contrast. The difference between invert and complement are listed here.
But, I realized that I did not need that. Here is the code for my theme implementation using SASS.
// rainbow
$blue: #00a4ef
$yellow: #f4b400
$red: #db4437
$green: #61b500
$purple: #6e14ef
$pink: #ff0090
$carmine: #c6004b
// monochroma
$white: #fff
$light: #f5f5f5
$lgray: #c2c2c2
$dgray: #6e6e6e
$ldark: #363636
$dark: #232323
$black: #000
$themes: (light: (logo: url("../static/logo-light.svg"), bg: $white, card-bg: $light, text: $black, link: $red, hover: $pink, active: $carmine, border: $lgray, button: $yellow), dark: (logo: url("../static/logo-dark.svg"), bg: $dark, card-bg: $ldark, text: $light, link: $red, hover: $pink, active: $carmine, border: $dgray, button: $purple))
#mixin themeProperty($theme, $property, $color, $additionalProperties)
#if $additionalProperties
#{$property}: unquote(map-get($theme, $color) + " " + $additionalProperties)
#else
#{$property}: unquote(map-get($theme, $color))
#mixin theme($property, $color, $additionalProperties: "")
$light: map-get($themes, light)
$dark: map-get($themes, dark)
#media (prefers-color-scheme: light)
#include themeProperty($light, $property, $color, $additionalProperties)
#media (prefers-color-scheme: dark)
#include themeProperty($dark, $property, $color, $additionalProperties)
There is a color map named "themes" which lists each color for light and dark themes for different use cases.
Furthermore, the mixins match the exact color for exact usage for the desired theme mode, whichever is being used by the client-side (browser or OS), thanks to #media queries.
For example, if you'd like to color a background-color using the button preset on the theme mapping, the usage is as follows:
#include theme("background-color", button)

Compass animation mixin with multiple animations

I’m trying to use Compass animation mixin with multiple animations. Is this possible?
I’ve tried #include animation(an-1 5s infinite, an-2 10s infinite), but I’m getting an error: Mixin animation takes 1 argument but 2 were passed.
Your compass syntax is correct and works in the current version of compass. Maybe this wasn’t the case in a previous version.
Demo on Codepen
Though you can always combine both animations into one (if both animations should use the exact same options, e.g. easing):
#include animation(an-3 5s ease-in infinite);
#include keyframes(an-3) {
from {
transform: scaleY(0);
opacity: 0;
}
to {
transform: scaleY(1);
opacity: 1;
}
}

Using sprite for retina with SASS/Compass

I'm working with SASS/Compass sprite libraray and I'm trying to configure my sprite to work with 3 icon sizes: 1x, 1.5x and 2x (retina)
this is the import of the folders:
#import "icons10/*.png";
#include all-icons10-sprites;
#import "icons15/*.png";
#include all-icons15-sprites;
#import "icons20/*.png";
#include all-icons20-sprites;
this is a mixin I am writing to manage these sprites:
#mixin my-icon($name) {
#extend .icons10-#{$name};
#media (-webkit-min-device-pixel-ratio: 1.5) {
#extend .icons15-#{$name};
background-position: 100% 100%;
}
#media (-webkit-min-device-pixel-ratio: 2) {
#extend .icons20-#{$name};
}
$icon-width: icons10-sprite-width($name);
$icon-height: icons10-sprite-height($name);
width: $icon-width;
height: $icon-height;
}
I'm completely clueless on how to manage backround-size and background-position in order to make the 1.5x and the 2x library to work. My questions are:
is there a retina solution for this specific SASS library?
I can manage my manual solution if I can fetch the sprite's dimensions themselves, but I don't understand how can I fetch the dimensions of the whole sprite
There is no such build in solution in SASS so far. But if you are willing to switch to sprite maps, there is a way to get the sprite maps size:
background-size: image-width(sprite-path( [your sprit emap] )) image-height(sprite-path( [your sprite map] ))
There is a great piece of code from Gaya Kessler on retina sprites for compass you should check out: Retina Sprites for Compass.
Adding your third icon size shouldn't be a problem.
try this:
https://gist.github.com/alanhogan/2878758
if sprite-url not work, you can try sprite-file

Compass Sprite Image and Scale

I've spent the past 4 hours trying to find a way to create a sprite image with Compass and sass that also automatically scales each individual image for use with the background-size property.
Nothing I've found works, can't believe it's that difficult.
Does any one have a working example?
Edit: This is what I have so far
#mixin resize-sprite($map, $sprite, $percent) {
$spritePath: sprite-path($map);
$spriteWidth: image-width($spritePath);
$spriteHeight: image-height($spritePath);
$width: image-width(sprite-file($map, $sprite));
$height: image-height(sprite-file($map, $sprite));
#include background-size(ceil($spriteWidth * ($percent/100)) ceil($spriteHeight * ($percent/100)));
width: ceil($width*($percent/100));
height: ceil($height*($percent/100));
background-position: 0 floor(nth(sprite-position($map, $sprite), 2) * ($percent/100) );
}
#mixin resize-sprite-set($map, $percent, $only...) {
$name: sprite_map_name($map);
#each $sprite in sprite_names($map) {
#if length($only) == 0 or index($only, $sprite) != false {
.#{$name}-#{$sprite} {
#include resize-sprite($map, $sprite, $percent);
}
}
}
}
The mixin returns no errors.
$my-icons-spacing: 10px; // give some space to avoid little pixel size issues on resize
#import "my-icons/*.png";
$my-icons-sprite-dimensions: true;
#include all-my-icons-sprites;
// the fun part
.small-icons { // overriding all sprites
#include resize-sprite-set($my-icons-sprites, 40); // 40% sized
}
.some-part-of-my-site {
#include resize-sprite-set($my-icons-sprites, 40, logo, ok); // will create overrides only for sprites "logo" and "ok"
}
I get the following error message from the above implementation when I try to compile. Via Prepros App.
remove ../images/my-icons-s9e77ab1ef1.png
create ../images/my-icons-s9e77ab1ef1.png
error style.scss (Line 62 of _mixins.scss: Undefined mixin 'resize-sprite-set'.)
identical ../css/style.css
I've also done some research on this. This gist is what I came up with:
https://gist.github.com/apauly/7917906
Update:
The solution depends on three key-parts:
scale width
scale height
get background-position
0.
Grab the dimensions for both, the complete sprite and the single icon:
$icon-file: sprite-file($map, $icon);
$icon-width: image-width($icon-file);
$icon-height: image-height($icon-file);
$sprite-file: sprite-path($map);
$sprite-width: image-width($sprite-file);
$sprite-height: image-height($sprite-file);
1.
Consider a div displaying a sprite as its background. Set background-size: 100%; to make sure, that the background sprite covers the full width of the div.
If one would use width: 100%;, the result would be something like this:
+----------------+
|--| |
|----------------|
|--------| | <--- This is the sprite image we want to display
|------| |
+----------------+
So we need to enlarge our background to get something like this: (the div should have overflow:hidden though)
+----------------+
|---------| |
|-----------------------|
|----------------| | <---
|-------------| |
+----------------+
To achieve that, just divide the width of the complete sprite by the width of the single icon:
width:percentage($sprite-width / $icon-width);
2.
This one is basically inspired by a blog post form tkenny:
http://inspectelement.com/tutorials/a-responsive-css-background-image-technique/
The resulting sass code is this:
display: block;
height: 0;
padding-bottom: percentage($icon-height / $icon-width);
background-size: 100%;
3.
The rest is just some basic math to calculate the top spacing of the icon inside of the sprite as a relative value:
Get the space from the top in pixels (a negative value):
$space-top:floor(nth(sprite-position($map, $icon), 2));
Sass will need a px-value
#if $space-top == 0 {
$space-top: 0px
}
Set the background position with percentages:
background-position:0 percentage(
-1 * $space-top / ( $sprite-height - $icon-height )
);
Here's a mixin for resizing sprites that works beautifully
#mixin resize-sprite($map, $sprite, $percent) {
$spritePath: sprite-path($map);
$spriteWidth: image-width($spritePath);
$spriteHeight: image-height($spritePath);
$width: image-width(sprite-file($map, $sprite));
$height: image-height(sprite-file($map, $sprite));
#include background-size(ceil($spriteWidth * ($percent/100)) ceil($spriteHeight * ($percent/100)));
width: ceil($width*($percent/100));
height: ceil($height*($percent/100));
background-position: 0 floor(nth(sprite-position($map, $sprite), 2) * ($percent/100) );
}
and the github it came from:
https://gist.github.com/darren131/3410875

CSS Compass custom sprite name [duplicate]

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);
}
}

Resources