Prefixing SCSS code without nesting rule to its child items - css

I'm creating css themes for our framework. I want to prefix all specific CSS rules with class namespace to make it look this way.
.my-skin .button {...}
.my-second-skin .button {...}
It's easy when using structured SCSS rules to have button.scss file and include the rules to parent this way:
//my-skin/button.scss
.button {...}
//my-second-skin/button.scss
.button {...}
//main.scss
.my-skin {
#import my-skin/button.scss
}
.my-second-skin {
#import my-second-skin/button.scss
}
//output.css
.my-skin .button {...}
.my-second-skin .button {...}
Problem occurs when prepended nested rules are used in skin files:
//my-skin/button.scss
.button {
.test & {...}
}
//main.scss
.my-skin {
#import my-skin/button.scss
}
//produced output.css
.test .my-skin .button {...}
Is there any way to produce this kind of output using directly SCSS without any post-processing? Thank you
//desired output.css
.my-skin .test .button {...}

Related

Import inside CSS rule to append class on the same node level

I have something like this
.my-class {
#import url("style.less");
}
style.less contains
.second-class {
color: red;
}
I get
.my-class .second-class {
color: red;
}
I would like
.my-class.second-class {
color: red;
}
Notice the missing space in the selector. Because the element I would like to style matches .my-class and .second-class.
I am using LESS.
How to get what I want ?
As for as I know it is not possible in LESS.
You should directly add .my-class class in style.less and import that file into wherever you want or make outer HTML element with .my-class class

Automatically generate nested SCSS from regular CSS?

I'd like to take some legacy CSS files and convert them to SCSS with nested styles. For example:
Input
#SomeElement .button { /*Some styles*/ }
#SomeElement .link { /*Some styles*/ }
Output
#SomeElement {
.button { /*Some styles*/ }
.link { /*Some styles*/ }
}
Is there any tool to make this project manageable with thousands of lines of CSS to convert? I understand there may be some edge cases that need manual fixing, but it would be great to be able to jump start the process with some sort of automatic conversion.
Would PostCSS or Gulp have any tools I could leverage?
Thanks for reading.
By using this you can change your css to scss
http://css2sass.herokuapp.com/
Using Gulp
https://www.npmjs.com/package/gulp-css-scss

How to extend css class with another style?

I have nearly 30 classes and I want to apply this classes to my button element. I don't want to add class attribute for every button element. Is there any way to create a new button class like;
.button{
.rounded-corner
.corner
.button-effective
//another 20 classes
}
You will have to use a CSS preprocessor to do this.
SASS
placeholder
%rounded-corner {}
%corner {}
%button-effective {}
.button {
#extend %rounded-corner;
#extend %corner;
#extend %button-effective;
/* Some other styles. */
}
.box {
#extend %rounded-corner;
}
Compiles to:
.button, .box {
/* rounded-corner styles */
}
.button {
/* corner styles here */
}
.button {
/* button-effective styles here */
}
.button {
/* Some other styles. */
}
/*
`.box` is NOT defined here because it only uses placeholders. So it
is placed where the placeholder is defined.
*/
Note: with placeholders, the CSS selector is added to wherever the placeholder is defined. Not where the selector is defined.
extend
.rounded-corner {}
.corner {}
.button-effective {}
.button {
#extend .rounded-corner;
#extend .corner;
#extend .button-effective
// Continue with other classes.
}
Compiles to:
.rounded-corner, .button {}
.corner, .button {}
.button-effective, .button {}
mixin
#mixin rounded-corner {}
#mixin corner {}
#mixin button-effective {}
.button {
#include .rounded-corner;
#include .corner;
#include .button-effective
// Continue with other classes.
}
Compiles to:
.button {
/* rounded-corner styles here */
/* corner styles here */
/* button-effective styles here */
}
LESS
LESS has a similar sytanx to SASS and also has extend and mixin, though LESS is a little more forgiving if you want to add one class' style to another. While I believe still considered a mixin in LESS, you can add one class style to another like the following without having to use a keyword.
.rounded-corner {}
.corner {}
.button-effective {}
.button {
.rounded-corner;
.corner;
.button-effective;
// Continue with other classes.
}
Compiles to:
.button {
/* rounded-corner styles here */
/* corner styles here */
/* button-effective styles here */
}
It will be possible in CSS4:
:root {
--toolbar-theme: {
border-radius: 4px;
};
--toolbar-title-theme: {
color: green;
};
}
.toolbar {
#apply --toolbar-theme;
#apply --toolbar-title-theme;
}
For now, you need to use Sass/Less preprocessors.
You could use the attribute selector and concatenate your classes; it would still involve adding a long class to your button element:
<button class="button-rounded-corner-effective">Your button</button>
OR
<button class="button rounded corner effective">Your button</button>
/* Which is exactly what you did not want to do,
but the CSS below will apply all the same.
This example to clarify, then. */
... and then your CSS will be:
[class*="button"]{/*Generic button styles*/}
[class*="rounded"]{/*Rounded styles*/}
[class*="corner"]{/*Corner styles*/}
[class*="effective"]{/*Effective styles*/}
You will need to be careful about the namespacing though - the wild card selector will match any class that has that matches the string.
For example:
[class*="round"]{/*Will match rounded*/}
With CSS modules, you can use composes:
.className {
color: green;
background: red;
}
.otherClassName {
composes: className;
color: yellow;
}
Yes you can use Less or Sass. For me, Less is "easier" to integrate to your project and you will have this code :
.button{
.rounded-corner
.corner
.button-effective
}
.secondClass{
.button;
// your style code
}
.thirdClass{
.button;
// your style code
}
You are describing a mixin or an extends, which is possible currently if you use a CSS Preprocessor like LESS or SASS. CSS Preprocessors allow you to write non-CSS with extra features, and then run it through the preprocessor to convert it into regular CSS which is given to the browser.
It's not possible in regular CSS to do what you are describing.
With CSS modules, you can also compose extending classes from other CSS module by pointing a file:
.otherClassName {
composes: className from "./style.css";
color: yellow;
}

How to #import without including all CSS but just the #extends ones

I'm using stylus with bootstrap-stylus. This is my app.styl code
#import "../../node_modules/bootstrap-stylus/lib/bootstrap.styl";
section
#extend .row
After i run gulp, I notice that complete bootstrap css is included to the target app.css. I want to dynamically include just the .row rule using #extend. what I'm trying to get is this..
section { //.row rules
zoom: 1;
margin-left: -20px;
}
Is it possible? What am I missing? Is it possible with SASS?
AFAIK both stylus and sass do not support importing only certain selectors of a file. If you have control over the imported file, though, you could use SASS placeholder selectors instead of classes/ids. A placeholder selector is some sort of abstract selector which simply doesn't render anything by default.
/* _partial.scss */
%some-selector {
prop: value;
}
%another-selector {
prop: value;
}
/* main.scss */
#import 'partial';
.some-class {
#extend %some-selector;
}
results in the not-extended placeholder selectors being ignored (in this case %another-selector)
/* output.css */
.some-class {
prop: value;
}

Mix css modules classes and boostrap active

In a project I am working on we use css modules with postcss (also postcss-cssnext and postcss-include). We also have bootstrap as a dependency which is globally provided.
In a given component I do have a custom class for a button. So my button has the following classes: btn btn-custom.
According to the requirements I want to modify the appearance of the button when it is in an active state. For that bootstrap has the following selector: .btn.active, .btn:active. Overwriting the pseudoclass is the easy part. The .active class though is where it gets tricky.
In my css file I have tried several ways to handle this but none seems to work. Here are some of the things I've tried:
.btn-custom {
&.active, &:active {}
#nested :global &.active, &:active {}
#nested :global & { &.active, &:active: {} }
#nested :global { &.active, &:active: {} }
}
:global {
.btn-custom { &.active, &:active {} }
.btn { &.active, &:active {} }
}
Has anyone any idea on how this could be achieved?
Global targeted classes needs to be wrapped in parens, like so:
.btn-custom {
color: red;
}
.btn-custom:global(.active) {
color: blue;
}
So with nesting:
.btn-custom {
&:global(.active),
&:active {}
}
That last one is untested, I guess the order of PostCSS plugins is important here.

Resources