I have a project generated via create-react-app with sass-compilation (doc) and foundation-sites framework.
Let's say I have a component that renders something like this:
<div class='mycomp grid-x'>
<div class='mycomp__element cell small-6'>1</div>
<div class='mycomp__element cell small-6'>2</div>
</div>
I thought maybe it would be cleaner if I moved markup foundation classes to sass like this:
.mycomp
#extend .grid-x
&__element
#extend .cell
#extend .small-6
It's not really pretty but at least I don't have to think about markup classes in js-code. And if I want to change css-framework mostly I will need to edit .sass files.
So my question is "Is it a good thought?". And if it is how do I approach this? Since sass compiles each file into corresponding .css I will have to compile them all together in one big .css and remove all import './Mycomp.css' from js-files I guess
The two main benefits of #extend are:
using inheritance like features in CSS/sass
keeping the HTML markup clean and writing all messy styling things only in styling files
Refer: this article https://www.sitepoint.com/the-benefits-of-inheritance-via-extend-in-sass/
Related
I have been looking at tailwind CSS, when I am using it, it feels like writing style inside HTML. Which makes this an awkward library to use for me. But while I was looking at it I got an idea.
Instead of using tailwind like this
<div class="p-4 flex text-lg">Something</div>
Is it possible for me to do this using some CSS preprocessor:
// in html
<div class="some">Something</div>
// in css (with a preprocessor)
.some {
include: .p-4;
include: .flex;
include: .text-lg;
}
This way I don't have to write style in HTML but still get the benefits of tailwind's utility classes.
I know Scss has mixins, but as far as I know tailwind only provides classes and not mixins, and I have no experience with any other CSS preprocessor. So is there any preprocessor that supports this feature?
With SCSS, #extend could do the job. However, it will only work if you have access to the classes you want to extend. As for Tailwind CSS, I think #apply is the built-in way to do what you want.
How can you use css mixins based on an existing library? Example: Consider you want to create a new css class based on the bootstrap btn btn-success classes. It might look like:
.disabled-button {
#mixin .btn;
#mixin .btn-success;
#mixin .disabled;
color:red;
}
Less/Sass are capable of doing such kind of things when you define the classes btn or btn-success yourself, but how do you deal with it when it comes from bootstrap (or another css framework) ?
If you can add LESS compilation into your workflow, you can achieve this easily with its #import (reference) and :extend(x all). Without needing to learn anything more about LESS, you'd do
#import (reference) "bootstrap.less"; // this file is included with bootstrap. `(reference)` means it will only pull in the styles you ask it for, so you could continue using this even if you switch to another framework and don't want to include all of bootstrap
.disabled-button:extend(.button all, .button-success all, .disabled all) {} // pulls in the `.button` styles, `.button-success` styles, and `.disabled` styles
.disabled-button {color:red} // adds on your styles
Explanation of LESS's :extend(all) and relevant documentation links are in this answer
Since CSS is valid LESS, you wouldn't have to make any other changes to your stylesheet. Okay, so how do you add LESS compilation to your workflow? The simplest solution is described in LESS's "Command Line Useage" documentation, which boils down to installing less (once)
$ npm install less -g
and then running lessc, the less compiler
$ lessc my-styles.less my-compiled-styles.css
Using the tools provided by Zurb's Foundation as they were intended means you have to compromise your HTML-markup. You'll be adding classes the HTML doesn't need just to pull in that Foundation functionality.
Using the SASS source code I'm trying to avoid aforementioned problem by using #extend.
Some example HTML markup I want to avoid
<nav id="main_navigation" class="top-bar">
By doing this
#main_navigation {
#extend .top-bar;
}
I realise this would still compile to redundant CSS as well as probably break the JS functionality for the topbar, but let's save that for another question.
The issue is that it doesn't work! Styles that apply to children of .top-bar as well as any pseudo-classes don't get extended to apply to #main_navigation. I tried to recreate the problem in a CodePen, but the compiled code over there is flawless.
So is this a structural problem in Foundation? Or am I messing something up?
I use a Grunt task with grunt-sass to compile the Foundation SASS with my own code after it.
After some more extensive debugging using CodePen I figured the issue had to be in the compiler.
Switching from grunt-sass to the more stable (but slower) grunt-contrib-sass made all unexpected behavior disappear.
Yes, you can #extend Foundation SCSS
I have several styles that use Sass' #extend or #include to inherit properties from selectors imported from Bootstrap scss files.
I would like to convert all of the Bootstrap selectors to #extend-Only placeholders, so I do not have to include any original Bootstrap selectors in my final .css output. The goal is to write my own css classes, extend from Bootstrap only where desired.
For example, I wish to have a navbar called .super-freaky-nav:
.super-freaky-nav{
#extend .navbar;
#extend .navbar-default;
#extend .navbar-top-fixed;
}
Ideally, my final .css output will not have a single reference to .navbar, .navbar-default, or .navbar-top-fixed.
Is there a way to do this without going into the _navbar.scss file and converting all of the selectors to #extend-Only classes (%navbar, %navbar-default, %navbar-top-fixed, etc)?
Thanks!
No. Sass does not have the ability to do what you're asking for. There's still a legitimate need to be able to extend normal classes and Sass has no way of differentiating between classes that should or shouldn't be extended.
One potential implementation I'm exploring uses custom importers in ruby-sass or the experimental importers feature in node-sass (2.0+) to apply a sed (find and replace) transform to the Bootstrap Sass files, replacing leading class definitions with % syntax. I haven't gotten much past experimentation, though, and I don't know what I might break without a comprehensive visual test suite. Happy to have some help with it.
The question pretty much says it all.
For instance, if I were using, say, Twitter Bootstrap, could I define classes in my own SASS stylesheet that inherit from Bootstrap's CSS classes? Or does inheritance in SASS only work within the scope of a single file?
YES! its possible.
If you want all <button> elements to inherit the .btn class from Twitter Bootstrap's Default buttons
In your styles.scss file you would have to first import _bootstrap.scss:
#import "_bootstrap.scss";
Then below the import:
button { #extend .btn; }
**I might be mistaken, but if I get what you're trying to do, can't you just use the #extend .classname; command inside the element that you'd want to extend? Naturally, you should only modify your own code to preserve updatability.
To my knowledge, you have to use #import of the file containing the classes you want to use into your SASS file in order to utilize them in that file. However, I am not a SASS/SCSS expert, so someone may know of another way to remotely use them that I am not aware of.
Just as the accepted answer has shown this is possible with #import, however #import has been deprecated by sass
The Sass team discourages the continued use of the #import rule. Sass will gradually phase it out over the next few years, and eventually remove it from the language entirely. Prefer the #use rule instead.
The #use rule is better suited for use now, since it does not pollute the scope of the importing (user) module. unfortunately at the time of writing the use rule is only implemented in Dart sass.