Simple Sass @extends and % issue

I'm probably doing something stupid, but I have the following code:
%list {
@include mixins.reset-list();

&-navigation {
display: none;

@media (min-width: tokens.$bp-main-nav) {
@include mixins.flex(row, center, center, 4);
}
}
}

.list {
@extend %list;

&-navigation {
@extend %list-navigation;
}
}
%list {
@include mixins.reset-list();

&-navigation {
display: none;

@media (min-width: tokens.$bp-main-nav) {
@include mixins.flex(row, center, center, 4);
}
}
}

.list {
@extend %list;

&-navigation {
@extend %list-navigation;
}
}
I want %list-navigation to extend the default styling from %list. From what I've read, this should work. I then have a class list-navigation that extends %list-navigation, but it's not inheriting the default styling, in this case the reset-list mixin. I have to correct class names in my HTML. Is this not how Sass works? It's not working for my other mixins either
31 Replies
b1mind
b1mindβ€’2y ago
best way is to always look at the output css
vince
vinceOPβ€’2y ago
You mean the actual stylesheet to check for the selectors? I've already checked devtools and it's not applying the styling
b1mind
b1mindβ€’2y ago
yea the .css output Its been awhile but are you supposed to be mixing these two? I've only extended classes so
vince
vinceOPβ€’2y ago
I'm following this article: https://www.smashingmagazine.com/2015/05/extending-in-sass-without-mess/ which shows to do this, not really sure the exact reason why
b1mind
b1mindβ€’2y ago
and from what I remember it would not extend the nested modifiers with it πŸ€” 2015 article xD
vince
vinceOPβ€’2y ago
πŸ˜‚ Yea you got a point I don't know, it looks like it should work though
b1mind
b1mindβ€’2y ago
vince
vinceOPβ€’2y ago
It's neater than writing out separate classes, if it actually works and I'm not being stupid
b1mind
b1mindβ€’2y ago
Extends are resolved after the rest of your stylesheet is compiled. In particular, it happens after parent selectors are resolved. This means that if you @extend .error, it won’t affect the inner selector in .error { &__icon { ... } }. It also means that parent selectors in SassScript can’t see the results of extend.
mmm yea not sure cause docs show it too https://sass-lang.com/documentation/style-rules/placeholder-selectors but again its not going to extend the nested like that
%list {
@include mixins.reset-list();
}

%list-navigation {
display: none;

@media (min-width: tokens.$bp-main-nav) {
@include mixins.flex(row, center, center, 4);
}
}
%list {
@include mixins.reset-list();
}

%list-navigation {
display: none;

@media (min-width: tokens.$bp-main-nav) {
@include mixins.flex(row, center, center, 4);
}
}
?
vince
vinceOPβ€’2y ago
Sorry, I was trying to make sense of what you linked me was saying, what you have here definitely works I was just hoping there was a nicer way to write it (like in the article I mentioned) I guess there isn't 😩 Actually, would that extend the base %list styling though? Or do I have to @extend %list inside %list-navigation?
b1mind
b1mindβ€’2y ago
You really don't need placeholders if you were going to have the same class and not reuse the placeholder though.
vince
vinceOPβ€’2y ago
Yea that is a fair point lol
b1mind
b1mindβ€’2y ago
mm yea idk check the output xD I think it should πŸ€”
vince
vinceOPβ€’2y ago
Let's see So I ended up doing:
%list {
@include mixins.reset-list();
}

.list {
@extend %list;

&-navigation {
display: none;

@media (min-width: tokens.$bp-main-nav) {
@include mixins.flex(row, center, center, 4);
}
}
}
%list {
@include mixins.reset-list();
}

.list {
@extend %list;

&-navigation {
display: none;

@media (min-width: tokens.$bp-main-nav) {
@include mixins.flex(row, center, center, 4);
}
}
}
Makes more sense, like you said no point in using % if I'm not reusing
b1mind
b1mindβ€’2y ago
James Steinbach
When I Use (and Don’t Use) Sass Extend β€’ James Steinbach
Front-end architect. Speaker & writer. React & Vue, Sass & CSS, performance & accessibility.
vince
vinceOPβ€’2y ago
Oh wait I'm being stupid, haha
b1mind
b1mindβ€’2y ago
Here they are saying to only extend placeholders so πŸ€·β€β™‚οΈ
vince
vinceOPβ€’2y ago
Awesome, let me check this out
b1mind
b1mindβ€’2y ago
Dave Redfern
Use Sass placeholders and extend wisely – a cautionary tale
Extends are probably one of the biggest selling points to use Sass. They allow you to say this selector has the same styling as thisΒ other element ...
b1mind
b1mindβ€’2y ago
Another good read All of the Sass info I have saved* is pretty old too seems like xD I've been holding off to take Kevins Sass course, and now I don't even know if I will cause I don't use it enough anymore >.>;
vince
vinceOPβ€’2y ago
You gave me a lot of great resources, thanks b1! I'll read through all this and come back with my findings πŸ€” Ah I see, I didn't know that. Whenever you use @extend, it pretty much copies the selectors everywhere the extended class is Which is why you use placeholders, so that doesn't happen So I ended up having to go with
%list {
@include mixins.reset-list();
}

%list-navigation {
@extend %list;
display: none;

@media (min-width: tokens.$bp-main-nav) {
@include mixins.flex(row, center, center, 4);
}
}

.list {
@extend %list;

&-navigation {
@extend %list-navigation;
}
}
%list {
@include mixins.reset-list();
}

%list-navigation {
@extend %list;
display: none;

@media (min-width: tokens.$bp-main-nav) {
@include mixins.flex(row, center, center, 4);
}
}

.list {
@extend %list;

&-navigation {
@extend %list-navigation;
}
}
I literally have no idea why I couldn't do what I posted earlier or something like
%list {
@include mixins.reset-list();
}

.list {
@extend %list;

&-navigation {
display: none;

@media (min-width: tokens.$bp-main-nav) {
@include mixins.flex(row, center, center, 4);
}
}
}
%list {
@include mixins.reset-list();
}

.list {
@extend %list;

&-navigation {
display: none;

@media (min-width: tokens.$bp-main-nav) {
@include mixins.flex(row, center, center, 4);
}
}
}
I checked my compiled css and it just would not apply the base styling from %list to .list-navigation This can't be an @extends issue at this point. I even tried:
.list {
border: 1px solid red;

&-navigation {
display: none;

@media (min-width: tokens.$bp-main-nav) {
@include mixins.flex(row, center, center, 4);
}
}
}
.list {
border: 1px solid red;

&-navigation {
display: none;

@media (min-width: tokens.$bp-main-nav) {
@include mixins.flex(row, center, center, 4);
}
}
}
And it compiles to:
.list {
border: 1px solid red;
}
.list-navigation {
display: none;
}
@media (min-width: 40.625rem) {
.list-navigation {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
gap: 4rem;
flex-wrap: wrap;
}
}
.list {
border: 1px solid red;
}
.list-navigation {
display: none;
}
@media (min-width: 40.625rem) {
.list-navigation {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
gap: 4rem;
flex-wrap: wrap;
}
}
I made a minimal reproduceable example:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="x.css" />
<title>Document</title>
</head>
<body>
<h1>Hello world</h1>
<a href="" class="link-navigation">aaaa</a>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="x.css" />
<title>Document</title>
</head>
<body>
<h1>Hello world</h1>
<a href="" class="link-navigation">aaaa</a>
</body>
</html>
Sass:
.link {
border: 1px solid red;

&-navigation {
color: red;
}
}
.link {
border: 1px solid red;

&-navigation {
color: red;
}
}
Compiled css:
.link {
border: 1px solid red;
}
.link-navigation {
color: red;
}
.link {
border: 1px solid red;
}
.link-navigation {
color: red;
}
b1mind
b1mindβ€’2y ago
looks correct
vince
vinceOPβ€’2y ago
Shouldn't .link-navigation inherit .link properties?
b1mind
b1mindβ€’2y ago
nope not how nesting works, you are still relying on inheritance at that point you would want like
.link {
border: 1px solid red;

&-navigation {
@extends .link;
color: red;
}
}
.link {
border: 1px solid red;

&-navigation {
@extends .link;
color: red;
}
}
vince
vinceOPβ€’2y ago
Ah dang, I thought that's how it worked that whole time... πŸ˜‚
b1mind
b1mindβ€’2y ago
that is why looking at the output is good
vince
vinceOPβ€’2y ago
So I would have to explicitly @extends then? This works:
%link {
border: 1px solid red;
}

.link {
@extend %link;

&-navigation {
@extend %link;
color: red;
}
}
%link {
border: 1px solid red;
}

.link {
@extend %link;

&-navigation {
@extend %link;
color: red;
}
}
b1mind
b1mindβ€’2y ago
.someClass {
& p {
color: blue;
}
}

.someClass p {
color: blue;
}
.someClass {
& p {
color: blue;
}
}

.someClass p {
color: blue;
}
CSS nesting will work the same way. yea and makes sense to use a placeholder too
vince
vinceOPβ€’2y ago
Thanks again b1! I've learned a lot today (and had a lot of headache πŸ˜‚ ). Now I need to read up on inheritance properly so this doesn't happen again haha
b1mind
b1mindβ€’2y ago
yea np thanks for helping me learn how to use extends properly πŸ˜„ We learned together today 🀘
vince
vinceOPβ€’2y ago
πŸ₯³
Want results from more Discord servers?
Add your server