How to use !default in a SASS mixin? - css

I have this SASS mixin:
#mixin micro-clearfix
&:after,
&:before
content: ""
display: table
&:after
clear: both
* html &
height: 1% !default
*+html &
min-height: 1% !default
Unfortunately, it does not compile, unless I remove !default which would be the point of having this mixin.
The error message I'm getting is:
Invalid CSS after "1% ": expected expression (e.g. 1px, bold), was "!default")
What I'd like to achieve is that if height (or min-height) has already been defined for the selector then the mixin should use that value, otherwise it should define this property as 1%.
I don't wish to use zoom since that's not a valid property and I like to keep my CSS clean.
Am I using !default the wrong way?
I have Compass 0.12.1 and SASS 3.1.10.

!default is intended to use only when declaring variables: http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#variable_defaults_
What you are trying to do should be done with CSS !important declaration, which should be used in the rule outside the mixin (the one you want to prevail). Anyway, using !important usually it's not a good practice. Maybe you could rely on cascade or specificity.

Here's how I've done it finally:
#mixin micro-clearfix
$minHeight: 1% !default
&:after,
&:before
content: ""
display: table
&:after
clear: both
* html &
height: $minHeight
*+html &
min-height: $minHeight

Related

How do I disable CSS properties in previous style sheets during RTL conversion?

I am trying to convert my bootstrap theme to a RTL layout. I load two stylesheets due to the orders you see below:
#import "mycss.css";
#import "RTL.css";
How I can disable any CSS property in mycss.css by overriding them with a second CSS property in the second stylesheet?
I tried the initial value for this property, but not working.
Look at my example here:
First property in mycss.css stylesheet:
.myclass { right: 64px; }
Second property should be disabled and override by the code below:
.myclass { left: 64px }
The problem is that, after writing the second CSS property, both properties remain. I expected the disabling or deleting of the first property with only the second property remaining.
I have a similar problem with background-color, too.
For disabling you can use 'unset'.
For example background-color: unset;
All css properties have a default value. You can reset the value to this default to make it ignored.
In the case 'right', the default is 'auto' - MDN
.myclass {right: auto; left: 64px; }

Can I nest classes in standard CSS like in LESS

With the LESS preprocessor, you can nest CSS code inside other CSS code, like this:
.Element {
.AnotherElement {
background-color: #FFF;
}
.YetAnotherElement {
background-color: #000;
}
}
This would make the background of .Element .AnotherElement white, and it makes .Element .YetAnotherElement have a background color of black. It does it all without writing it out like:
.Element .AnotherElement {
background-color: #FFF;
}
.Element .YetAnotherElement {
background-color: #000;
}
Does the first example coincide with CSS syntax, or do I have to use the LESS preprocessor?
Nesting is a feature of LESS and SASS, not native to CSS.
This is one of the most common uses for CSS preprocessors, but they offer a lot more too.
No, css doesn't support this syntax, in your css example the "Element" and "AnotherElement" will to receive this properties, AnotherElement will not inherit properties of Element.

How to cancel out .table width:100% in bootstrap css

I want to have my table not take all available space. In my bootstrap.css, I have:
.table {
width: 100%
...
In Chrome Dev Tools, I cancel it and the table shrinks.
How can I override this in my CSS files without modifying the bootstrap file.
Thanks
Ensure your own stylesheet is included after Bootstrap in your HTML.
Override Bootstrap's 100% width style declaration by setting the .table's width to 'auto' in your stylesheet:
.table {
width: auto;
}
Option 1
If it's possible to add your CSS file AFTER your Bootstrap file, this is really all it takes :
.table {
width: auto;
}
Option 2
If it's not possible to add your CSS file AFTER your Bootstrap file, you could increase the specificity like this :
table.table {
width: auto;
}
Note that this would also work if you put this code after your Bootstrap file. Option 1 is just slightly simpler.
Option 3 (not recommended)
You could also add an !important declaration to your rule, which means your rule will override the Bootstrap style no matter (1) whether it's before or after your Bootstrap file, and (2) regardless of specificity :
.table {
width: auto !important;
}
Because CSS rules with !important declarations can override any rule without !important declarations no matter where they're defined or what's their specificity, styles with lots of !important declarations are difficult to maintain and debug. Therefore, it is recommended to avoid using !important, so you should use either option 1 or option 2, depending on whether your CSS comes before or after your Bootstrap file.
.table {
width: initial;
}
or
.table {
width: unset;
}
does the trick.
.table{Width :100% !important;}

Getting Sass to parse browser hacks

What's the best approach to getting Sass (3.4.15) to parse browser CSS property hacks - not using compass or any other library. E.g. '_property' or '*property'.
.hack-test{
display: inline-block;
display: *inline;
}
Invalid CSS after " display: ": expected expression (e.g. 1px, bold), was "*inline;"
I searched around Stack Overflow but could not find anything that could definitively answer this.
You can use sass strings, in such a way that the invalid css is injected as a string.
I put it all inside a mixin for re-use:
$star: "*inline";
#mixin hack-test($selector) {
#{$selector} {
display: inline-block;
display: #{$star};
}
}
So if you try and use the mixin:
#include hack-test('.foo');
The css output will be as desired:
.foo {
display: inline-block;
display: *inline;
}
You can view some SCSS browser hacks I've put on Github here

Does sass harm performance?

I've been educating myself. Reading this:
The engine evaluates each rule from right to left, starting from the rightmost selector (called the "key") and moving through each selector until it finds a match or discards the rule. (The "selector" is the document element to which the rule should apply.)
For example:
ul li a {...}
#footer h3 {...}
* html #atticPromo ul li a {...]
Now, some example code SASS outputs for me:
#content #blog {
/* ... */
}
/* line 85, ../sass/screen.scss */
#content #flickr {
/* ... */
}
#content #flickr div p {
/* ... */
}
This seems a bit awkward.. am I doing something wrong? Is this a communication problem between me and Sass? Are we losing it?
Edit:
Some SCSS code:
#flickr {
#include columns(5,8);
background: url('../img/ipadbg.png') no-repeat;
#ipod-gloss {
z-index: 999;
position: relative;
}
div {
margin-top: -80px;
margin-right: 20px;
h2 {
color: $white;
font-size: 24px;
}
p {
margin-top: 40px;
}
}
}
Side Bonus!: The article says browsers (or at least Firefox) search the selectors from right to left. I couldn't understand why this is a more efficient why. Any clues?
You have to find your compromise between maintainability (nesting makes it easier to find your way around in the stylesheet) and rendering performance.
A rule of thumb says you should try to restrict yourself to a three-level nesting and you should avoid to nest IDs if it's not necessary.
However, I think nesting too much is not the biggest issue. As soon as I became aware of the power of mixins, I used them a lot.
For example, this is my often used button mixin:
#mixin small-button($active-color: $active-color, $hover-color: $button-hover-color, $shadow: true)
display: inline-block
padding: 4px 10px
margin:
right: 10px
bottom: 10px
border: none
background-color: $button-color
color: $font-color-inv
+sans-serif-font(9px, 700)
text-align: center
text-transform: uppercase
cursor: pointer
#if $shadow
+light-shadow
&:hover
text-decoration: none
background-color: $hover-color
&:last-child
margin-right: 0
a
color: $font-color-inv
&, &:hover
text-decoration: none
&.disabled
+opacity(0.75)
&:hover
background-color: $button-color
&.active
background-color: $active-color
&.disabled:hover
background-color: $active-color
You see, quite a bit code. Applying such mixins to many elements on your page will result in a big CSS file which takes longer to be interpreted.
In the old fashioned CSS-way you would give each button element e.g. the class .small-button. But this method pollutes your markup with unsemantic classes.
Sass provides a solution though: selector inheritance via the #extend directive.
If you set defaults for your parameter of the mixin, you can also provide a simple class, which uses the mixins with your default:
// Use this mixin via #extend if you are fine with the parameter defaults
.small-button
+small-button
And then you can just inherit from this class in various contexts:
#admin-interface
input[type=submit]
#extend .small-button
The resulting CSS statement aggregates all usages of .small button into one rule with comma-separated selectors:
.small-button, #admin-interface input[type=submit] {
display: inline-block;
...
}
Concluding, a naive usage of Sass can effect your CSS performance. Used wisely, however, it is maintainable thanks to well-structured and DRY code, it leads to proper separation of markup and styling (semantic classes only) and allows for smart and performant CSS code.
SASS is only a language that compiles down to CSS. If you're concerned with SASS' performance in terms of how it runs in the browser, then SASS doesn't enter the equation -- it'll be compiled and served to the browser as regular CSS.
From what I can see of your usage of SASS, there's a couple of things I could suggest:
You don't have to nest everything.
The ability to nest rules inside each-other in SASS is a language feature, but you don't have to do it if it doesn't make sense to do so.
In terms of your general CSS usage:
If the nesting gets too severe/unwieldly, consider using classes where it makes sense.
When it's necessary to use the hierarchy of DOM elements, consider using the [child combinator]: .foo > .bar.
IDs are meant to be unique, thus should always only reference a single element. Most of the time, they can be CSS rules unto themselves -- #content #flickr would become just #flickr, for instance -- and browsers will optimise the lookup for a single ID. The only time you would need something like #id1 #id2 is if #id2 needs to appear in different contexts on different pages.
If your selector contains things like #id div p, that div is either superfluous or serving a specific purpose.
If it's superfluous, change the rule to #id p, which selects any <p> that occurs as a descendant of #id.
If it serves a specific purpose, consider classing the <div> with a class name that describes its purpose -- perhaps <div class="photos-list">. Then your CSS could become .photos-list p, which is far more maintainable and reusable.

Resources