How do I create a scoped class without #include? - css

I managed to create a scoped CSS class like this:
.container {
#import "./baa";
/* other props ... */
}
but since #import is getting depreciated, what are my options to make a scoped CSS class now?

If you want to keep your CSS separated from any "framework" setup, the best way is probably to use the mixins system. It's definitely not the best way, but it's what come the closest as what you want, without going with CSS modules or else.
You can define your mixins in some file and import them where you need.
Exemple:
#mixin reset-list {
margin: 0;
padding: 0;
list-style: none;
}
#mixin horizontal-list {
#include reset-list;
li {
display: inline-block;
margin: {
left: -2px;
right: 2em;
}
}
}
nav ul {
#include horizontal-list;
}

Related

SCSS How to create style on the fly

I often use styles like next ones:
...
v-slot-padding-top4 {
padding-top: 4px;
}
v-slot-padding-top16 {
padding-top: 8px;
}
...
I can created many styles in cycle, but this way gives me many created styles that I'll never use.
Is there any way in scss to created styles on the fly? Or prepared something like function and call it from html attribute like class?
SCSS (Sass) is a preprocessor scripting language. It will be converted to CSS. You cannot dynamically create styles on the fly (runtime).
But you can use Sass features like #for. To create all your classes in range you need.
your.scss:
#for $i from 1 through 16 {
.v-slot-padding-top#{$i} {
padding-top: #{$i}px
}
}
Result in CSS:
.v-slot-padding-top1 {
padding-top: 1px;
}
.v-slot-padding-top2 {
padding-top: 2px;
}
.v-slot-padding-top3 {
padding-top: 3px;
}
.v-slot-padding-top4 {
padding-top: 4px;
}
/* etc */

Can I extend external scss rule without including it in the output?

GIVEN that there is existing scss file that defines rules like .btn {..} or .btn-primary...
I WANT to declare my own rules by extending existing rules
.my-button {
#extend .btn
#extend .btn-primary
}
without actually including the .btn and .btn-primary classes in my generated css file?
Normally I need to #import exiting.scss, but that includes all the rules from the file in my css output.
Sass does not currently support this by default, neither with the #import nor #use rule.
Nonetheless, if you (can) use npm packages (npm / yarn) in your project, then node-sass-magic-importer may come in handy for you.
In your example, you could do the following:
#import '{ .btn, .btn-primary } from ~bootstrap';
.my-button {
#extend .btn
#extend .btn-primary
}
Note that the above will not do exactly what you desire – it will still import the other two classes though at least not the entire stylesheet. If you'd still like to go one step further, you could do:
#import '{ .btn as .my-button } from /bootstrap/_buttons.scss';
#import '[variables] from /bootstrap/_variables.scss';
#import '[mixins] from /bootstrap/mixins/_buttons.scss';
.my-button {
#include button-variant($btn-primary-color, $btn-primary-bg, $btn-primary-border);
}
I will recommend you to use #mixins and #include for this.
Although because as you said in your question, you are using an existing file (probably third party) that defines this rules. It may be tedious to turn the classes from this file into mixins.
so if you are going to use only a few classes from this file I recommend you to do that.
You will have to turn:
.btn{
/*
some cool styles
*/
}
into:
#mixin{
/*
cooler styles
*/
}
but still mixins as declared in the Sass documentation do exactly what you want.
source code SCSS:
#mixin reset-list {
margin: 0;
padding: 0;
list-style: none;
}
#mixin horizontal-list {
#include reset-list;
li {
display: inline-block;
margin: {
left: -2px;
right: 2em;
}
}
}
nav ul {
#include horizontal-list;
}
result CSS:
nav ul {
margin: 0;
padding: 0;
list-style: none;
}
nav ul li {
display: inline-block;
margin-left: -2px;
margin-right: 2em;
}
when you import as #import in scss and when you do a production build the webpack dependancy graph will only include it once at the top level as it becomes a common chunk since you are using it in multiple places. Yes there is a side effect that unused scss is also included as there isn't much of tree shaking that is done.
Hence it should not affect the production build.

How to import and use Bulma framework with SCSS but not export all it's contents to CSS

I have been using Bulma CSS framework a lot on my recent web projects, it's amazing and makes my work easier and straightforward.
However I don't use most of it's features, just a few. I know I can import only the files I need and for example: If I only need the columns system I would create a SCSS file like this:
#import "bulma/sass/utilities/_all.sass";
#import "bulma/sass/base/_all.sass";
#import "bulma/sass/grid/columns.sass";
This will generate a huge CSS file and I won't need the most of it! I will only make use of it with the #extend keyword like this:
.my-column {
#extend .column;
...
}
But the generated CSS file will be poluted with lines like these:
/* line 3, ../sass/bulma/sass/grid/columns.sass */
.column, .my-column {
display: block;
flex-basis: 0;
flex-grow: 1;
flex-shrink: 1;
padding: 0.75rem;
}
/* line 9, ../sass/bulma/sass/grid/columns.sass */
.columns.is-mobile > .column.is-narrow, .columns.is-mobile > .is-narrow.my-column {
flex: none;
}
/* line 11, ../sass/bulma/sass/grid/columns.sass */
.columns.is-mobile > .column.is-full, .columns.is-mobile > .is-full.my-column {
flex: none;
width: 100%;
}
/* line 14, ../sass/bulma/sass/grid/columns.sass */
.columns.is-mobile > .column.is-three-quarters, .columns.is-mobile > .is- three-quarters.my-column {
flex: none;
width: 75%;
}
The first block is what I want only. I will not use most of the generated classes in my HTML, only the my-column class.
What I'm looking for is for the pre-processor only include in the class that I declare (my-column) what is needed in this way:
.my-column {
display: block;
flex-basis: 0;
flex-grow: 1;
flex-shrink: 1;
padding: 0.75rem;
}
I don't know if it's possible, maybe is not necessary because the Bulma framework is very lightweight. I just don't like to have so much stuff in the CSS file that's not necessary.
Maybe I just got this whole SCSS pre-processor thing wrong. But if I did not made myself clear in anyway please let me know in the comments.
Thanks for your time!

Convert this CSS in SCSS (same child different parents)

I'm converting a long CSS file into SCSS and got stuck on the following piece of CSS which consists of the a child div that can have different parent divs:
.dark-bg li.accordion-item,
.image li.accordion-item,
.parallax li.accordion-item {
margin: 0;
}
Could that be convertible to SCSS?
Thank you.
Any CSS is valid SCSS. If you rely want to make more like SCSS, you could write:
.dark-bg, .image, .parallax {
li.accordion-item {
margin: 0;
}
}
Is this ok?
#mixin hasAccordion() {
& li.accordion-item {
margin: 0;
}
}
.dark-bg, .image, parallax {
#include hasAccordion;
}

What is right BEM approach to global class inheritance?

I recently started using BEM methodology and I'm confused about class inheritance, or rather - when we talk about BEM - some use cases of modifiers.
Let's look at this example, I have a simple element with few children
.b-content { width: 100%; }
.b-content__image { display: block; }
.b-content__date { font-size: 14px; }
.b-content__title { font-size: 30px; }
.b-content__text { font-size: 16px; }
Now I want to reuse my .b-content block with slightly different styles, so I use modifier .m-compact and now I'm not sure what approach is the right one (in BEM).
Whether I should append modifier class to all elements (which I find more valid according to documentation):
.b-content.m-compact { width: 50%; }
.b-content__image.m-compact { display: none; }
.b-content__date.m-compact { font-size: 12px; }
.b-content__title.m-compact { font-size: 24px; }
.b-content__text.m-compact { font-size: 14px; }
or should I append modifier only to the parent element:
.b-content.m-compact { width: 50%; }
.b-content.m-compact .b-content__image { display: none; }
.b-content.m-compact .b-content__date { font-size: 12px; }
.b-content.m-compact .b-content__title { font-size: 24px; }
.b-content.m-compact .b-content__text { font-size: 14px; }
I find this second method more logical, you know, since I'm writing cascading styles and in real world if I want to write e-mail to 10 people, I would write one and just add more recipients, but on the other hand I realize BEM is practically non-cascading approach.
So what should I use and why?
As you point out in the last lines of your question, when doing BEM you should avoid cascading so, as a corollary to this, you don't have to repeat the modifier where it isn't needed.
For your Modifier I'd write something like this:
.b-content--m-compact {
width: 50%;
}
In your example the Block and the Modifier set only the width, so this is a limited use case. In general it comes handy to use some kind of CSS preprocess to ease the code writing, e.g. in SASS:
.my-block
width: 100%
color: red
&--modifier
#extend .my-block
border: 1px solid red
which will results in:
.my-block, .my-block--modifier {
width: 100%;
color: red;
}
.my-block--modifier {
border: 1px solid red;
}
Modifier in BEM looks like this: .block_modName_modValue
You can add additional class - but it's not BEM. And also modifiers have a name and value.
Block in BEM set namespace
So you set default styles for blocks and all unique(that can be changed) place in css with modifiers. This way your styles don't messed up.
To do this you need:
Place common styles in block styles(.portfolio)
Place unique style(with modifiers) like this.(portfolio_theme_list)
In css you don't need to separate this(preprocessor will be needed).
.portfolio {
/* common styles */
&_theme_list {
/* modifiers style */
}
}
In BEM project-stub(template engine) it would look like this:
If you add modifier to block. Then compile(bemjson) to html.
{
block : 'portfolio',
mods : { theme : 'list' },
}
You will see this code
<div class="portfolio portfolio_theme_list">
</div>
You write elements correctly and understand that they need to be separated(without inheritence).
So now you need just define styles for your block with modifier(portfolio_theme_list).
You have 2 options:
1) If you have 2 different blocks - you need separate common and
unique styles. Unique styles place in styles with modified blocks.
2) If you have only 1 different block & you already have styles on
this blocks. Then you can override and don't separate common
styles(but it can cause pain if you add another modifier/instance)

Resources