Merging selector #extend issue - css

I have a problem about "#extend" directive in SCSS.
.header {
.introduction-group {
text-align: center;
color: $white;
width: 70%;
}
.about {
&__description-group {
#extend .introduction-group;
This code block does not work. However,
.header {
&__introduction-group {
text-align: center;
color: $white;
width: 70%;
}
.about {
&__description-group {
#extend .header__introduction-group;
Second one works. Why?
Thank you.

As mentioned here nested classes won't be applied with #extend. Your second code block targets the specified class including the parent prefix. The first code block doesn't, it only targets the nested class.
I made a small codepen demo to illustrate the problem in a simple way. Make sure you checkout the Sass docs for a more comprehensive explanation!
<h1 class="wrong">Test style gone wrong</h1>
<h1 class="right">Test style gone right</h1>
.test {
.nested {
color: red;
}
&-nested {
color: red;
}
}
.wrong {
#extend .test;
#extend .nested;
}
.right {
#extend .test-nested;
}

Related

style priority not working as expected in SASS

I have the following scss styles defined in a separate file
.radio-button-focused {
background-color: $PURPLE;
text-align: left;
opacity: 1;
width: px-to-rem(1248px);
margin-bottom: px-to-rem(15px);
#include truncate;
}
.radio-button {
background-color: $BLACK;
text-align: left;
opacity: 1;
width: px-to-rem(1248px);
margin-bottom: px-to-rem(15px);
#include truncate;
}
Both of them are being applied to a button
But the problem is that radio button is overwritting the color of radio-button-focused
I understand that I could use !important , or just use one of them instead of using them both at the same time. But if I was forced to use both, can something else be done to fix this?
The literal order in the CSS file matters. If two rules have the same specificity, the last one is applied. Move .radio-button before .radio-button-focused. You could also make your focused selector more specific. .radio-button.radio-button-focused for example.
Here's class B before A as an example.
.b
{
color: red;
}
.a
{
color: blue;
}
<div class="a b">Hi</div>
And here's A before B.
.a
{
color: blue;
}
.b
{
color: red;
}
<div class="a b">Hi</div>

LESS - using BEM selector with extra class on parent to deviate

I have some markup that looks about like this -
<div class="card">
<div class="card__icon">Icon</div>
<div class="card__text">Text</div>
</div>
Which I am styling with a little LESS like so -
.card {
&__icon {
font-size: 1.75em;
#media (min-width: 992px) {
font-size: 2em;
}
}
&__text {
font-size: 1em;
}
}
This works great - however the parent is getting toggled a class .current on it and I was trying to change one of the childrens styles using the same methods, but could not seem to get it working. I was trying this -
.card {
&__icon {
font-size: 1.75em;
#media (min-width: 992px) {
font-size: 2em;
}
}
&__text {
font-size: 1em;
}
&.current {
// this is not working
&__text {
color: red;
}
}
}
I can change the &__text inside the &.current to .card__text and it works fine - however I was wondering if there was a way I could keep the &__text syntax inside the &.current with using LESS. Thanks!
According to the documentation, the parent selector & expands to the whole parent nested rule, taking each nested rule parent as is and inserting it in place of `&, so in your case
.card {
&.current {
&__text {
color: red;
}
}
}
compiles to
.card.current__text {
color: red;
}
which is not what we want, because class current__text does not exist. To avoid that you may rearrange the class selectors in your less rules like so:
.card {
.current & {
&__text {
color: red;
}
}
}
which compiles to:
.current .card__text {
color: red;
}
A working example can be found in this codepen

Bootstrap classes inside a defined class

Is there a way to put made classes inside a class?
e.g.
.my-upper-class{ .hidden-md, .hidden-sm, .hidden-lg}
Not with plain CSS, but with Sass, like so—
.hidden-sm {
background: red;
}
.hidden-md {
color: blue;
}
.hidden-lg {
font-size: 1em;
}
.my-upper-class {
#extend .hidden-sm;
#extend .hidden-md;
#extend .hidden-lg;
}
which outputs the final CSS as below, which is pretty much what you are looking for.
.hidden-sm, .my-upper-class {
background: red;
}
.hidden-md, .my-upper-class {
color: blue;
}
.hidden-lg, .my-upper-class {
font-size: 1em;
}

How to override mixin in Less

I want to override a property of the .btn mixin. I tried following code.
.btn() {
text-align: center;
}
.btn() {
text-align:left;
}
.button{
.btn;
}
Less generates following code according to above snippet.
.button {
text-align: center;
text-align: left;
}
Of course I can try to use "!important" tag, but I don't want this. I am expecting following output.
.button {
text-align: left;
}
How can I do it?

SASS, when to extend?

I'm currently working on a team that uses SASS. I see that we are extending styles that are very simple and to me I don't see the benefit of doing this. Am I missing something?
Here are some examples of a _Common.scss that is imported and used throughout other sass files:
.visibility-hidden{visibility: hidden;}
.display-inline { display: inline; }
.display-inline-block { display: inline-block; }
.display-block { display: block; }
.display-none { display: none; }
.display-box { display: box; }
.float-left { float: left; }
.float-right { float: right; }
.clear-both { clear: both; }
.width-percent-100 { width: 100%; }
.width-percent-65 { width: 65%; }
.width-percent-50 { width: 50%; }
.width-percent-45 { width: 45%; }
.width-percent-40 { width: 40%; }
.width-percent-33 { width: 33%; }
.width-percent-30 { width: 30%; }
.width-percent-20 { width: 20%; }
.height-percent-100 { height: 100%; }
.cursor-pointer { cursor: pointer; }
.underline { text-decoration: underline; }
.text-decoration-none { text-decoration: none; }
.bold { font-weight: bold; }
.font-weight-normal { font-weight: normal; }
.text-align-center { text-align: center; }
.text-align-left { text-align: left; }
.text-align-right { text-align: right; }
.font-10 { font-size: 10px; }
.font-11 { font-size: 11px; }
.font-12 { font-size: 12px; }
.font-13 { font-size: 13px; }
.font-14 { font-size: 14px; }
.font-15 { font-size: 15px; }
.font-16 { font-size: 16px; }
.font-17 { font-size: 17px; }
.font-18 { font-size: 18px; }
.font-percent-65 { font-size: 65%; }
.font-percent-80 { font-size: 80%; }
.font-percent-90 { font-size: 90%; }
.font-percent-100 { font-size: 100%; }
.font-percent-110 { font-size: 110%; }
.font-percent-120 { font-size: 120%; }
.font-percent-130 { font-size: 130%; }
.font-percent-140 { font-size: 140%; }
.font-percent-150 { font-size: 150%; }
.font-percent-160 { font-size: 160%; }
.font-percent-170 { font-size: 170%; }
.font-percent-180 { font-size: 180%; }
Example:
#CategoriesContainer
{
ul{
li{
&:first-child{
#extend .font-11;
}
a
{
#extend .font-11;
#extend .text-decoration-none;
}
}
}
}
You should only use extend when you have a certain attribute set that will be used multiple times. The sheer stupidy of extending a class with a class with one attribute that has the unit value worked into the name of it is incomprehensible.
A better example for a reason to extend can be found in the reference guide
Say we have 2 classes
.error {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
border-width: 3px;
}
.error is a general no interesting style but a serious error should be really clear.
.seriousError is created to thicken the line, the only problem is that now we have to use both classes in the html to combine the styles.
Because we're lazy and just want to use one class and not duplicate code that might be changed in the future we can extend .seriousError with .error
.seriousError {
#extend .error;
border-width: 3px;
}
Now we didn't duplicate the code in our sass file but did get the right styles on the page.
Check out the reference guide for more/better examples.
Just please for the sake of kittens stop extending classes with one attribute classes. And don't implicitly state the value/attributes in the selector, thats not very semantic.
You, and your team, should read this post which explains a few problems with the aproach you take here vs semantic code. Couldn't find a better tuned post this quick.
You aren't missing anything, this is just bloated code in poor form and not a great way to extend classes.
There is maybe one (bad) reason I can imagine why this would be used. If for example .font-10 needs to be .7em instead of 10px, it can be easily changed - but then you've just defeated the point of naming the class "font10". Something like small-font would even make more sense in that case (and I'm not suggesting you use that either).
I won't discuss the merits of semantic class names and the folly of presentational ones (especially as literal as these are), but I will suggest that this is a very narrow use of extending classes. With a 1:1 mapping of class name to property/value, you've practically defeated the purpose of #extend, which is supposed to make you write less CSS.
Better example of what to use #extend for:
.media {
padding:1em;
border-color:blue;
background-color:red;
clear:left;
}
.my-media {
#extend .media;
background-color:green;
}
Atomic CSS
The technique of very simple CSS rules does have a bit of precedent - at Yahoo! they call it Atomic CSS. Thierry Koblentz argues in this Smashing Magazine article for using the simple classes directly in your markup, similar to inline styling. This can be helpful on very large projects across multiple web properties, where styles are not consistent. Base styles for OOCSS components can't be reused as much in such a situation, causing you to have to write many more lines of extension classes or overrides.
The downside is, of course, as Wesley mentioned, that it is much more difficult to make changes across your entire project's styles, such as updating the text size of a specific selector.
I've been playing around with a variant of this technique recently in a fairly large project, where styles can often be one-off. In an effort to avoid the I try to avoid putting hard values directly in the selectors. For instance, the following css (example fiddle):
_colors.scss
.text-white {
color: $white;
}
.blue {
#extend .text-white;
background: $blue;
}
_effects.scss
.circle {
width: 50px;
height: 50px;
border-radius: 50%;
text-align: center;
line-height: 50px;
font-size: 40px;
}
.matted {
border: 4px solid $white;
}
.shadow {
#include box-shadow(0 1px 4px 1px rgba($black, 0.25));
}
HTML:
<div class="blue matted circle shadow">?</div>
Specificity issues
One last thing to keep in mind if you decide to use this technique - it can cause specificity problems if you're extending base-level classes that use the same CSS properties. For instance, in the following example (fiddle), how would your border-radius appear? You wanted the top to be squared off (no border-radius) but this isn't happening, because the .circle class is further down in your css and just as specific (single class) as the other effects. This is a bit of a contrived example, but if you reuse CSS properties across your atomic selectors, this can be a real problem.
_colors.scss
.text-white {
color: white;
}
.blue {
#extend .text-white;
background: royalblue;
}
_effects.scss
.squared-top {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.rounded {
border-radius: 10px;
}
.circle {
width: 50px;
height: 50px;
border-radius: 50%;
}
HTML:
<span class="circle blue rounded squared-top"></span>
If you do it that way you can also use it directly in the HTML - so it looks like they took the OOCSS path and because it's already in the CSS you can now also extend to it. Very flexible but it could also turn very messy.
Extend option is used poorly here. It should be used for extending classes with more content and in that case extend can be very helpful.You can find more about extend and its options here.

Resources