How to use menu items using SASS [duplicate] - sass

This question already has an answer here:
How do i get the same object with a class in SCSS?
(1 answer)
Closed 8 years ago.
I am creating menu items with their class name as l1, l2 respectively and want to provide different background colors to each item. To get desired background color for each item in CSS file I have to write my code like this:
.menu ul li.l1 {
background: red;
}
.menu ul li.l2 {
background: green;
}
in Sass i am trying to use nesting property and write my code like this:
.menu {
some properties
ul li {
some properties
.l1 {
background: red;
}
}
}
On writing above mentioned code I am getting following CSS as output:
.menu ul li .l1 {
background: red;
}
This is not setting my desired background.
Wow can I access my menu items using SASS?

Your .l1 is not declared properly.
.menu {
ul li {
&.l1 {
background: red;
}
}
}

Related

check if the parent has a specific class on it

This is the usual list where one of the items is .open
for this I want to check if the parent (in this case is .item but its not relevant i think) has a specific class.
I've tried > but it doesnt seem to work.
Essentially how to put this:
&.open .info {
display: none;
}
&.open .inner-info {
display: flex;
}
inside of the their specific classes:
.info {
display: flex;
/* some other stuff */
}
.inner-info {
display: none;
/* some other stuff */
}
all of this is inside an .item{} block
So how do i have it so that i only have two blocks inside the .item{}?
It seems overkill to me, but you can use a hacky way to do that using a mixin and various functions. Please note that this will work for your specific example but probably not for something else.
I used the helper functions str-to-list and nth-delete, which are not native to SASS.
#mixin parentWithClass($class) {
$parent: nth-delete(str-to-list(#{&}), -1);
#at-root #{selector.replace(&, $parent, #{$parent}#{$class})} {
#content;
}
}
.item {
.inner {
color: blue;
#include parentWithClass(".open") {
color: orange;
}
}
.inner-info {
color: red;
#include parentWithClass(".open") {
color: grey;
}
}
}
You can also nest -info in inner.

sass merge selectors on ampersand

assuming I have an existing SASS rule like:
[dir] .foo {
background-image: ...;
// ... some more
}
And I want to add specific behaviors for ltr / rtl like:
[dir] .foo {
background-image: ...;
[dir='ltr'] & {
padding-right: ...;
}
[dir='rtl'] & {
padding-left: ...;
}
}
this would generate undesired css like:
[dir='rtl'] [dir] .foo {
padding-left: ...;
}
This will not match what I want.
Assuming I cannot change the parent selectors (due to specificity), is there any way I can write such nested selectors in a way that compiles to just [dir='rtl'] .foo {...} for the nested elements?
Some resources about the ampersand: https://css-tricks.com/the-sass-ampersand/#aa-qualifying-based-on-context
There is no way that I know to merge selectors as requested.
As you're not allowed to change the parent selector, the only solution I see would be to use the #at-root rule.
#at-root
The #at-root rule is usually written #at-root { ... } and causes everything within it to be emitted at the root of the document instead of using the normal nesting. It's most often used when doing advanced nesting with the SassScript parent selector and selector functions.
Definition on sass-lang.
Here is an example:
[dir] .foo {
$root: '.foo';
background-image: linear-gradient(black, white);
#at-root {
[dir=ltr] #{$root} {
padding-right: 1em;
}
[dir=rtl] #{$root} {
padding-left: 1em;
}
}
}
This will compile to:
[dir] .foo {
background-image: linear-gradient(black, white);
}
[dir=ltr] .foo {
padding-right: 1em;
}
[dir=rtl] .foo {
padding-right: 1em;
}
You could create a mixin to help you with that:
#mixin dir($dir: ltr, $selector: &) {
#at-root {
[dir=#{$dir}] #{$selector} {
#content;
}
}
}
[dir] .foo {
$root: '.foo';
background-image: linear-gradient(black, white);
#include dir(ltr, $root) {
padding-right: 1em;
}
#include dir(rtl, $root) {
padding-right: 1em;
}
}
Food for thougt
If you don't have to support internet explorer, you might want to check padding-inline-end and padding-inline-start properties.
They will free you from the need to have different rules for different directions.
padding-inline-end
The padding-inline-end CSS property defines the logical inline end padding of an element, which maps to a physical padding depending on the element's writing mode, directionality, and text orientation.
MDN Docs - padding-inline-end
padding-inline-start
The padding-inline-start CSS property defines the logical inline start padding of an element, which maps to a physical padding depending on the element's writing mode, directionality, and text orientation.
MDN Docs - padding-inline-start

How to prefix SASS blocks with a specific scope ID via mixin

Looking to be able to add the app scope id to my sass files when we have multiple apps reusing class names.
That way I can have the following definition:
$app-scope-id: 'appOne';
And then write my SCSS in that app
.blockName{
background: blue;
&__element{
color: orange;
}
}
And call a mixin or something else to just go
#include prefixMixin(){
.blockName{
background: blue;
&__element{
color: orange;
}
}
}
And that render out css like:
.appOne-blockName{ background: blue; }
.appOne-blockName__element{ color: orange }
I'm aware I can use interpolation at the beginning of my block, but was hoping I could keep it cleaner with just a mixin call where necessary and only call it once for an entire SASS file if I wanted.
I don't think it's possible to do what you want with SASS. You could maybe do something like this:
$app-scope-id: 'appOne';
#mixin prefix($selectorType: ".") {
#at-root {
#{$selectorType}#{$app-scope-id}-#{&} {
#content;
}
}
}
blockName {
#include prefix() {
background: blue;
&__element{
color: orange;
}
}
}
Which compiles as:
.appOne-blockName { background: blue; }
.appOne-blockName__element { color: orange; }
But you would still need to include it for each selector that needs the prefix. I'm not sure this can be called "clean" either.

How to convert less mixin to scss?

I only just starting to learn both less and sass and can't figure out how to convert this less mixin to scss. This one compiles just fine and provides proper values in a compiled .css file:
.button-styles(#type) {
&--#{type} {
border-color: ##type;
a:hover {
background: ##type;
color: #FFF;
}
}
}
I tried using different converters.
This doesn't work, for example:
#mixin button-styles($type){
&--${type} {
border-color: $$type;
a:hover {
background: $$type;
color: #FFF;
}
}
}
I also tried to tinker with this mixin myself but I can't make it to work.
Help, please.

Using parent classes [duplicate]

This question already has an answer here:
SASS Replicating nested selector
(1 answer)
Closed 7 years ago.
Ive tried searching for an answer, but I feel like I'm asking the wrong questions.
I'm trying to create a "base parent" class that I can use to split up my rules nicely and across multiple files. The structure of the parent would be something like this:
.parent {
.child {
//some rules here
}
I then want to be able to import that parent and child class to help define further elements (using faux-syntax here)
#[custom class name]:
.parent {
//some rules
.child {
color: #000
}
Then, using my custom class name, I can specify this as the parent of another selector, like:
#[custom class name] {
.grand-child {
background-color: #fff;
}
}
This would generate out the following rule
.parent .child .grand-child {
color: #000;
background-color: #fff;
}
One way of doing this could be to create a mixin that uses the #content directive, like so:
#mixin selectors {
.parent {
.child {
#content;
}
}
}
Then, any time you want to nest something under .parent .child, you would write:
#include selectors {
.grand-child {
color: #000;
}
}
Which would result in the following CSS output:
.parent .child .grand-child {
color: #000;
}
You could always make use of the & selector.
If .grand-child is in another file, you could do something like this:
.grand-child{
.parent .child & {
color: #000;
}
}
this will compile to
.parent .child .grand-child{
color: #000;
}
Or are maybe you are also looking for the #extend possibility?
where you would add
.grand-child{
#extend .parent .child;
color: #000
}
This would get the style from .parent .child and add it to the grand-child, but only the styling, it will not change the selector above.

Resources