How to extend css class with another style? - css

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;
}

Related

With scss #extend pseudo selected CSS

One can do #extend .foo but apparently not #extend .foo:focus.
I'm dealing with a 3rd party component which adds it's own focused class when it considers it is focused. Using #extend to apply Bootstrap styles works fine, but because the 3rd party component does not get a :focus the .form-control:focus is never matched.
My SCSS in principal would be:
.thirdparty {
#extend .form-control;
}
.thirdparty.thirdparty-focused {
#extend .form-control:focus;
}
#extend .form-control:focus; does not compile however.
Currently I can't figure out how to do this without copying the .form-control:focus CSS into .thirdparty.thirdparty-focused, which is obviously rather unideal.
Is some sort of #extend .form-control:focus; equivalent possible, and if not, any suggestions better than copying N lines of CSS to match the rest of Bootstrap?
#extend .form-control:focus will act as a selector, specifically looking for a rule named .form-control:focus. Here is an illustration.
The best solution to your problem would be to outsource the :focus pseudo-selector of the original Bootstrap class, using the %-selector, and then re-extend it into it - so that you could call it seperately.
%focus {
color: #2196f3;
}
.base {
color: #000;
&:focus {
#extend %focus;
}
}
div {
#extend .base;
&.focus {
#extend %focus;
}
}
// Other Bootstrap components can still call `#extend .base;`
This will compile to:
.base:focus, div:focus, div.focus {
color: #2196f3;
}
.base, div {
color: #000;
}
When I tried this, the error message basically told me what to do:
SassError: compound selectors may no longer be extended.
Consider `#extend .form-control, :focus` instead.
Using this should work (don't forget necessary imports to bootstrap):
.thirdparty.thirdparty-focused {
#extend .form-control, :focus;
}

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;
}

How to reference multiple sub-classes on the same element with SASS

I'm using the SMACSS method of writing my SCSS code, and I have a subclass that I want to reference if it also has another subclass.
HTML
<div class="parent-class parent-class-subclass1 parent-class-subclass2">
SCSS
.parent-class {
&-subclass1.&-subclass2 {
//Styles here
}
}
Any idea how I can do this?
So, when parent element also has subclass1 && subclass2, apply styles?
#katniss.everbean Yes, but the way you wrote it makes you have to duplicate the code.
After searching around for a while I stumbled upon this solution that works perfectly by writing any & references after the first one like #{&}:
SASS
.parent-class {
&#{&}-subclass1#{&}-subclass2{
border: 1px solid red;
}
}
Compiles into (CSS)
.parent-class.parent-class-subclass1.parent-class-subclass2 {
border: 1px solid red;
}
I found it on the SASS GitHub page.
...and I have a subclass that I want to reference if it also has another
subclass.
So, when parent element also has subclass1 && subclass2, apply styles?
You only need one & to join the nested selector to the parent class as a sibling. Then write the two subclasses as a regular sibling selector (next to each other without a space in between to indicate they're both required sibling classes).
The SCSS would look like this:
.parent-class {
//some styles
&.parent-class-subclass1.parent-class-subclass2 {
//subclass styles
}
}
That's equivelant to the following CSS
.parent-class {
//some styles
}
.parent-class.parent-class-subclass1.parent-class-subclass2 {
//some other styles
}
To keep your modular naming structure and not have to write out the whole subclass name, you could try using wildcard selectors. I'm not sure it actually ends up looking any better than just writing out the whole class name though.
Here's a codepen that demonstrates:
http://codepen.io/anon/pen/vXKZYA
And the basic code in that pen for posterity:
<div class="parent-class parent-class-subclass1 parent-class-subclass2">
some text that has all the goods
</div>
.parent-class {
color: #0000ff;
&[class*="-subclass1"][class*="-subclass2"] {
font-size: 20px;
font-family: sans-serif;
}
}
you should do it like this
<div class="parent-class subclass1 subclass2">
.parent-class {
&.subclass1.subclass2 {
//Styles here
}
}
or you can even do it like this
.parent-class {
&.subclass1 {
//subclass1 Styles here
&.subclass2 {
//subclass1 & 2 Styles here
}
}
}

Prefixing SCSS code without nesting rule to its child items

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 {...}

Sass/Scss #mixin for element's selector as well

Say I have to have the following CSS:
div { }
div:hover {}
div:active {}
Is there a way to create a #mixin so that I can use
#mixin myAmazingMixer() {
// Div stuff
:hover { // Hover stuff }
:active { // active stuff }
}
div {
#include myAmazingMixer
}
Absolutely! The one thing you're probably missing is the & selector (which references the parent selector)
#mixin myAmazingMixer() {
// Div stuff
&:hover { // Hover stuff }
&:active { // active stuff }
}
div {
#include myAmazingMixer
}
Without the &, your :hover would be applied to all child elements of div.
Create a mixin like : #mixin highlight{color: white;} and then if at all any other element needs to be given a color white u can simply add this mixin to that specific class by mentioning #include highlight
Yes you can do that. You can create a mixin(a css rule) and include it.

Resources