SCSS Calling Mixin without duplication - css

I am looking to develop this mixin further, so I can pass multiple arguements through the mixin without having to re-create the include every time e.g:
NOT THIS:
#include main-container(red);
#include main-container(blue);
BUT THIS:
#include main-container(red, blue);
Current Code
#mixin main-container-bg($name){
&.#{$name}-bg{
background:url("/images/"#{$name}"-angle-bg.png") center 78px no-repeat;
}
}
I believe I need a for statement alongside an each statement to loop my mixin though all of the arguments in the #include later in the scss.
Any idea's?
Any help is welcomed.
-Neil

You could use the #each directive and pass a list to the mixin in this way
#mixin main-container-bg($listcolours) {
#each $colour in $listcolours {
&.#{$colour}-bg{
background:url(/images/#{$colour}-angle-bg.png) center 78px no-repeat;
}
}
}
div {
#include main-container-bg((red, blue));
}
The generated CSS is
div.red-bg {
background: url(/images/red-angle-bg.png) center 78px no-repeat;
}
div.blue-bg {
background: url(/images/blue-angle-bg.png) center 78px no-repeat;
}

Related

refactoring repetitive sass to modify based on immediate parent's class

tldr: how to avoid repetition of ".well" selector in below example.
I am using bootstrap and sass to display a "well" div with a shape and with a gradient fill. This may not be a proper use of wells and I'd welcome other suggestions as to how to draw circular/rectangular divs with X% shaded (ideally where X is any integer. [0, 100]) but, for now, I am most interested in whether it's possible in SASS to get rid of the repetition of ".well". I tried using "&" but it would reverse .some_container too and I only wanted to reverse the immediate .inner_container parent to apply there (e.g. .inner_container.round). [There is one outer_container and multiple inner_containers. Each inner_container has one well.]
.outer_container {
.inner_container {
&.round .well {
border-radius: 50%;
}
&.barely_filled .well {
#include gradient-horizontal(sienna, $well-bg, 0%, 25%);
}
&.half_filled .well {
#include gradient-horizontal(sienna, $well-bg, 0%, 50%);
}
&.fairly_filled .well {
#include gradient-horizontal(sienna, $well-bg, 0%, 75%);
}
&.mostly_filled .well {
background-color: sienna;
}
}
}
The most terse way to write it would be like this:
#mixin well($sel) {
&#{$sel} .well {
#content;
}
}
.outer_container {
.inner_container {
#include well('.round') {
border-radius: 50%;
}
#include well('.barely_filled') {
test: 1;
}
#include well('.half_filled') {
test: 2;
}
#include well('.fairly_filled') {
test: 3;
}
#include well('.mostly_filled') {
background-color: sienna;
}
}
}
However, in addition to being more verbose, I feel that this decreases readability over what you currently have.

Sass - #extend mixin, change an argument

I'm new to Sass, so if this isn't the best way of doing this type of thing, I apologise!
So, I've got a mixin for button style, like so:
#mixin button ($bg, $color, $padding, $display: inline, $radius: 0, $transition: 0.2s) {
background: $bg;
#if $radius > 0 {
#include border-radius($radius)
}
color: $color;
#if $display != inline {
display: $display;
}
#if $padding > 0 {
padding: $padding;
}
text-decoration: none;
#include transition(all, $transition, linear);
&:hover {
#if lightness($bg) > 50% {
background: darken($bg, 10%);
} #else {
background: lighten($bg, 10%);
}
}
}
and a button, like so:
.btn {
#include button(#095d94, #fff, 10px, inline-block);
}
But, now I need another button with a different background colour. So what I'm wondering is: is there a way to extend a class, and also just change an argument of the mixin that that class includes, without having to do this:
.btn2 {
#extend .btn;
background: #bad78d;
&:hover {
background: darken(#bad78d, 10%);
}
}
Is it possible to feed in another background colour? Something like,
.btn2 {
$bg: #bad78d; //i know this doesn't work
#extend .btn;
}
or like,
.btn2 ($bg: #bad78d) {
#extend .btn; //this one doesn't even make sense, but I think I'm explaining what I need... ish.
}
I think you have two options here.
Also you try to keep it dry, there is nothing too wrong about repading sometimes. So if your mixin is not too huge it'll be ok to this:
.btn {
#include button(#095d94, #fff, 10px, inline-block);
}
.btn2 {
#include button(#bad78d, #fff, 10px, inline-block);
}
But This will only be required if the difference between .btn and .btn2 is big.
If you just want to change certain properties, you may also just use the classig cascading.
.btn,.btn2 {
#include button(#095d94, #fff, 10px, inline-block);
}
.btn2 {
background-color:#bad78d;
...
}

SASS/Compass better organizing

everyone.
I start to learn how to use SASS and Compass and whant to ask advice in better organizing this snippet of code
.main-link.first-item {
#include background(image-url($bg-sprite) no-repeat -27px -39px,
linear-gradient(#4b4e58, #3f424a));
&:hover {
#include background(image-url($bg-sprite) no-repeat -27px -1px,
linear-gradient(#4b4e58, #3f424a));
}
How can I use linear gradient without repeting, but only changing position of image?
You just need to adjust the background position of the first image.
&:hover {
background-position: -27px -1px, 0 0;
}
I agree with #cimmanon's answer.
Although if you want to use the same thing over and over again on different elements in different stylesheets I would propose to create a mixin and put it into a separate sass file. Than you can import that into the files where you need it:
# mixin.css.scss
#mixin custom-background($bg-sprite, $position-vertical, $position-horizontal) {
#include background(image-url($bg-sprite) no-repeat $position-vertical $position-horizontal,
linear-gradient(#4b4e58, #3f424a));
}
# some.css.scss
#import "mixin.css.scss"
.main-link.first-item {
#include custom-background($bg-sprite, -27px, -39px);
&:hover {
#include custom-background($bg-sprite, -27px, -1px);
}
}

how to generate sprite with fewest empty space using compass sass?

how to generate sprite with fewest empty space using compass sass?
I can not find any setting option to get smart layout for sprit-map function.
but I find that
$dropcap-layout:smart
#import "dropcap/*.png";
can do the job.
but not for sprite-map function.anyone help?
$map: sprite-map("sprite_common/*.png");
%sprite_common{
background-image: sprite-url($map);
background-repeat: no-repeat;
}
#mixin common_output($sprite){
#extend %sprite_common;
width: image-width(sprite-file($map, $sprite));
height: image-height(sprite-file($map, $sprite));
background-position: sprite-position($map,$sprite);
}
.top_tabs .arrow{
#include common_output(checkout_setting__crumb_arrow);
}
.uc_pagination .previous .arrow{
#include common_output(account__center_prev_page);
}
......
By the way, how to genterate sprite png with no radom charater?
for example ,i want sprite_common.png but not sprite_common-s2788fbf16e.png

Sass Background Image mixin

I'm kind of new to Sass, but I'm attempting to create a workflow for myself. I generate "color packs" for my theme designs and need to specify the following variables for my mixin. Is there a better way to do this?:
// folder,filename,extension,repeat,x-pos,y-pos
#mixin background ($folder:style1, $img:file, $type:png, $repeat:no-repeat, $x:0, $y:0) {
background-image: url(./images/#{$folder}/#{$img}.#{$type});
background-repeat: #{$repeat};
background-position: #{$x}px #{$y}px;
}
I'm inserting like so:
#nav {
#include background(style2,myimage,png,repeat-x,10,10);
}
which yields this:
#nav {
background-image: url(./images/style2/myimage.png);
background-repeat: repeat-x;
background-position: 10px 10px;
}
I'd prefer to use CSS shorthand when possible, but I ran into errors with the output. I'd appreciate any expert advice if this is not the best way to do it.
depending on how your packs are structured/applied you might be able to use a loop to generate a bunch of generic styles. See the documentation here: http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#id35
Do you really need 3 separate components to get your image url? wouldn't: $img and then setting that to /folder/img.ext be far easier?
Also, you don't need the #{} for repeat by the way.
I hope this is what you're after… the question is not very specific in terms of what you need the outcome to actually be.
Cheers,
Jannis
Update:
Okay, I see you've updated your question (thanks for that). I believe this could be a little better for general use:
#mixin background($imgpath,$position:0 0,$repeat: no-repeat) {
background: {
image: url($imgpath);
position: $position;
repeat: $repeat;
}
}
.testing {
#include background('/my/img/path.png');
}
This will then output:
.testing {
background-image: url("/my/img/path.png");
background-position: 0 0;
background-repeat: no-repeat;
}
Or you can use the shorthand version:
#mixin backgroundShorthand($imgpath,$position:0 0,$repeat: no-repeat) {
background: transparent url(#{$imgpath}) $repeat $position;
}
.testing2 {
#include backgroundShorthand('/my/img/path.png');
}
Which will generate:
.testing2 {
background: transparent url(/my/img/path.png) no-repeat 0 0;
}
Lastly if you want to specify your base path to your image directory separately you can do the following:
$imagedir:'/static/images/'; // define the base path before the mixin
#mixin backgroundShorthandWithExternalVar($filename,$position:0 0,$repeat: no-repeat) {
background: transparent url(#{$imagedir}#{$filename}) $repeat $position;
}
.testing3 {
#include backgroundShorthandWithExternalVar('filename.png');
}
This will then generate:
.testing3 {
background: transparent url(/static/images/filename.png) no-repeat 0 0;
}
Is this what you needed?
If not feel free to update the question or reply/comment.
some other sample:
path to the image:
$path--rel : "../images";
color
$black: #000000;
creating the mixin:
#mixin background-image($img, $background-position, $background-color) {
background-image: url('#{$path--rel}/#{$img}');
background-repeat: no-repeat;
background-position: $background-position;
background-color: $background-color ;
}
using the mixing:
.navbar-inverse {
#include background-image("header.png", right, $black);
}
result:
.navbar-inverse {
background-image: url("../images/header.png");
background-repeat: no-repeat;
background-position: right;
background-color: #000000;
}
take one $var and it will make it easier for you.
$list: pranav shah
=author-images
#each $author in $list
.photo-#{$author}
background: image-url("avatars/#{$author}.png") no-repeat
.author-bio
+author-images
css
.author-bio .photo-adam {
background: url('/images/avatars/adam.png') no-repeat;
}
.author-bio .photo-john {
background: url('/images/avatars/john.png') no-repeat;
}
.author-bio .photo-wynn {
background: url('/images/avatars/wynn.png') no-repeat;
}
.author-bio .photo-mason {
background: url('/images/avatars/mason.png') no-repeat;
}
.author-bio .photo-kuroir {
background: url('/images/avatars/kuroir.png') no-repeat;
}

Resources