Why people use '@extend' in SCSS?
It helps you write DRY code quickly. @extend can be very useful when used properly.
It allows a selector to extend the styles of another selector, essentially providing a form of sub-classing. @extend works by combining selectors into a single comma-separated selector.
I.e. -
.A {
font-size: 1rem;
color:red;
}
.a{
@extend .A;
line-height: normal;
}
Which outputs:
.A,.a {
font-size: 1rem;
color:red;
}
.a{
line-height: normal;
}
How do I directly extend an SCSS parent selector?
I've found that it works when I move the .img
selector next to the :first-child
selector and change the selector to :first-selector, :first-selector .img
.
Here is the working code (NOTE: line 3
):
article.featured {
h4 { margin-bottom: 20px }
:first-child, :first-child .img {
height: 100%;
padding-top: 0;
padding-left: 0;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
:last-child {
padding-top: 0;
padding-right: 0
}
}
Which compiles to:
article.featured h4 {
margin-bottom: 20px;
}
article.featured :first-child, article.featured :first-child .img {
height: 100%;
padding-top: 0;
padding-left: 0;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
article.featured :last-child {
padding-top: 0;
padding-right: 0;
}
How extend placeholder selector in Sass using @use rule
After some investigation I've found out that it's incorrect syntax. Placeholder selectors have global scope during compiling, so we cannot write like this and we don't need to do it.
Sass: Extending nested selectors
You could use an extend-only selector (%
), and extend both ul a
and ul strong
from that:
a {
color: #09f;
text-decoration: none;
&:hover {
text-decoration: underline;
opacity: 0.6;
}
}
ul {
font-size: 0.85em;
a {
@extend %a;
}
strong {
@extend %a;
}
}
%a {
font-family: Georgia, Times, serif;
font-style: italic;
color: #0a3;
}
SCSS - override an @extend with another @extend
The rulesets in the output CSS are in the exact same place/order/sequence as they have been defined in SCSS, just that you only output the extended .size-2xl
and .size-3xl
rulesets. So you need to switch the places of this two rule definitions (see demo) or define the size rules as mixins and include them in the header rules (see demo). So, I think you must be confusing something about how @extend
works.
If you have something like that:
.class1 {
foo: bar1;
}
.class2 {
foo: bar2;
@extend .class1;
}
You will only add the selector .class2
to the already existing ruleset with the selector .class1
- so the output will look like this:
.class1, .class2 {
foo: bar1;
}
.class2 {
foo: bar2;
}
However, if we do not add any new properties to .class2
but just use @extend
:
.class1 {
foo: bar1;
}
.class2 {
@extend .class1;
}
The .class2
ruleset will not be printed to CSS and only the selector will be added to .class1
- hence the output:
.class1, .class2 {
foo: bar1;
}
This is more or less what you are doing, just adding the selectors .header1
and .header2
to the rules .size-2xl
and .size-3xl
, so the output will be in the same place/order in which these rules are defined in SCSS.
So what you get at the end in your example:
- you define the rulesets
.size-2xl
and.size-3xl
- you add the
.header1-small
selector to the rulesets.size-2xl
- you add the
.header1-small
to the.header1
selector and add both to ruleset.size-3xl
- ruleset
.size-2xl
(now after extending:.size-2xl, .header1-small
) gets printed to CSS - ruleset
.size-3xl
(now after extending:.size-3xl, .header1, .header1-small
) gets printed to CSS - ruleset
.header1
(also the extended one.header1, .header1-small
) doesn't get printed out as it does not have any defined properties - ruleset
.header1-small
doesn't get printed out as it does not have any defined properties
Another note: The same will happen also if you use placeholder selectors (%
) just that then it may be even more confusing, for example in .size-3xl, .header1, .header1-small
the .size-3xl
will be invisible, but in the CSS the whole thing will still get compiled in the place where the .size-3xl
rule was defined in SCSS.
SCSS extend a nested selector and override the nested rulesets
Sass has no functionality for "merging" duplicate selectors. You'll need to find another utility to do this after the CSS has been compiled.
The @extend
directive isn't just a way to use classes in place of mixins (similar to LESS style mixin calls). Why @extend
works the way it does becomes clear when you're extending normal classes instead of extend classes:
.block {
font-size:12px;
}
.foo {
@extend .block;
font-weight: bold;
}
Output:
.block, .foo {
font-size: 12px;
}
.foo {
font-weight: bold;
}
Using an extend class just suppresses the emission of the original class name.
Now that you've seen why @extend
works the way it does, do you still want what @extend
offers? If the answer is no, then you need to use a mixin:
@mixin block {
// styles
.title {
font-size: 12px;
@content;
}
}
.superblock {
@include block {
font-weight: bold;
}
}
Output:
.superblock .title {
font-size: 12px;
font-weight: bold;
}
Related Topics
Stop Link's :Before Content from Being Underlined by Rule Applied to the Link
Prevent Nginx from Serving CSS Files as Text/Plain
Webgrease Error on Styles.Render Call in _Layout.Cshtml in MVC4
Is There a CSS Selector for an Img Which Has Been Constrained by Max-Width or Max-Height
CSS - Position Absolute & Document Flow
What Do /Deep/ and: :Shadow Mean in a CSS Selector
Font Weights Differing in Webkit and Firefox
Does a Cache Buster on an Image Url in CSS Cause an Extra Request
Sass/Scss @Extend Rule Selectors
CSS Media Queries for Samsung S6
Import Less File Only for One Page