Adding !important using a Compass Mixin - compass-sass

If I'm using compass for CSS and use a function or mixin like:
#include background-image(linear-gradient(#a3cce0, #fff));
is there any easy way to have compass add !important to every line it generates?

You can include it inside the mixin like so:
#include border-radius(5px !important);
Compass will output the following:
-webkit-border-radius: 5px !important;
-moz-border-radius: 5px !important;
-ms-border-radius: 5px !important;
-o-border-radius: 5px !important;
border-radius: 5px !important;

UPDATE: new versions of sass support this syntax now:
#include border-radius(5px !important);
Just do this (as noted in #naoufal answer).
--- old answer ---
You can not use !important with compass mixings, but the culprit is not compass, you should blame sass for this.
#include border-radius(5px) !important; #=> SASS Syntax Error

Actually you can use a #function to handle the !important while keeping the flexibility of the mixing itself. For example:
#function is-important($important){
#return #{if($important, '!important', '')};
}
// by default we don't want the !important at the end
#mixin button-primary($important: false) {
font-size: 14px;
background: #fff is-important($important);
color: #000 is-important($important);
}
Hope it helps!

Just spent hours figuring this out but there is a quick trick you can do. At the top of your SASS file add the following:
$i: unquote("!important");
in your style do the following:
color: #CCCCCC $i;
output is:
color: #CCCCCC !important;
full sample:
$i: unquote("!important");
.some-style {
color: white $i;
}
output:
.some-style {
color: white !important;
}

This question came up in my search for a similar problem, it's spot on but I just wanted to add that Making a Sass mixin with optional arguments was another possible approach that I found useful.
Replace inset with important and pass !important in when you need it.

I had this problem last time and I overrided the compass style with a stronger selector. I just added an ID on my html element
span { #include border-radius(5px);}
span#no-radius { #include border-radius(0px); } // override

Related

How do I customise the Bootstrap 5 Mixins

I am looking to change the .btn-primary color to $white and add a box-shadow. I know there is a very simple way to do this in plain CSS, but I am just learning to customise the Bootstrap SCSS.
I have a separate .scss file which have the below:
#import "../../assets/bootstrap/scss/bootstrap";
#mixin button-variant($color:$white) {
color: $white;
box-shadow: #000 1px 1px 1px;
}
How do I customise/edit/add to existing mixins?
"How do I customise/edit/add to existing mixins?"
The simplest way is to #include the mixin. Notice that the button-variant mixin has 2 required params for background and border color...
#import "bootstrap";
.btn-primary {
#include button-variant($white,$white)
box-shadow: #000 1px 1px 1px;
}
Demo
Use the other #mixin parameters as desired...
#mixin button-variant(
$background,
$border,
$color: color-contrast($background),
$hover-background: if($color == $color-contrast-light, shade-color($background, 15%), tint-color($background, 15%)),
$hover-border: if($color == $color-contrast-light, shade-color($border, 20%), tint-color($border, 10%)),
$hover-color: color-contrast($hover-background),
$active-background: if($color == $color-contrast-light, shade-color($background, 20%), tint-color($background, 20%)),
$active-border: if($color == $color-contrast-light, shade-color($border, 25%), tint-color($border, 10%)),
$active-color: color-contrast($active-background),
$disabled-background: $background,
$disabled-border: $border,
$disabled-color: color-contrast($disabled-background)
)...
The mixin parameterized button-variant, can be used to create customized coloured buttons.The mixin declaration is as:
#mixin button-variant(
$background,
$border,
$hover-background,
$hover-border,
$active-background,
$active-border
);
$background and $border parameters must be provided, and rest are optional parameters. It automatically generates button text color in contrast to the provided background color.
#import node_modules/bootstrap/scss/mixin;
$feature-bg: #ffd803;
.btn-feature {
#include button-variant($feature-bg, darken($feature-bg, 3%));
// optitional
// color: #fff; #uncomment and add your color
}
In html
<button class="btn btn-feature">Feature</button>
Read more: https://themightyprogrammer.dev/snippet/custom-bootstrap-button

SASS/SCSS change variable value before extend

I have Bootstrap 3.3.7 and custom scss files.
I want to override $grid-float-breakpoint only once before #extend evaluates. Right now I have 3 classes which extend base bootstrap class (they use default value, so i don't want to mess with them).
In doc when using mixins and include it's possible. Is it possible using .class and #extend?
I'm looking for something like
$foo : 1px;
.normal-class {
font-size: $foo;
}
.extended-normal-class {
#extend .normal-class;
font-color: yellow;
}
-- This is what I'm trying to do: ---------------------
.override-class {
$foo: 3px;
#extend .normal-class;
// font-size in this class after compile should have 3px;
}
To achiev what you need, you must use #mixin instead of #extend, heres follow an example:
#mixin size($size: 1px){
font-size: $size;
}
.extended-normal-class{
#include size();
}
.override-class{
#include size(3px);
}

compiling sass with grunt produce invalid property name

I don't know why but while compiling with grunt or anything there is an error called invalid property name
#flotTip {
border: none !important;
font-size: $font-size-small !important;
line-height: 1px !important;
#extend .tooltip-inner() !important;
}
in the above code in the line-height it produces an undefined property. My task was to convert all less files into sass files. Used many solutions to convert all of them to sass as far as I can find. But this one I can't find any solution. Can anyone answer what might be the problem?
Extend is only for extending simple selectors, like class, element, or id. You cannot use !important with #extend. This is the correct way to use extend:
.foo {
color: red;
}
#flotTip {
#extend .foo;
}
You may be confused confusing extends with mixins, which also cannot use !important. This is the correct way to use mixins:
#mixin foo() {
color: red;
}
#flotTip {
#include foo();
}
The line-height: 1px !important; line looks fine. The problem is with the following line. If you're trying to include a mixin, use #include and don't prefix the mixin's name with . (dot). Also, don't put !important after it.
I would guess that you are using #extend incorrectly. See the docs here: http://sass-lang.com/documentation/file.SASS_REFERENCE.html#how_it_works

Using #include vs #extend in Sass?

In Sass, I can't quite discern the difference between using #include with a mixin and using #extend with a placeholder class. Don't they amount to the same thing?
Extends do not allow customization, but they produce very efficient CSS.
%button
background-color: lightgrey
&:hover, &:active
background-color: white
a
#extend %button
button
#extend %button
Result:
a, button {
background-color: lightgrey;
}
a:hover, button:hover, a:active, button:active {
background-color: white;
}
With mixins, you get duplicated CSS, but you can use arguments to modify the result for each usage.
=button($main-color: lightgrey, $active-color: white)
background-color: $main-color
border: 1px solid black
border-radius: 0.2em
&:hover, &:active
background-color: $active-color
a
+button
button
+button(pink, red)
Results in:
a {
background-color: lightgrey;
border: 1px solid black;
border-radius: 0.2em;
}
a:hover, a:active {
background-color: white;
}
button {
background-color: pink;
border: 1px solid black;
border-radius: 0.2em;
}
button:hover, button:active {
background-color: red;
}
Please follow this consecutive set of code examples to see how you can make your code cleaner and more maintainable by using extends and mixins effectively: http://thecodingdesigner.com/posts/balancing
Note that SASS unfortunately does not allow using extends inside media queries (and corresponding example from the above link is wrong). In the situation where you need to extend based on media queries, use a mixin:
=active
display: block
background-color: pink
%active
+active
#main-menu
#extend %active // Active by default
#secondary-menu
#media (min-width: 20em)
+active // Active only on wide screens
Result:
#main-menu {
display: block;
background-color: pink;
}
#media (min-width: 20em) {
#secondary-menu {
display: block;
background-color: pink;
}
}
Duplication is inevitable in this case, but you shouldn't care too much about it because web server's gzip compression will take care of it.
PS Note that you can declare placeholder classes within media queries.
Update 2014-12-28: Extends produce more compact CSS than mixins do, but this benefit is diminished when CSS is gzipped. If your server serves gzipped CSS (it really should!), then extends give you almost no benefit. So you can always use mixins! More on this here: http://www.sitepoint.com/sass-extend-nobody-told-you/
A good approach is to use both - create a mixin that will allow you lots of customisation and then make extends for common configurations of that mixin. For example (SCSS Syntax):
#mixin my-button($size: 15, $color: red) {
#include inline-block;
#include border-radius(5px);
font-size: $size + px;
background-color: $color;
}
%button {
#include my-button;
}
%alt-button {
#include my-button(15, green);
}
%big-button {
#include my-button(25);
}
This saves you from calling the my-button mixin over and over. It also means you don't have to remember the settings for common buttons but you still have the ability to make a super unique, one-off button should you choose.
I take this example from a blog post I wrote not long ago. Hope this helps.
In my opinion extends are pure evil and should be avoided. Here is why:
given the scss:
%mystyle {color: blue;}
.mystyle-class {#extend %mystyle}
//basically anything not understood by target browser (such as :last-child in IE8):
::-webkit-input-placeholder {#extend %mystyle}
The following css will be generated:
.mystyle-class, ::-webkit-input-placeholder { //invalid in non-webkit browsers
color: blue;
}
When a browser doesn’t understand a selector, it invalidates the entire line of selectors. This means that your precious mystyle-class is no longer blue (for many browsers).
What does this really mean? If at any time you use an extend where a browser may not understand the selector every other use of the extend will be invalidated.
This behavior also allows for evil nesting:
%mystyle {color: blue;}
#mixin mystyle-mixin {#extend %mystyle; height: 0;}
::-webkit-input-placeholder {#include mystyle-mixin}
//you thought nesting in a mixin would make it safe?
.mystyle-class {#extend %mystyle;}
Result:
::-webkit-input-placeholder, .mystyle-class { //invalid in non-webkit browsers
color: blue;
}
::-webkit-input-placeholder {
height: 0;
}
Tl;dr: #extend is perfectly ok for as long as you never use it with any browser spesific selectors. If you do, it will suddenly tear down the styles wherever you have used it. Try to rely on mixins instead!
Use mixins if it accepts a parameter, where the compiled output will change depending on what you pass into it.
#include opacity(0.1);
Use extend (with placeholder) for any static repeatable blocks of styles.
color: blue;
font-weight: bold;
font-size: 2em;
I totally agree with the previous answer by d4nyll. There is a text about extend option and while I was researching this theme I found a lot of complaints about extend, so just have in mind that and if there is a possibility to use mixin instead of extend, just skip extend.

Why the css2sass and sass-convert converter trips off with CSS multiline comment?

The CSS to convert to SASS:
body {
background: transparent !important; color: #444 !important; text-shadow: none;
}
/* Don't show links for images */
pre, blockquote {
border: 1px solid #999; page-break-inside: avoid;
}
img {
page-break-inside: avoid;
}
/* Grade-A Mobile Browsers */
html {
-webkit-text-size-adjust:none; -ms-text-size-adjust:none;
}
Converted SASS:
body
background: transparent !important
color: #444 !important
text-shadow: none
/* Don't show links for images
pre, blockquote
border: 1px solid #999
page-break-inside: avoid
img
page-break-inside: avoid
/* Grade-A Mobile Browsers
html
-webkit-text-size-adjust: none
-ms-text-size-adjust: none
Watch out the /* Don't show links for images and /* Grade-A Mobile Browsers.
That makes the whole block after it commented.
It should have been /* Don't show links for images */ instead?
Actually Sass can go both ways. You have to understand that for Sass, /* is just the starting point of a block comment that will go like this :
/* This is the beginning of a commment
* This line is indented under it, so it's part of the comment
html
// This selector is not indented so it's not part of the comment
Sass doesn't need */ to end comments the same way it doesn't need } to end selectors : the indentation takes care of it for you.
I recommand you check the Sass comments syntax in more detail in the reference page.
sass-convert --from css --to scss actual.css>newlyCreated.scss
sass-convert --from css --to sass actual.css>newlyCreated.sass

Resources