extend from class name in another file sass - css

So I'm currently doing some styling, following the BEM standard.
An example of what I'm doing could be this:
.block{
&__element {
}
}
what i would like to do is this:
// file a
.block {
...
}
-
// file b
// add magic to reference the `block`class in file a
&__elelemnt {
...
}
What I'm currently doing:
// file a
.block {
...
}
-
// file b
.block__elelemnt {
...
}
(manually adding the block part to the name)
Is there any way to reference this in a smarter way?
Thanks in advance

You can have this file structure:
block-1/
--block-1.scss
--element-1.scss
--element-2.scss
block-2/
--block-1.scss
--element-1.scss
--element-2.scss
And import elements files info block files.
block.scss:
.block {
color: red;
#import "element-1.scss";
#import "element-2.scss";
}
element-1.scss:
&__element-1 {
color: green;
}
Compiles to:
.block {
color: red;
&__element-1 {
color: green;
}
}

This is perhaps the best you can do.
$namespace: "block";
.#{$namespace}-myClass {
...
}
OUTPUT
.block-myClass {
...
}
You can keep a variable $namespace at the top of your file or in a different file and import it. The advantage of using a variable is you can update it once and all your references will be updated.

SASS is all about DRY.
As in, if you want to modify anything, you should be able to modify it from one single place. If you need anything available across multiple files, consider defining its value in a _vars file and including it everywhere you need it. Also note this has nothing to do with code shortness, but with code maintainability and flexibility.
In fact, even if you do get to write more code (which, in practice, doesn't happen), the advantage of DRY far outweighs it.
Here's how it should be done:
/* _vars.scss: */
$block:block;
/* a.scss: */
#import _vars;
.#{$block} {
...
}
/* b.scss: */
#import _vars;
.#{$block}__element {
...
}
Now, whenever you need to change block value, you can do it from one place: _vars.scss.
But, in practice, most people use the initial technique (nesting):
.block {
...
&__element {
...
}
}
Chances are .block and .block__element are related and, overall, it makes more sense to put them in same file. As your app grows in complexity, you'll find it harder to keep track of your code if you over-complicate it.

Related

Execute minimal css rule sets with both common and specific parts using scss?

.name {
%common {
// common stuff
}
&__first-type {
#extend %common;
// first type thing
}
enter code here
&__second-type {
#extend %common;
// second type thing
}
}
I want to collapse all thing in name class
(first-type, second-type, and also a common part)
but I don't want anything more in the executed CSS file.
.name__first-type, .name__second-type {
//common thing
}
.name__first-type {
//first type thing
}
.name__second-type {
//second type thing
}
can I do this thing without separating non-executable common(%common)?
It is possible to generate those two class like this.
%name__common {
// common stuff
}
.name {
&__first-type {
#extend %name__common;
// first type thing
}
&__second-type {
#extend %name__common;
// second type thing
}
If you mater nice project architecture you can either put this %name__common{...} in partial file such as _commons.scss
or try to change your project coding style.

How to override mixins in LESS CSS 1.4+

I've been using what I thought was a very elegant pattern for defining the styles of reusable components/widgets, using LESS. It works beautifully in LESS 1.3-, but after upgrading recently, my whole library is broken. Does anyone know a way to accomplish something like this in 1.4+?
Here's a very simple example of a component:
#componentName {
.loadMixins(){
.text() {}
.header() {}
}
.apply(){
> h3 {
// markup-specific styles
padding: 3px;
margin-bottom: 0;
// custom styles
.header();
}
> div.body, > div.popup p {
color: red;
// custom styles
.text()
}
}
}
And here's how it would be used:
.coolWidget {
#componentName.loadMixins();
// override mixins here
.text(){
color: green;
}
#componentName.apply();
}
This keeps all the markup-dependent styles abstracted from the user. I could completely change my markup and the user's styles would still work. According to the less.js changelog, 1.4.0 Beta 1 has a line "variables in mixins no longer 'leak' into their calling scope"
Is there any way around this?
Strictly speaking nested variables and mixins are still expanded into calling scope unless this scope already has those names defined.
Your example above results in a error:
SyntaxError: .header is undefined...
and it's expected as no .header() is actually defined within the .coolWidget (or anywhere else).
This can be fixed by providing "default" definitions for .text and .header somewhere inside #componentName.
For example if you modify .loadMixins() to:
.loadMixins() {
.text();
.header();
// default properties in case a caller does not provide its own:
.text() {}
.header() {}
}
then the example compiles OK and all text/header properties are overridden as expected.
I can imagine how your library may become broken because of new scope rules but this particular example you gave above does not illustrate the problem.

LESS - import a file but not print it

I need to compile a LESS file and mix in some of the classes used in other files, but I don't want to print the whole contents of the imported files.
This looks pretty much like silent selectors in SASS.
How can this be achieved?
"muted" imports are not yet implemented in the current stable version of less (1.4.2 as of as of this post), but are planned for inclusion in 1.5.0. source #github issues
They don't seem to be working in the current beta, but when they are finally baked in, the implementation should like this:
PSEUDO CODE
reference.less:
.not-awesome {
color: red;
}
.awesome {
color: blue;
}
main.less:
#import (mute) "foo.less";
.more-awesome:extend(.awesome){
font-size:8em;
}
output:
.awesome,
.more-awesome {
color: blue;
}
.more-awesome {
font-size: 8em;
}

Splitting LESS output into two files - variable and constant

I'm using a great number of variables in my LESS implementation, however there are obviously many rules that are hard coded. The variables are defined on compile by a LESS file containing my style definitions.
Is it possible to split all of the CSS rules output by LESS into variable parts and constant parts, without manually creating two separate files?
So:
#myColour: white;
.foo {
background-colour: #myColour;
width: 120px;
}
becomes two files:
.foo {
background-colour: white;
}
and
.foo {
width: 120px;
}
This way if the theme changes, only the variables need to be reloaded.
Any ideas?
Thanks
Short Answer: No
"Without manually creating two separate files?" (emphasis added), the answer is "No."
You, the programmer, would have to code up two separate files , one that contains the variable calls, then one that contains the "hard coded" info (although, see UPDATE below). But I would not recommend that, as it would be hard to maintain (as far as seeing what is going on with the two different .foo entries in two different files). That's probably why you were hoping to split them after you coded (automatically), but this is just not possible to instruct LESS to output the variable property values to one file and the hard coded to another, at least, not automatically...
UPDATE: The Closest I Could Get
If I understand what you want, you want one file to code in, having the various selectors defined once, but having the properties able to split into a file of css that is variable controlled and therefore that file updated regularly, and one that is static (or "hard coded") that is rarely updated. Here is the closest I could come to coding for that. It is certainly not automatic, but does offer some "consistency" in how it functions.
Consider...
LESS Variables and Master files
// assume this is your variables file (variables.less)
#myColour: white;
// assume this is a master coding file, but it keeps all the properties
// "hidden" in nested mixins labled props()
// This file imports your variables.less file
// Note that the #file variable is NOT in the variables.less file, but
// is in the particular files used to split the code.
// We will call this file master.less
#import variables.less;
.foo {
.props() when (#file = var), (#file = all) {
background-colour: #myColour;
}
.props() when (#file = static), (#file = all) {
width: 120px;
}
& > p.nested {
.props() when (#file = var), (#file = all) {
background-colour: #myColour;
}
.props() when (#file = static), (#file = all) {
margin: 1em;
}
.props(); // call the props, each nesting needs its own props() call.
}
.props(); // call the props
}
Generate LESS Static File
// Assume this is your desired static only file, called staticCSS.less
// It has imported the master coding file to access mixins
// and all code is produced by setting the local #file variable in it
#import master.less;
#file: static; // only static css will output
CSS Static File Output
.foo {
width: 120px;
}
.foo > p.nested {
margin: 1em;
}
Generate LESS Variable Controlled File
// Assume this is your desired variable controlled file, called variableCSS.less
// It has imported the master coding file to access mixins
// and all code is produced by setting the local #file variable in it
#import master.less;
#file: var; // only variable css will output
CSS Variable Controlled File Output
.foo {
background-colour: #ffffff;
}
.foo > p.nested {
background-colour: #ffffff;
}
Generate All Properties
For testing purposes, or just to better see the total combined output of the files, I set the above mixins to all be called if #file: all was set, so you could do this in either of the files while testing:
#import master.less;
#file: all; //all css will output
CSS Variable Controlled File Output
.foo {
background-colour: #ffffff;
width: 120px;
}
.foo > p.nested {
background-colour: #ffffff;
margin: 1em;
}
The class is still fully usable as a mixin itself, or extendable (LESS 1.4)
Adding the following works (making it for #file: static here):
.test {.foo }
.test2 {&:extend(.foo all);}
CSS Output
.foo,
.test2 {
width: 120px;
}
.foo > p.nested,
.test2 > p.nested {
margin: 1em;
}
.test {
width: 120px;
}
.test > p.nested {
margin: 1em;
}

Declare a global CSS property ? Is this possible?

I have a very wierd question, I dont know wether if its possible in css or not
Suppose I have say 3 different css classes as shown below, as you can see I have a common property of all these classes, I want to declare this color somewhere else and pass a reference to it here, so if next time I want to change the color I can simply change at one place rather than changing in all the 5 classes.
I know that you can use body{}, or a wrapper for this but that would affect the colors of the entire site right ? Is there a way to do this ?
Is this even possible ?
.abc {
color:red;
}
.abc2 {
color:red;
}
.abc3 {
color:red;
}
.abc4 {
color:red;
}
.abc5 {
color:red;
}
The bad news: you can't do it in CSS.
The good news: you can write in a meta-CSS language like LESS, which then processes a LESS file to pure CSS. This is called a "mixin".
In LESS:
#errorColor: red;
.error-color {
color: #errorColor;
}
#error-1 {
.error-color;
}
.all-errors {
.error-color;
}
More info: http://lesscss.org/#-mixins
if you want to declare all of them at a time, you can use:
.abc, .abc2, .abc3, .abc4, .abc5 {
color:red;
}
Or you can declare an additional class & add to all the .abc, .abc2.... & make its color:red;.
This can not be done with CSS, but that is still a very popular thing to do by using a CSS preprocessor such as LESS, SASS, SCSS, or Stylus.
A preprocessor will let you define a variable (say $red = #F00). It will replace the variable in your CSS document with the variable value for you, allowing you to write very DRY and module CSS.
This functionality is referred to as "CSS variables", which is part of the future spec, but not yet implemented on any browsers.
For now, the best way to do this in pure CSS is to declare an additional class for the desired "global", and then add that class to all relevant items.
.abc_global { color: red; }
.abc1 { /* additional styling */ }
.abc2 { /* additional styling */ }
<div class="abc1 abc_global"></div>
<div class="abc2 abc_global"></div>
With LESS
You are able to define that red color once:
.myRedColor {
color:red;
}
Now you can call that red on any CSS styles. Even NESTED styles! It's a wicked tool!
.abc1 {
.myRedColor;
}
.abc2 {
.myRedColor;
}
.abc3 {
.myRedColor;
}
.abc4 {
.myRedColor;
}
NESTED EXAMPLE:
.abc {
.itsEasyAsOneTwoThree{
.myRedColor;
}
}
Now all of our "itsEasyAsOneTwoThree" classes that are properly nested inside of an "abc" class will be assigned the red style. No more remembering those long #867530 color codes :) How cool is that?!
You can also use PostCSS with the plugin postcss-preset-env and support custom properties/variables, then use the :root selector to add global css variables.
:root {
--color-gray: #333333;
--color-white: #ffffff;
--color-black: #000000;
}

Resources