Use Sass to list of duplicate CSS selectors - sass

Is there a more efficient way to add these prefixes instead of having two lines for each icon? One for fa-ion-md and one for fa-ios-md
$fa-menu-size: 2.4rem;
.menu-inner {
.#{$fa-ion-md-css-prefix}-glass,
.#{fa-ion-ios-css-prefix}-glass,
.#{$fa-ion-md-css-prefix}-music,
.#{fa-ion-ios-css-prefix}-music,
[many more icons]
.#{$fa-ion-md-css-prefix}-meetup,
.#{fa-ion-ios-css-prefix}-meetup {
font-size: $fa-menu-size;
}
}

Probably the simplest way would be to go with the classic ampersand parent selector to combine the prefixes with the suffixes:
$fa-ion-md-css-prefix: "fa-ion-md";
$fa-ion-ios-css-prefix: "fa-ion-ios";
$fa-menu-size: 2.4rem;
.menu-inner {
.#{$fa-ion-md-css-prefix},
.#{$fa-ion-ios-css-prefix} {
&-glass,
&-music,
&-meetup{
font-size: $fa-menu-size;
}
}
}

You could use iteration, DEMO
$fa-menu-size: 2.4rem;
$fa-ion-md-css-prefix: "fa-ion-md";
$fa-ion-ios-css-prefix: "fa-ion-ios";
$icons: glass, music, meetup, stuff, things;
#each $icon in $icons {
#{$fa-ion-md-css-prefix}-#{$icon},
#{$fa-ion-ios-css-prefix}-#{$icon} {
font-size: $fa-menu-size;
}
}

Related

scss, same class, different elements html

I use scss,
I have a css class, I need some css property to be different, depending of the html element:
<a class="myClass">...</a><input class="myClass"/>
I've try, but it don't work:
.myClass {
&.someOtherClass{...}
&text-area{...}
&input{...}
}
Any idea?
for easy readinf, I need the element to be define INSIDE the class, I can't use something like
input{ &.myClass{...}}
text-area{ &.myClass{...}}
With the #at-root directive you can write your SCSS code in a nested fashion but the resulting CSS will not be nested.
.myClass {
#at-root input#{&} { color: red; }
}
will result in
input.myClass {
color: red;
}
But honestly I don't find this better readable than just doing it KISS:
.myClass { ... }
input.myClass { ... }

Extending a placeholder and a regular class

I'm having a little issue with SASS #extend, placeholder class and interpolation.
I'm trying to keep the HTML as clean as possible and that's I decided to go for the #extend function in pair with placeholder classes. However, I'm mainly extending layout-related classes like grid, list etc - that's why I'm mixing a placeholder with a regular class in the declaration, i.e:
%drawer,
.drawer {
...
}
Everything was going just fine except for a moment when I noticed the interpolation with the variable being the ampersand in the main class causes some issues. Sample code (with most of the CSS rules removed):
%drawer,
.drawer {
$this: &;
position: fixed;
z-index: 10;
&__content {
right: 0;
transform: translate(100%, 0);
}
&__optional-element {
background: red;
}
&--left { // I want this modifier to be applied to the parent element as it may affect more than one children element
#{$this}__content {
left: 0;
transform: translate(-100%, 0);
}
}
}
And the extension code:
.product-drawer {
#extend %drawer;
&__content {
#extend %drawer__content;
}
}
However, the compiled CSS output is the following:
.drawer--left .product-drawer,
.drawer--left .drawer__content {
left: 0;
transform: translate(-100%, 0);
}
You may notice the first line is redundant and actually wrong. In addition, the "&__optional-element" bit is not outputted for the "product-drawer" extension which makes it really strange. It happens only to rules with the $this interpolation.
As soon as I remove the regular ".drawer" class from the original declaration (and just leave %drawer there), the problem is gone but in these layout-related classes (.grid, .list), we want to keep the regular class name as well so in some various, simple cases it can be used as well, without a need to write new CSS and extending it the placeholder class.
I know that this could be resolved by separating the placeholder class (%drawer) from the regular one (.drawer) completely and then extend the placeholder class inside the regular ".drawer" declaration but that would simply duplicate the code... Or maybe my approach is wrong by design?
Thank you!
The problem is not the #extend rule. The thing is that placeholders are a shallow copy of a class. If you extend from a class you are going to inherit all its properties, but if you extend from a placeholder it is only going to copy the first level.
See this example:
%placeholder{
content: 'placeholder';
&__element{
content: 'placeholder__element';
}
}
.a{
#extend %placeholder;
}
.class{
content: 'class';
&__element{
content: 'class__element';
}
}
.b{
#extend .class;
}
.a {
content: 'placeholder';
}
.class, .b {
content: 'class';
}
.class__element {
content: 'class__element';
}
By using both you're forcing placeholder class to use also the properties:
%placeholder,
.class{
content: 'class';
&__element{
content: 'class__element';
}
}
.b{
#extend %placeholder;
}
.b,
.class {
content: 'class';
}
.class__element {
content: 'class__element';
}

Is there a way to combine scss nesting and tailwindcss?

I'm new to tailwindcss, and i want to use both sassy css and tailwind for my new project. But I'm having trouble with the nesting specially when i used "#apply".
section {
#apply .p-4;
ul {
li {
#apply .ml-8 .text-red-600;
li:last-child {
#apply .text-gray-300;
}
}
}
}
the red color apply to all li but the last-child (gray color) is not working. I'm not sure if it's possible
Right now we cant combine the SCSS and tailwind file. But we can achieve this by doing like this, give a class name to ul tag mylist
section {
#apply .p-4;
}
.mylist li {
#apply .ml-8 .text-red-600;
}
.mylist li:last-child {
#apply .text-gray-300;
}
You can use Sass and Tailwind together, though there are a few things to watch out for as detailed in the docs.
Though, as also noted in the docs it is recommended that you use PostCSS exclusively as your pre-processor. You can use nesting, variables and much, much more with PostCSS, there's really nothing that you can do with Sass that you cannot do with PostCSS.
I switched my build process from using Sass to PostCSS exclusively, more than 3 years ago, and I've not found anything missing. Indeed I can do so much more, I've never looked back.
Selector you're trying to build here will be compiled to something like:
section ul li li:last-child {...}
I think what you're trying to achieve here is this:
section {
#apply .p-4;
ul {
li {
#apply .ml-8 .text-red-600;
}
li:last-child {
#apply .text-gray-300;
}
}
}
Sure they can!
Nothing's wrong with them, there are couple of very small drawbacks but nothing special.
If your case, you have a tiny mistake in your code
section {
#apply p-4;
ul {
li {
#apply ml-8 text-red-600;
&:last-child {
#apply text-gray-300;
}
}
}
}

Ampersand and mixins in SCSS

Searched but can't find an answer..
I have an element which gets generated (by an external platform) with the following classes: p-button and button.
Now the SCSS is like this:
.p-button {
&.button {
margin: 10px;
}
}
But I want to refactor using mixin includes (this is a big project so there is no other way of making this code better except using mixins). The mixin takes the given selector and applies a . to it. I can't change the mixin, as it is used by many other teams, so I can't pass the ampersand together with the selector. I tried this:
.p-button {
& {
#include button-appearance("button") {
margin: 10px;
}
}
}
But that doesn't work (puts a space between it). You can't do this:
.p-button {
&#include button-appearance("button") {
margin: 10px;
}
}
Anyone have a clue?
EDIT: Here is the mixin
#mixin button-appearance(
$appearance-class,
$show,
$background-color,
$background-image,
$background-position) {
$sel: $button-selector;
#if $appearance-class {
$sel: $sel + '.' + $appearance-class;
}
#{$sel} {
#include normalized-background-image($background-image);
#include show($show);
background-color: $background-color;
background-position: $background-position;
}
#content;
}
EDIT 2: Here is the $button-selector (I can not edit this in the platform, but maybe overwrite it in my own project?)
$button-class: 'p-button';
$button-selector: '.#{$button-class}';
Everyone, finally found the solution. I just removed the &.button from the .p-button mixin include and now it works:
#include button-appearance ("button") { *styles* }
#include button-appearance () { *styles* }
Edited the answer after the original question was edited adding the used and un modifiable mixin
The original mixin does not append the ‘#content’ passed to the mixin to the generated selector. So if you cannot modify the original mixin, the only way is to add your properties outside the mixin. According to the mixin the selector will match a predefined ‘$button-selector’ variable, so it won’t use your class.
So, if you want to use the same class defined in ‘$button-class’, try the following:
#{$button-selector}.button {
margin: 10px;
}
Will output:
.p-button.button {
margin: 10px;
}

Sass Parent Selector

I'm not sure the best way of phrasing this, but through examples.
My desired output is:
.parent-class2.parent .child {
color: red;
}
This is the sort of syntax that I'm using.
.parent {
.child {
.parent-class2.& {
color: red;
}
}
}
Your syntax is almost there. There are two things to take note of:
1) SASS doesn't like redundant periods . in selectors (malformed selectors):
With .parent-class2.& the period before .& is redundant since & = .parent .child
Notice that having the extra period before .& would incorrectly compile to
..parent .child
2) To use the ampersand in the middle of a selector without any spaces, you will have to wrap it with a string interpolation & → #{&} for SASS to evaluate it.
Here's the fixed version:
.parent {
.child {
.parent-class2#{&} {
color: red;
}
}
}
You can use the &#{&} selector ("&" is the parent, so we select "the parent of the parent").
As mentioned in https://css-tricks.com/the-sass-ampersand/#article-header-id-11
The interpolation brackets #{ } are needed as two touching ampersands are invalid Sass.
You can also take a look at #at-root selector which could be usefull in your case.

Resources