Is it possible to compile only mixins in scss? - sass

I have a scss file with some partial mixins. I want to compile only that mixin, without converting it to CSS. Let me show you the code.
#mixin baseButton() {
position: relative;
display: inline-block;
&:disabled {
background-color: gray;
}
}
#mixin button($classname:".midori-button") {
#{$classname} {
color: gray;
#include baseButton();
}
}
#include button();
Is it possible compile this code into SCSS like the above but not into CSS like:
.midori-button {
color: gray;
position: relative;
display: inline-block;
&:disabled {
background-color: gray;
}
}
Thanks.
P.S: Not native.

Not sure if I'm reading this question right but you can create mixin partials that does not render CSS by adding an underscore to the file name like _button.scss
If you do that you should place the #inclue in the file/files you want to render CSS (using #import to make the mixins available).
// _button.scss => No CSS
#mixin baseButton(){ ... }
#mixin button(){ ...}
// module-1.scss => module-1.css
#import '_button.scss';
#include baseButton;
#include button;
// module-2.scss => module-2.css
#import '_button.scss';
#include baseButton;
#include button;

Related

Mixin in SCSS (properties of a class inside another one)

In LESS I could write something like:
.foo {
color: red;
}
.boo {
.foo();
background: blue;
}
To "include" properties of .foo class into .boo one.
What is the easiest and clean way to obtain a similar beaviour in SCSS?
How about trying like this,
mixins.scss
#mixin flex($x: center, $y: center) {
display: flex;
align-items: $x;
justify-content: $y;
}
custom.scss
.classname {
#include flex(flex-start, space-between);
color: red;
}
Use #include

import content of scss file using mixin

Is there any way to import the content of a scss file into another scss file using mixins?
Something like this:
// media.scss
#mixin media($width, $url) {
#media (min-width:$width) {
#import url($url);
}
};
#mixin small($url) {
#include media(576, $url);
};
//main.scss
#import '../../styles/media.scss';
#include small('./styles/small.scss');
.menu {
height: 4rem;
border-bottom-left-radius: 10px;
background-color: #202020;
}
//small.scss
.menu {
background-color: aqua;
}
In order to use a #mixin in SCSS, you have to use #include in the class selector in which you prefer to include those changes or those style rules.
For example,
.menu {
height: 4rem;
border-bottom-left-radius: 10px;
background-color: #202020;
#include small($url)
// #include (name of mixin)(arguments)
}
or
.menu {
background-color: aqua;
#include small($url)
}
It depends on the class selector you want to use the mixin with. The
$url will be the actual value in this case.
Usually, it is better practice to create a seperate partial file which will include all mixins you have created. These are named with an underscore in the beginning.
For example, a partial _media.scss file can be imported in the main.scss file as #import './media.scss'; or #import '../../styles/media.scss'; depending on the relative path of the partial file.

How can I re-define an existing mixin whilst retaining the original output?

Let's say I have the following mixin:
#mixin foo {
color: red;
}
This mixin is imported in a library, so I don't want to touch the source code. I do however want to extend the functionality of the mixin, and add my own styles to it.
So I need a way to create a new mixin with the same name, whilst retaining the original output but allowing me to add new output, something like:
#mixin foo {
color: blue;
}
#mixin foo {
#include foo; // this is the original
font-size: 14px;
}
Of course the above will not do what I want, but is there something I can do?
I've been playing around and came up with this which seems to work:
#mixin foo() {
color: red;
}
%foo {
#include foo;
}
#mixin foo() {
#extend %foo;
font-size: 22px;
}
.foo {
#include foo;
}
You can extend/change code block of a Mixin using #content; while you have lines inside it by default.
#mixin foo(){
background:green;
border:solid 5px black;
#content;
}
div{
width:200px;
height:100px;
&.one{
+foo(){
border:0;
}
}
}
https://jsfiddle.net/Thielicious/hhb09b61/

SASS: generated CSS not optimal

I am trying to learn SASS. I got this snippet working but the generated css is awful in my opinion. I would like all this css to go in te same .container{ }. Not three different as shown below.
SASS:
.container{
#extend %clearfix;
#extend %text-truncate;
#include border-radius(10px);
}
Genereted css:
.container{
...clear fix
}
.container{
...text-truncate
}
.container{
...clear border-radius
}
What I want:
.container{
...clear fix
...text-truncat
...clear border-radius
}
This is the nature of #extend. If you change your extend classes to ordinary classes, the way it works the way it does is revealed.
#mixin my-mixin() {
padding: 1em;
}
.a {
color: red;
}
.b {
border: 1px solid;
}
.foo {
#extend .a;
#extend .b;
#include my-mixin();
}
Compiles to:
.a, .foo {
color: red;
}
.b, .foo {
border: 1px solid;
}
.foo {
padding: 1em;
}
Using an extend only class simply suppresses the name from the output. If your extend classes are not intended for reuse, then they are better suited as a mixin.
See also: https://codereview.stackexchange.com/a/27910/26722

right-to-left (RTL) support in SASS project

I'm wondering if it's possible to make a mixin that handles multiple arguments as properties that should be converted to rtl.
I want to do something like
.css-selector {
width: 300px;
height: 200px;
#include rtl {
padding: 10px 5px 3px 4px;
margin: 3px 8px 2px 5px;
}
}
with a mixin:
$rtl = false !default;
#mixin rtl() {
#if $rtl {
dir: rtl;
#each $property in #content {
//check property if it's padding or margin or something
else rtl-related... if hit use rtl mixin
}
}
#else { #content; }
}
I think I should parse the #content, but it doesn't work (Invalid CSS after "...h $property in ": expected expression (e.g. 1px, bold), was "#content {) .
Now I handle rtl with 2 vars:
$dir: left !default;
$opdir: right !default;
that i change when it's rtl. I use it in my sass files like
margin-#{$dir}: 15px;
But I don't think this solution is flexible enough. And I also don't want to include a seperate mixin per css property.
Somebody has a better idea or solution? Any feedback welcome
not the same approach, but bi-app-sass will solve the rtl problem, and it will generate a 2 different stylesheets for you
after creating the necessary files (explained in the link above), all you have to do is to call a predefined mixin for left / right properties ( float, border, margin, padding, text-align ... )
.foo {
#include float(left);
#include border-left(1px solid white);
#include text-align(right);
}
there are also a port of this project for less language
bi-app-less
Update
in bi-app-sass there are rtl & ltr conditional mixins that is useful to handle special cases, see the following example
.something {
#include ltr {
// anything here will appear in the ltr stylesheet only
background-image: url( 'app-ltr.jpg' );
}
#include rtl {
// for rtl sheet only
background-image: url( 'app-rtl.jpg' );
margin-top: -2px;
}
}
Note that this feature is not supported in bi-app-less
The following SCSS import adds some useful variables, functions, and mixins.
View on GitHub
Read more
// Override default value for $dir in directional.scss
$dir: rtl;
// Import helpers from directional.scss
#import "directional";
// Use the helpers to make CSS for LTR or RTL
body {
text-align: $left;
padding-#{$right}: 1em;
margin: dir-values(0 2em 0 1em) if-ltr(!important);
}
I would suggest to use a single mixin which can easily handle both cases incl. nested selectors:
_mixin.sass:
$isRLT: true;
#mixin rtl {
#if $isRLT {
#if & {
& {
#content;
}
}
#else {
#content;
}
}
}
_main.sass:
.test {
float: left;
padding: 5px 5px 0px;
#include rtl {
padding: 5px 0px 0px 5px;
}
}
core.scss
// include all your libraries
#import '_mixin';
#import '_main';
This will generate the file without rtl.
For further information check => https://github.com/davidecantoni/sass-rtl-mixin

Resources