简体   繁体   中英

How to conditionally load CSS and extend it using SASS/SCSS

tl:dr version: is there a way to @extend a css class and not have the original class appear in my compiled css without changing all my css classes to %placeholder classes?

Short answer based on the below answers : it appears there is no way to do this unless you go through and convert the css to silent/placeholder classes eg convert .one{} to %one{} and even then that will cause problems with media queries.

I have a css file (lets call it "style.css") which contains 200+ CSS classes to style various elements like forms and buttons etc. What I want is to include some of those classes in a project and other classes from that file in other random projects/websites. With each new project I also want to give the classes random semantic class names of my choosing.

My preprocessor of choice when working with CSS is SCSS and I really need an answer that uses the power of SCSS.

Here is a quick example of what I'm talking about - loading css into a SCSS file and then extending that css with my own class names:

//style.css
.one {
  color: red;
  padding-top: 1px;
}

//style2.scss
@import "style.css";

.two {
  @extend .one;
}

The problem here is that my SCSS file will compile to CSS and look like this:

//style2.css
.one {
  color: red;
  padding-top: 1px;
}
.two {
  color: red;
  padding-top: 1px;
}

But what I want to do is only include the second class, which I gave a special name.

I've tried a few ways of doing this but here's one example that does not work but is along the lines of what I was thinking I should be able to do:

A.) First, I grab the style.css file and chuck copy/paste it into a style.scss file.

B.) Second I wrap all the whole thing in a placeholder/silent class, like so:

//style.scss
%placeholder {
  .one {
    color: red;
    padding-top: 1px;
  }
}

C.) Then I import that SCSS file and try and extend a class of my choosing that is within the placeholder, like this:

//style2.scss
@import "style";

.two {
  @extend .one;
}

When I try and compile this I get a blank css file (and rightly so for trying to be too tricky). The other thing I know is that you can't extend nested selectors so "@extend %placeholder .one;" is also out of the question.

My question is this: does anyone know of a way to import and then extend a css class so that the compiled result does not include the imported css?

The only other solution I can think of is to just delete the imported css from the top of my file before I let it out into the wild. But this is honestly less than ideal solution.

Thank you in advance to any answers :)

You're using placeholders incorrectly, the placeholder should simply be one , no need to wrap it. Try this:

// style.scss
%one {
  color: red;
  padding-top: 1px;
}

// style2.scss
@import "style";

.two {
  @extend %one;
}

Note that there is an issue with this approach. While the outputted CSS is leaner than using a mixin ( @include ), you will not be able to use %one inside of any @media queries. Ie. this will not work:

// style2.scss
@import "style";

@media screen and (max-width:1024px) {
  .two {
    // This won't produce CSS as it's inside the media query
    @extend %one;
  }
}

The only way I'm aware to get around this is to use a mixin instead of a placeholder which will result in more CSS (if you use one more than once).

// style.scss
@mixin one() {
  color: red;
  padding-top: 1px;
}

// style2.scss
@import "style";

@media screen and (max-width:1024px) {
  .two {
    @include one();
  }
}

I've detailed the difference in output between mixins and placeholder selectors on my blog if you're not aware.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM