Sass Parent Selector - sass

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.

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 { ... }

#mixin format is it ok to not have ()?

Learning about #mixin and I came across this code. How come the hover-not-disabled on the first line is not followed by () and is it ok to do this? Thanks in advance!
#mixin hover-not-disabled {
&:not([disabled]):hover {
#content;
}
}
.button {
border: 1px solid black;
#include hover-not-disabled {
border-color: blue;
}
}
Its fine. It won't cause any errors, since (…) is meant to contain the arguments which when using a #mixin are usually needed, however in this case the editor wants to pass the mixin into mutliple elements and then edit the #content.
From a subjective point of view, I'd recommned to always include the () for the sake of consistency even if they would be empty, so when quickly scanning the code, nothings seems odd.
So this would be my approach, but generally spoken, it's totally fine to leave them in such cases.
#mixin hover-not-disabled() {…}
#include hover-not-disabled();

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;
}

SCSS generate prefix for class

I want to be able to generate .pre-class and .sub-class for any .class.
e.g. .title, .pre-title and .sub-title or .heading, .pre-heading, .sub-heading
I can do this via passing class variable (example below), is there any cleaner/straightforward way to achieve prefixes for the class?
$className: heading;
.section {
.#{$className} {
color: pink;
}
.sub-#{$className} {
color: red;
}
.pre-#{$className} {
color: green;
}
}
[class^="sub-"] — starts with "status-" (obviously).
[class*=" sub-"] — contains the substring "status-" occurring directly after a space character. Class names are separated by whitespace per the HTML spec, hence the significant space character. This checks any other classes after the first if multiple classes are specified, and adds a bonus of checking the first class in case the attribute value is space-padded (which can happen with some applications that output class attributes dynamically).
Although the best way and my recommendation to reduce code/cleaning is what you mention. Definitely.
Prefix SCSS here
You could use suffixes instead of prefixes.
It is shorter but less relevant.
$className: heading;
.section .#{$className} {
color: pink;
&-sub {
color: red;
}
&-pre {
color: green;
}
}

Using interpolation for calling compass sprite mixins

the problem that i have with this mixing is that i can't interpolation for calling different sprite mixins that compass provides.
I want to be able to have this in one place, create the sprites in different scss and them just include this shared mixing and use it.
So far seems that Sass doesn't allow me to do that. Maybe i just have a crazy and bad way of doing things ( i'm no designer really and i learn about sass a few months ago ).
Thanks for your time.
#mixin icon-button($width, $height, $icon-bg-color, $icon, $sprite-name){
.icon-base{
width: $width;
height: $height;
background-color: $icon-bg-color;
.icon{
$icon-height: #{$sprite-name}-sprite-height(#{$icon});
$icon-width: #{$sprite-name}-sprite-width(#{$icon});
#include #{$sprite-name}-sprite(#{$icon});
width: $icon-width;
height: $icon-height;
position: relative;
left: ($width - $icon-width)/2;
top: ($height - $icon-height)/2;
}
}
}
The #{something} is a ruby-way of interpolation. Compass framework uses ruby compiler to make css from scss/sass. Interpolation is just the way to insert some value (of a variable) into a string, like this: puts "I want to say #{smth}" will print "I want to say something" into irb console if you previously defined the smth = "something" variable. You also may notice the difference between ' and ". So, sometimes you would like to use standalone functions in compass like this:
headings(all) {
color: $color;
}
to compile it into css:
h1, h2, h3, h4, h5, h6 {
color: #2a2a2a;
}
Instead, it throws an error. So, to do this you need to interpolate the call of the function:
#{headings(all)} {
color: $color;
}
And it runs. But if you try to make interpolation with variables:
$color: #abc;
$color2: "#abc";
#mixin some($color) {
color: #{$color};
}
will also throw an error because in this case interpolation outputs a string "#abc".
Try to avoid using ruby syntax in compass if it is possible for cleaner style.
Note: I would appreciate if someone can explain with better compilation details because i'm not a rubyist, i'm pythonist.
Update
Check this code:
#mixin setFonting($from, $to, $size) {
$curr: $from;
$to: $to + 3;
#while $curr != $to {
h#{$curr} {
font-size: $size;
}
$curr: $curr + 1;
$size: $size + 2;
}
}
#include setFonting(1, 3, 20px);
It compiles to :
h1 {font-size: 20px;} h2 {font-size: 22px;} h3 {font-size: 24px;} h4 {font-size: 26px;} h5 {font-size: 28px;}
So as you see, #{} interpolation in compass works outside curly brackets used to define statements for selector.

Resources