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;
}
Related
Is there a way to see the CSS that corresponds to the SCSS when we are using SCSS as the preprocessor for Angular?
There is an answer here:
When using angular with scss, how can I see the translated css?
And it mentions using the --extract-css option, however when I try that it looks like it has been deprecated:
sandbox/project $ ng build --extract-css
Unknown option: '--extract-css'
Thoughts?
Styles in Angular Build Files
In your build files the styles of components will actually be compiled in the main.js file. You can find it in the network tab of your browsers developertools.
You will also see a file called styles.css, but this will only contain your global styles. This is because of Angulars view-encapsulation of styles per component. The behavior of angular may change if you change the view-encapsulation strategy as explained here to:
Emulated (default)
ShadowDOM
None
I would not recommend doing that though.
However, if you want you can compile your sass files into css using the command line tool you can install as explained on the official sass website.
You can also just use online sass converters like thisone.
If you are just interested in the global styles here's a reference to How you can switch the format from scss to css in your browser.
Example
app.component.scss
p {
background-color: orange;
}
styles.scss
#import 'default';
p {
color: red;
&:hover {
color: blue;
}
}
default.scss
h1 {
color: teal;
}
Result in Build
styles.css:
h1 {
color: teal;
}
p {
color: red;
}
p:hover {
color: blue;
}
main.js:
AppComponent.ɵfac = function AppComponent_Factory(t) { return new (t || AppComponent)(); };
AppComponent.ɵcmp = /*#__PURE__*/ _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({ type: AppComponent, selectors: [["app-root"]], decls: 1, vars: 0, template: function AppComponent_Template(rf, ctx) { if (rf & 1) {
_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](0, "lib-my-lib");
} }, directives: [my_lib__WEBPACK_IMPORTED_MODULE_1__.MyLibComponent], styles: ["p[_ngcontent-%COMP%] {\n background-color: orange;\n}\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFwcC5jb21wb25lbnQuc2NzcyIsIi4uXFwuLlxcLi5cXC4uXFxBbmd1bGFyJTIwUHJvamVjdHNcXGxpYi1leGFtcGxlXFxzcmNcXGFwcFxcYXBwLmNvbXBvbmVudC5zY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0VBQ0Usd0JBQUE7QUNDRiIsImZpbGUiOiJhcHAuY29tcG9uZW50LnNjc3MiLCJzb3VyY2VzQ29udGVudCI6WyJwIHtcclxuICBiYWNrZ3JvdW5kLWNvbG9yOiBvcmFuZ2U7XHJcbn1cclxuIiwicCB7XG4gIGJhY2tncm91bmQtY29sb3I6IG9yYW5nZTtcbn0iXX0= */"] });
*Note the orange background-color in the last line.
This is just a complement to the accepted answer. I wrote it up in a medium article, as it was not immediately obvious as styles.scss is opened first when selecting elements in Chrome Developer Tooling, but styles.css is in the tab right next to it.
https://fireflysemantics.medium.com/viewing-generated-global-css-for-angular-sass-projects-857a6887ff0b
I am trying to learn SCSS and encountered a small obstacle (if you can call it that) with something I am trying to do.
So the code beneath is probably a non-logical, simplified example of what I am trying to achieve.:
.gt-button {
// some css
&.gt-button-alt-l {
font-size: 2em;
}
}
.gt-buttonset {
// some css
&.gt-button-alt-l > .gt-button {
font-size: 2em;
}
}
This will generate:
.gt-button.gt-button-alt-l {
font-size: 2em;
}
.gt-buttonset.gt-button-alt-l > .gt-button {
font-size: 2em;
}
So I am wondering how to logically get underneath CSS instead:
.gt-button.gt-button-alt-l, .gt-buttonset.gt-button-alt-l > .gt-button {
font-size: 2em;
}
How would I go about getting above generated CSS? I have fiddled around in Sassmeister.com but I cannot seem to get it in a way that is logical to me. I also don't really know the technical term of joining those two CSS pieces into the desired generated CSS piece.
I do have to add that I did get it to work like this:
.gt-button {
&.gt-button-alt-l, .gt-buttonset .gt-button-alt-l > & {
font-size: 2em;
}
}
But that for some reason does not seem logical to me. As .gt-buttonset is no child or anything of the .gt-button. So putting it there just feels weird.
I would appreciate to know if the last code fragment actually is the way to do this or if there are other options. If there are other options I would also like to know them.
If the outputted CSS is that important to you, you could leverage the #extend rule to achieve it:
Source SCSS:
.font-size-two { font-size: 2em; }
.gt-button {
// some css
&.gt-button-alt-l {
#extend .font-size-two;
}
}
.gt-buttonset {
// some css
&.gt-button-alt-l > .gt-button {
#extend .font-size-two;
}
}
Output CSS:
.font-size-two, .gt-buttonset.gt-button-alt-l > .gt-button, .gt-button.gt-button-alt-l {
font-size: 2em;
}
Obviously, the downside is that you now also have an unused .font-size-two class in your CSS.
That said, you may be focusing too much on the nuances of the output CSS-- as long as what you have in your SCSS is expressive, maintainable, and doesn't generate a ton of superfluous CSS output, I would think that to be sufficient, and not worry that every possible optimization is being made. Remember that if you're leveraging any other build tools there will be minification and potentially other optimizations, and that CSS is, ultimately, quite fast.
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.
I am using css modules, however a library I use in a component to append tweets with JavaScript adds some elements to my component in the following structure:
<div class='user'></div>
<div class='tweet'></div>
I want to now style these elements in my css module for the component, as follows:
MyComponent.css
.user {
/* styles */
}
.tweet {
/* styles */
}
However of course now my .user class changes to .MyComponent__user___HZWfM due to the hash naming in the webpack loader.
How can I set a global style in my css module?
According to the css modules docs, :global switches to the global scope for the current selector. e.g.
:global(.example-classname)
So this should work:
:global(.tweet) {
text-align: left;
}
:global(.user) {
text-align: left;
}
Or define a global block
:global {
.tweet {
text-align: left;
}
.user {
text-align: left;
}
}
Can use module class with static class with this way.
myStyle.module.css
.moduleClass_g1m59k:global(.StaticClass) {
background-color: orange;
}
Output will generate like this
.moduleClass_g1m59k.StaticClass {
background-color: orange;
}
Many people have struggled with this and there doesn't seem to be any one agreed upon solution. The one I have settled with involves some tweaking of your bundler and specifically addresses the need to import libraries as-is without having to wrap them or edit them manually.
In my webpack config I have set it to scan all files ending css except those within the 'node_modules' and 'src/static' folders. I import my libraries from here and they dont suffer the classname transforms so I am free to use regular classnames for global css and the className={styles.element} convention as usual for modular css (which will compile down to .component_element__1a2b3 or something similar).
Here is an example of a working production webpack config with this solution:
http://pastebin.com/w56FeDQA
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;
}