I'm learning SASS/SCSS and am playing around with mixins, trying to get my head around the different accepted variations that are available.
Below is what I'm using to create box-shadows, I'm using an if and else statement to display ether with or without the inset property.
#mixin box-shadow($inset: false, $horizontal: 0px, $vertical: 1px, $blur: 2px, $color: 000) {
#if $inset {
box-shadow: $inset $horizontal $vertical $blur $color;
}
#else {
box-shadow: $horizontal $vertical $blur $color;
}
}
I'm wondering how to set the $inset: false to true for this to work as intended.
Or is there a more efficient way to achieve what I'm trying to do?
I think that instead of including the variable $inset, just include the keyword inset. This way, you can pass true or false and it will parse properly:
#mixin box-shadow($inset: false, $horizontal: 0px, $vertical: 1px, $blur: 2px, $color: 000) {
#if $inset {
box-shadow: inset $horizontal $vertical $blur $color;
}
#else {
box-shadow: $horizontal $vertical $blur $color;
}
}
.no-inset {
#include box-shadow($inset: false);
}
.inset {
#include box-shadow($inset: true);
}
Output:
.no-inset {
box-shadow: 0px 1px 2px 0;
}
.inset {
box-shadow: inset 0px 1px 2px 0;
}
Related
Is there any way to check argument in mixins.
For example, I have a shadow mixin and want to include it (call it) different way in case of its argument.
#mixin shadow($shadow, $position, $color) {
.....
}
If I pass Top2 it should change only first parameter
.box { #include shadow(inset, Top2, #000); } => `box-shadow: inset, 2px 0 0 0, #000`
If I pass Bottom2 it should change the parameter to -2px
.box { #include shadow(inset, Bottom2, #000); } => `box-shadow: inset, -2px 0 0 0, #000`
I think you should use this type.
#mixin box-shadow($values) {
-webkit-box-shadow: $values;
-moz-box-shadow: $values;
box-shadow: $values;
}
#mixin box-shadow-inset($inset) {
-webkit-box-shadow: $inset;
-moz-box-shadow: $inset;
box-shadow: $inset;
}
I wonder if there is a way to compose/decompose CSS shorthand with Sass. For example, I have:
$standardPadding: 4px 2px 1px 2px;
and I want to have:
$someSpecificPadding: doSomething($standardPadding, top, 2px);
then the final value of $someSpecificPadding is 2px 2px 1px 2px.
Is there existing any doSomething in Sass (scss) or Less ?
You could use this code to achieve your desired result
#function do_something($list, $args...) {
#each $mini-list in $args {
$value: nth($mini-list, 2);
$position: nth($mini-list, 1);
#if $position == top {
$list: set-nth($list, 1, $value);
}
#else if $position == right {
$list: set-nth($list, 2, $value);
}
#else if $position == bottom {
$list: set-nth($list, 3, $value);
}
#else if $position == left {
$list: set-nth($list, 4, $value);
}
}
#return $list;
}
The function can be used to change single or multiple positions in the shorthand value as shown below
$standardPadding: 4px 2px 1px 2px;
//change both top and bottom values
$standardPadding: do_something($standardPadding, top 18px, bottom 15px);
h2 {
border-width: $standardPadding; //returns 18px 2px 15px 2px
}
h3 {
//changes only top value
border-width: do_something($standardPadding, top 12px); //returns 12px 2px 15px 2px
}
Hope this helps.
You can use a mixin somewhat like this
#mixin padding($top, $left: $top, $bottom: $top, $right: $left){
padding-top: $top;
padding-left: $left;
padding-bottom: $bottom;
padding-right: $right;
}
Here's my LESS statements:
#colorWhite: #FFFFFF;
#colorBlack : #000000;
#opacityNormalFill: 0.2;
#opacityNormalLabel: 0.75;
.colorWithAlpha(#color, #alpha)
{
#colorWithAlpha: rgba( red(#color), green(#color), blue(#color), #alpha );
}
if I write both background-color and color as this:
.button {
.colorWithAlpha(#colorBlack, #opacityNormalFill);
background-color: #colorWithAlpha;
.colorWithAlpha(#colorWhite, #opacityNormalLabel);
color: #colorWithAlpha;
}
The output will be:
.button {
background-color: rgba(0, 0, 0, 0.2);
color: rgba(0, 0, 0, 0.2);
}
I have to write it like this:
.button {
.colorWithAlpha(#colorBlack, #opacityNormalFill);
background-color: #colorWithAlpha;
}
.button {
.colorWithAlpha(#colorWhite, #opacityNormalLabel);
color: #colorWithAlpha;
}
It will output correctly:
.button {
background-color: rgba(0, 0, 0, 0.2);
}
.button {
color: rgba(255, 255, 255, 0.75);
}
How to resolve it?
Ok, your var #colorWithAlpha is limitted to your function .colorWithAlpha. If you try to use a global var, it will modifie all your code. You should pass the part to set this color in the function params like this :
#colorWhite: #FFFFFF;
#opacityNormalFill: 0.2;
#opacityNormalLabel: 0.75;
#colorBlack : #000000;
.colorWithAlpha(#color, #alpha, #property)
{
#{property} : rgba( red(#color), green(#color), blue(#color), #alpha );
}
And when you use it :
.button {
.colorWithAlpha(#colorBlack, #opacityNormalFill, background-color);
.colorWithAlpha(#colorWhite, #opacityNormalLabel, color);
}
less doesn't set global variables. You should be using the mixin as a nested style, not as a function.
Like:
.colorWithAlpha(#bgcolor, #color, #alpha)
{
background-color: rgba( red(#bgcolor), green(#bgcolor), blue(#bgcolor), #alpha );
color: rgba( red(#color), green(#color), blue(#color), #alpha );
}
Then:
.button {
.colorWithAlpha(#colorBlack, #colorWhite, #opacityNormalLabel);
}
Docs:
All variables defined in a mixin are visible and can be used in caller's scope (unless the caller defines its own variable with the same name).
Since your first .colorWithAlpha expansion does already define the #colorWithAlpha variable inside the .button, the second .colorWithAlpha call has no effect. (See #1892 for more details).
So you need either to isolate each expansion in its own scope:
.button {
.colorWithAlpha(#colorBlack, #opacityNormalFill);
background-color: #colorWithAlpha;
& { // <- begin new scope
.colorWithAlpha(#colorWhite, #opacityNormalLabel);
color: #colorWithAlpha;
}
}
Or use the solution suggested in #throrin19's answer.
---
And btw., to change color opacity use fade function, i.e. you don't need this mixin at all and your snippet can be simplified to:
#opacityNormalFill: 20%;
#opacityNormalLabel: 75%;
.button {
background-color: fade(#000, #opacityNormalFill);
color: fade(#fff, #opacityNormalLabel);
}
Take a look at the following example:
#mixin placeholder ($color) {
&.-moz-placeholder {
color: $color;
}
&:-ms-placeholder {
color: $color;
}
}
#include placeholder(#999);
But instead I want to insert multiple properties not just the color in the placeholder style. Like this:
#mixin placeholder ($properties) {
&.-moz-placeholder {
$properties;
}
&:-ms-placeholder {
$properties;
}
}
#include placeholder(color: #999, text-shadow: 1px 0px 0px #000);
Is this possible, and if so how?
As #dave suggests, you can accomplish this using Sass's #content directive. Here's what your example would look like using that syntax:
#mixin placeholder {
&.-moz-placeholder {
#content;
}
&:-ms-placeholder {
#content;
}
}
#include placeholder {
color: #999;
text-shadow: 1px 0px 0px #000;
};
Note that to pass a content block, you use curly braces rather than parentheses. You can read more in the SASS documentation.
Are you looking for "Passing Content Blocks to a Mixin"?
http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#mixin-content
On IE I'm having a bit of trouble with my CSS:
body.transparent {
background-color: transparent;
color: #ffffff;
text-shadow: 0 -1px #000, 1px 0 #000, 0 1px #000, -1px 0 #000;
filter: Glow(color=#000000, strength=1);
}
body.transparent a {
text-shadow: none;
filter: -;
}
The Glow filter needs to be excluded on body.transparent a, like the text-shadow is. But I just can't disable the filter for the links. How do I do this??
It seems that you cant override the filter in child elements. Look at this question, there the solution was to give the child a absolute or relative position.
You can explicitly override the filter by negating it.
.parent-element{
filter: hue-rotate(210deg);
}
.unfilter-child{
filter: hue-rotate(-210deg);
}
Try filter:image that is the default value
EDIT
Then try this filter: Glow(Color=#ffffff, Strength=1)
and this filter: Glow(Color=#ffffff, Strength=0)