If I have this
.base {
color:red;
}
.variation1 {
color:red;
border:1px solid black;
}
How can I change it to something like
.base {
color:red;
}
.variation1 {
import #.base
border:1px solid black;
}
in sass? I basically don't want to repeat the base stuff, I want to import its properties.
Does anyone know?
Thanks
Mixin
You can create a mixin to create reusable chunks of CSS. This helps you avoid repetitive code.
I would suggest a more semantic naming system compared to the sample below.
#mixin base {
color: red;
}
.base {
#include base;
}
.variation1 {
#include base;
border:1px solid black;
}
For more information about the mixin directive check out this article on Sitepoint.
Extend
CSS Tricks elaborates nicely on the extend feature that can also be used but it's got some quirks to it.
.base {
#include base;
}
.variation1 {
#extend .base;
border:1px solid black;
}
It expands all nested selectors as well
It cannot extend a nested selector
You can't extend inside a media query to a selector defined outside the media query
From CSS Tricks
Related
Can CSS have inheritance like OOP?
For example I have this style
.myButton {
background-color:#ffec64;
border:1px solid #ffaa22;
}
Can I define parent for color attributes? Something like
myYellow: #ffec64
So that in every styles I will just use
.myButton {
background-color:myYellow;
border:1px solid #ffaa22;
}
So that changing yellow color will only be on myYellow attribute not for every background-color attributes.
Thanks in advance
This is not possible when using CSS alone.
You can do this by using a css preprocessor like LESS or SASS. These allow for variables, mixins, functions and many other techniques that allow you to make CSS that is more maintainable, themable and extendable.
Once you have written your LESS or SASS you then need to compile it to standard css (in the case of LESS this can be done client-side).
You may need to use CSS Pre Processors like LESS or SASS.
Example Using LESS variables
#myYellow: #ffec64;
.myButton {
background-color: #myYellow;
border: 1px solid #ffaa22;
}
or even you can use LESS mixin to inherit css class.
.myCommonButton {
background-color: #myYellow;
border: 1px solid #ffaa22;
}
.myButton {
.myCommonButton;
color: black;
}
I am using SASS and there is nice feature: I can create "fake/virtual" class and then use it for extend.
Example:
%myFakeClass
{
color:#fff;
background-color:#000;
}
.myRealClass
{
#extend %myFakeClass;
}
.myRealClass2
{
#extend %myFakeClass;
}
Output:
.myRealClass, .myRealClass2
{
color:#fff;
background-color:#000;
}
The question:
Does LESS has something similar? In other words, I want to create a "virtual class" that I can inherit from, but the "virtual class" itself not exists in output.
Not Directly as of Yet
As of this date (11-22-2013) there is still a feature request that would allow this by doing extending on empty parameter mixins (which do not output css themselves). So eventually something like this would be possible (which mirrors almost exactly what you want):
.myFakeClass() {
color:#fff;
background-color:#000;
}
.myRealClass {
&:extend(.myFakeClass);
}
.myRealClass2 {
&:extend(.myFakeClass);
}
And output as you expect.
Workaround for now
This was mentioned by Bass Jobsen, but not explicitly demonstrated. In LESS 1.5, you build a file for your fake classes, say fakeClasses.less, which for our example has this in it:
.myFakeClass {
color:#fff;
background-color:#000;
}
Then in your file that you want to extend to it, let's say styles.less, you do this:
#import (reference) fakeClasses.less;
.myRealClass {
&:extend(.myFakeClass);
}
.myRealClass2 {
&:extend(.myFakeClass);
}
This will import the fakeClasses.less classes but NOT compile them to css (so they are "fake" within the context of styles.less, but "real" in that they can be extended to), and you will get the output you expect.
.myRealClass, .myRealClass2 {
color:#fff;
background-color:#000;
}
Maybe the following helps you img { &:extend(.img-responsive); } from Why gives Grunt / Recess an error and Lessc not when compiling Bootstrap 3 RC1?
update from How do I create a mixin using less.js that doesn't output in the final stylesheet:
.myFakeClass()
{
color:#fff;
background-color:#000;
}
.myRealClass, .myRealClass2
{
.myFakeClass();
}
since LESS 1.5 you could also place you virtual classes in a separate file and use:
#import (reference) "file.less";
We have another import option - reference. This means that any
variables or mixins or selectors will be imported, but never output.
I'm not entirely sure if #extend works the same as a "mixin", but it looks the same.
.myFakeClass(#textColor: #fff, #bgColor: #000 )
{
color:#textColor;
background-color:#bgColor;
}
.myRealClass
{
.myFakeClass();
}
.myRealClass2
{
.myFakeClass();
}
The out put for this would be the same as what you have above. I added variables in the mixin for easier customization for this mixin.
Example:
.myRealClass3
{
.myFakeClass(#369, #00f);
}
The output for all three classes would be:
.myRealClass, .myRealClass2
{
color:#fff;
background-color:#000;
}
.myRealClass3
{
color:#369;
background-color:#00f;
}
Like I said, I'm not entirely sure if there is a big difference between extending a class in SASS and using a mixin in LESS. Hope this helps either way.
Oh, and just to clarify, if the .myFakeClass() class is in a separate .less file that is imported, it will not show up in your CSS unless it is used. I tested this on a website I'm building. I have:
.box-shadow(#a, #b, etc..) {
box-shadow: #a #b etc..;
-webkit-box-shadow: #a #b etc..;
etc: #a...;
}
The class .box-shadow does not show up in my CSS at all.
Link: http://lucienconsulting.com/gs-news/wp-content/themes/TheStone/css/style.css
However, if you write a mixin like this:
.myMixin{
background: #000;
color: #fff;
}
It will show up like a normal class even if not used. Obviously, it looks just like a normal class and could be used by itself, or as a mixin, like so:
.myClass{
.myMixin;
border: 1px solid #fff;
}
This would compile to:
.myClass{
background: #000;
color: #fff;
border: 1px solid #fff;
}
It works, but .myMixin would also show up in your style sheet in this case.
But, like I said, in my original example, it would not.
Succinctly, By using Susy's at-breakpoint responsive mixin, is there a way or function to include an external CSS file in the body of the breakpoint call?
Something like this:
.page {
border: 1px dashed #000;
height: 650px;
#include container;
.content {
color: red;
text-align: center;
border: 1px dashed red;
height: 400px;
#include span-columns(4 omega, 6);
.main {
color: green;
border: 1px dashed green;
text-align: center;
#include span-columns(1, 2);
}
.secondary {
color: blue;
border: 1px dashed blue;
#include span-columns(2, 3);
}
}
#include at-breakpoint(800px 8 250px) {
#include container;
.content {
#include span-columns(1, 1);
}
//IMPORT or INCLUDE CSS FILE HERE somehow...
} //end of breakpoint
}
I was hoping it was possible, because that'd be a whole lot cleaner than writing all the CSS rules I wish to be applied right there inline. Let me know if it's possible or what's the best practice in this case.
Thank you!
Sure. This isn't really a question about Susy, so much as a question about Sass. The same answers are true for working in the context of any wrapping mixin.
You can only import files at the root level (for now, at least) — but that's not your only option. I've seen people write all their site styles inside mixins, and then simply include those mixins as needed:
#mixin medium-layout {
// your medium css
}
.page {
#include at-breakpoint($medium) {
#include medium-layout;
}
}
You can use as many mixins as you like, call them whatever you want, and put them in other files (as long as you #include those files before calling the mixins).
I use a different approach. Rather than nesting everything under a .page selector, with big groups for each breakpoint, I break things up into modules, and keep the breakpoint styles attached to each module as needed.
// _main.scss
.main {
color: green;
#include at-breakpoint($medium) { /* changes to main */ }
}
// _secondary.scss
.secondary {
color: blue;
#include at-breakpoint($medium) { /* changes to secondary */ }
}
From a mobile-first perspective, where breakpoint styles may need to override or build on existing styles, this keeps all the related code in one place.
I use the latest SASS/Compass versions for developing CSS. I've declared some SASS variables at the beginning of the "media=all" stylesheet like this:
$var1: red;
$var2: blue;
$var3: black;
$var4: green;
Later in this SCSS file i import a print stylesheet (#import 'print.scss';) which looks like this:
#media print {
$var1: black;
$var2: black;
$var4:black;
}
I thought, that the variables in the print stylesheet overrides the "normal" vars only if the Browser is in "print mode". But the variables do override always the "normal" vars declared before.
I'm a little confused and appreciate any help.
Thanks!
As per this questions, it's basically not possible in your current form. If you want to achieve this, you'll have to import each style that makes use of your $varX, like:
$blue: blue;
.test{
color: $blue;
}
#media print {
$blue: pink;
.test{
color: $blue;
}
}
output:
.test{color:blue}#media print{.test{color:pink}}
It's not the ideal solution (you'll get lots of repeated code), but unfortunately it's all you can do due to the way CSS works.
This may be a slightly better solution:
$blue: blue;
$print_blue: pink;
.test{
color: $blue;
text-align: right;
#media print {
color: $print_blue;
}
}
output:
.test{color:blue;text-align:right}#media print{.test{color:pink}}
I'm starting to use the LESS framework for styles in an app. I often have places in the app where I need to standardize pseudo-classes for an element to all be the same styles.
Rather than typing out
button:hover,
button:active,
button:hover:active {
/*styles here */
}
I'm using LESS's nested styles to append those psuedo-classes like so:
.button {
{
&,
&:hover,
&:active,
&:hover:active {
border: 2px solid #000000
}
}
That works perfectly fine and outputs button class with appended psuedo-classes.
My question is this: Can I take this even a step further to add the psuedo calls into a mixin and therefore call the mixin? I know this might seem like over-engineering, but I'm reusing this alot throughout several stylesheets and it would be great to be able to reuse one line of code with a mix in.
You can use functional mixins:
.button(#_arg) {
&,
&:hover,
&:active,
&:hover:active {
border: #_arg;
}
}
and then use it following way:
.example {
.button(2px solid #000);
}