CSS compiles the lighten( ) function and the similar SASS colors' functions in a way that does not seem right - sass

CSS compiles the following mixin code:
#mixin message ($color, $background-color: lighten ($color, 20%) ) {
color: $color;
background-color: $background-color;
}
.message-danger { #include message(red); }
to this
.message-danger {
color: red;
background-color: lighten red, 20%;
}
Obviously you can see that CSS did not compile the lighten( ) function properly. I tried to change the color to a hex code color but that made no difference. I thought the problem was from my code editor, but when I tried the code on sassmeister it gave me the same result. Please help.

Related

extend Compass breakpoint mixin to avoid duplicates

I am using Compass mixin to create media queries for retina like in example:
header {
height: $header-image-height;
text-align: center;
position: relative;
#include breakpoint($standard-resolution) {
background:
linear-gradient(
rgba(0, 0, 0, 0.1),
rgba(0, 0, 0, 0.1)
),
url(../../img/dist/xxx.jpg) center center no-repeat;
}
#include breakpoint($retina-resolution) {
background:
linear-gradient(
rgba(0, 0, 0, 0.1),
rgba(0, 0, 0, 0.1)
),
url(../../img/dist/xxx_2x.jpg) center center no-repeat;
background-size: 1176px auto;
}
color: $header-color;
#extend %montserrat-bold;
}
It works well. But if I put the same mixin into another element, I will get duplicated output of #media at the end - one for each element:
#media screen and (max-resolution: 1.9999dppx), screen and (-webkit-max-device-pixel-ratio: 1.9999), screen and (max--moz-device-pixel-ratio: 1.9999), screen and (max-resolution: 191.9904dpi) {
header {
background: linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1)), url(../../img/dist/xxx.jpg) center center no-repeat;
}
}
And the same output for another elements. Is there any way I could somehow make placeholder from this mixin, so all elements would be under the same single #media directive?
I found a good solution to avoid duplicate code on the output.
First of all there is a good tool to manage breakpoints called maps:
$breakpoints: (
'retina':
//here put all your breakpoints
)
Second instead of putting breakpoint inside each target element, it is better to put #include directive to the root and inside it put all your elements with new directive respond to like this (I have created separate file for this):
_retina.scss:
#include respond-to(retina) {
element1 {}
.element2 {}
}
End not duplicated code))) I hope it will help somebody. By the way I have discovered that Compass sucks((( I wont use it anymore.

Can I remove or ignore a defined sass function?

We are using Rails+Sprockets+Compass. Compass defines a linear-gradient function, which conflicts with the css function of the same name.
After our scss file does an #import "compass", is there a way to remove Compass's linear-gradient function so that I can insert a raw linear-gradient into css?
I know I can redefine the function, but I still can't figure out how to redefine it so that I can insert a raw linear-gradient. I want to remove the function entirely.
The problem is that we're migrating to libsass, which means that Compass's Ruby-based functions no longer work. So this
#import "compass";
.tmp {
button-background: linear-gradient(to bottom, #fdefd4, #fdc154);
}
which I would like to be output as-is, compiles to this:
.tmp {
button-background: _linear-gradient_legacy(compact(to bottom), #fdefd4, #fdc154...);
}
where _linear-gradient_legacy is a Ruby-based compass function that will no longer be expanded under libsass.
Compass expects you to use the provided background and background-image functions whenever you use either of the gradient functions (linear/radial). This is how you get your prefixes. The reason why the functions involved are written in Ruby is so that you can get an SVG gradient for browsers that don't support gradients.
If you want absolutely none of that, just redefine the function like so:
#function linear-gradient($options...) {
#return #{'linear-gradient(#{$options})'};
}
Before redeclaring the function:
#import "compass/css3";
.foo {
background: linear-gradient(to bottom, #fdefd4, #fdc154);
}
.bar {
#include background(linear-gradient(to bottom, #fdefd4, #fdc154));
}
Output:
.foo {
background: linear-gradient(to bottom, #fdefd4, #fdc154);
}
.bar {
background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuNSIgeTE9IjAuMCIgeDI9IjAuNSIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZkZWZkNCIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZkYzE1NCIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');
background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #fdefd4), color-stop(100%, #fdc154));
background: -moz-linear-gradient(top, #fdefd4, #fdc154);
background: -webkit-linear-gradient(top, #fdefd4, #fdc154);
background: linear-gradient(to bottom, #fdefd4, #fdc154);
}
After:
#import "compass/css3";
#function linear-gradient($options...) {
#return #{'linear-gradient(#{$options})'};
}
.foo {
background: linear-gradient(to bottom, #fdefd4, #fdc154);
}
.bar {
#include background(linear-gradient(to bottom, #fdefd4, #fdc154));
}
Output:
.foo {
background: linear-gradient(to bottom, #fdefd4, #fdc154);
}
.bar {
background: linear-gradient(to bottom, #fdefd4, #fdc154);
}
Otherwise, you'll have to implement your own versions of the Ruby functions in Sass.

Updating variables created by lighten/darken functions by modifying the original base color afterwards

I'm currently trying to create a mix-in that will let me build buttons with hover values using the darken and lighten color functions in sass. My code for some reason is spitting out white and black for the background color instead of the hex value of a returned color. Here it is on code pen: http://codepen.io/malikabee/pen/vEQZOv
$btn_color: #fff;
$btn_alpha: 1;
$btn_color_amount: 100%;
$color_funcs: (
'darken': darken($btn_color, $btn_color_amount),
'lighten': lighten($btn_color, $btn_color_amount),
'transparentize': transparentize($btn_color, $btn_alpha)
);
#mixin _btn_color($base_color, $amount, $hover){
background: $base_color;
a:hover,
a:focus{
#each $func_name, $color_func in $color_funcs{
#if($func_name == $hover){
$btn_color: $base_color;
$btn_color_amount: $amount;
background-color: $color_func;
}
}
}
}
.btn{
display: inline-block;
vertical-align: bottom;
text-align: center;
border-radius: 10px;
text-decoration: none;
}
.btn_blue{
#include _btn_color(#3c3c3c, 10%, 'darken');
}
Once you get past this block of code, the expressions don't exist anymore, only the value they evaluated to does:
$color_funcs: (
'darken': darken($btn_color, $btn_color_amount),
'lighten': lighten($btn_color, $btn_color_amount),
'transparentize': transparentize($btn_color, $btn_alpha)
);
Changing $btn_color after this point does nothing. Sass cannot to go back in time and re-run those expressions because they've already been evaluated using the original color (black).
What you can do instead is use the call function.
#mixin _btn_color($base_color, $amount, $func){
background: $base_color;
a:hover,
a:focus{
background-color: call($func, $base_color, $amount);
}
}
.btn_blue{
#include _btn_color(blue, 10%, 'darken');
color: white;
}

Extract body class for use in Scss

I am learning Sass but a bit stuck trying to work something out. I'd like to have a unique background image and header image on different pages. How can I perhaps extract the body class name form the markup and interpret that in scss?
Essentially I require some way to prevent having to do this (which is totally the point of scss right?!)
body.page1 {
background: url(../img/bkg-page1.png) left top repeat-x;
header {
background: url(../img/header-page1.png) center top no-repeat;
height: 320px;
}
}
body.page2 {
background: url(../img/bkg-page2.png) left top repeat-x;
header {
background: url(../img/header-page2.png) center top no-repeat;
height: 320px;
}
}
I realise using variables is the right direction, but not sure how to relay the markup class to the scss.
Any pointers would be most appreciated.
What you're looking for is an #each loop:
#each $class in (page1, page2, page3) {
body.#{$class} {
background: url(../img/bkg-#{$class}.png) left top repeat-x;
header {
background: url(../img/header-#{$class}.png) center top no-repeat;
height: 320px;
}
}
}
This assumes that the class name corresponds to the image name, as indicated in your sample.
body.page1 {
background: url(../img/bkg-page1.png) left top repeat-x;
}
body.page1 header {
background: url(../img/header-page1.png) center top no-repeat;
height: 320px;
}
body.page2 {
background: url(../img/bkg-page2.png) left top repeat-x;
}
body.page2 header {
background: url(../img/header-page2.png) center top no-repeat;
height: 320px;
}
body.page3 {
background: url(../img/bkg-page3.png) left top repeat-x;
}
body.page3 header {
background: url(../img/header-page3.png) center top no-repeat;
height: 320px;
}
You could use a #for loop instead (which eliminates the need for the list of class names) if your class names are always going to have numbers at the end of their name.

CSS3 Animation Question

How can I make a CSS3 Animation play to the end and then stop dead. I don't want it to return the elements being transformed back to their initial states.
Right now I'm using some javascript to add a class to the element after the animation's duration with the same properties as 100% in the animation.
This is possible with the "animation-fill-mode" defined as "forwards", at least in Webkit. I got this result with code like this:
#-webkit-keyframes test {
100% { background-color: #0000ff; }
}
a { background-color: #ff0000; }
a:hover { -webkit-animation: test 1s 1 ease forwards }
Note that specifying start color in 0% keyframe and end color in :hover was not necessary.
Of course, this code is Webkit specific. I haven't tried in other browsers with other vendor prefixes or with the general "animation" property.
put your end values in the main css class and the start values in the animation keyframes at 0%:
#keyframes test {
0% {
background-color: #ff0000; /* start value */
}
100% {
background-color: #0000ff;
}
}
a {
background-color: #ff0000; /* normal state */
}
a:hover {
animation-name: test;
animation-duration: 1s;
background-color: #ff0000; /* final state, after animation is finished */
}
In case this question is still open, I don't think this is possible using CSS3 animations as they're currently specified:
An animation does not affect the computed value before the application of the animation, before the animation delay has expired, and after the end of the animation.
However, you should be able to use CSS3 transitions for basic effects. There's a slide in the html5rocks.com presentation that shows how to do this. Here's the relevant [paraphrased] excerpt:
#box.left { margin-left: 0; }
#box.right { margin-left: 1000px; }
#box { -webkit-transition: margin-left 1s ease-in-out; }
// Run this to animate to the left
document.getElementById('box').className = 'left';
// Run this to animate to the right
document.getElementById('box').className = 'right';
animation-fill-mode: forwards
The animation-fill-mode CSS property specifies how a CSS animation should apply styles to its target before and after it is executing

Resources