How to select nth-child in SASS within a nested selectors - css

Is there a way not to repeat the clip-item class when using nth-child in a nested SCSS? The output should be in the CSS below.
CSS
.clip-item .group-left {
padding: 0;
}
.clip-item .group-left:nth-child(2n+1) {
background: blue;
}
.clip-item .group-left:nth-child(2n+2) {
background: gray;
}
.clip-item .group-right {
padding: 0;
}
.clip-item .group-right:nth-child(2n+1) {
background: blue;
}
.clip-item .group-right:nth-child(2n+2) {
background: gray;
}
I was trying to do it like below. Even though t's working, I don't think it's the right way / clean way.
SCSS
.group-left {
.clip-item & {
padding: 0;
}
.clip-item:nth-child(2n+1) & {
background: blue;
}
.clip-item:nth-child(2n+2) & {
background: gray;
}
}
.group-right {
.clip-item & {
padding: 0;
}
.clip-item:nth-child(2n+1) & {
background: blue;
}
.clip-item:nth-child(2n+2) & {
background: gray;
}
}
I'm also using the .group-left and .group-right classes in some content, that's why I used it as a parent selector.
EDIT:-
Each group wrappers are wrapped in a clip-item div. Below is my markup:-
<div class="clip-item">
<div class="group-left">
<div class="group-right">
</div>
<div class="clip-item">
<div class="group-left">
<div class="group-right">
</div>

If you need to group the selectors in this way - I recommend using the #at-root directive.
The #at-root directive causes one or more rules to be emitted at the
root of the document, rather than being nested beneath their parent
selectors.
.group-left {
.clip-item & {
padding: 0;
}
#at-root .clip-item &:nth-child(2n+1) {
background: blue;
}
#at-root .clip-item &:nth-child(2n+2) {
background: gray;
}
}
.group-right {
.clip-item & {
padding: 0;
}
#at-root .clip-item &:nth-child(2n+1) {
background: blue;
}
#at-root .clip-item &:nth-child(2n+2) {
background: gray;
}
}
Codepen demo (View compiled CSS)
Also, this CSS-tricks post may help:
The & doesn't allow you to selectively traverse up your nested
selector tree to a certain place and only use a small portion of the
compiled parent selector that you want to use.
By the way:
Even though it's working, I don't think it's the right way
Well actually, your SCSS is not currently producing the requested CSS.

Related

Scss specific style for multiple classes using "&"

I've got this Scss:
.top {
background-color: red;
&--checked {
background-color: yellow;
}
&--completed {
background-color: green;
}
}
Which compiles correctly to this:
.top {
background-color: red;
}
.top--checked {
background-color: yellow;
}
.top--completed {
background-color: green;
}
This is probably simple, but I'm trying to add an additional style for elements using both "top--checked" and "top--completed", but nested within top.
Something like this (in CSS):
.top--checked.top--completed {
background-color: blue;
}
I'm just not sure on how to achieve this, as chaining ampersands doesn't seem to produce the desired effect.
I think the best you can do would be something like this:
&--checked#{&}--completed {
background: blue;
}

SCSS selection with "&". Advanced trick

I have a button class .btn and want to select only when it is with a link. What to add to a so I will get a.btn using SCSS and my code bellow?
SCSS:
.btn {
background: red;
a {
background: blue;
}
}
I want to get this in css:
.btn {
background: red;
}
a.btn {
background: blue;
}
Logical will be to do this a&. But it gives an error. a & and & a is giving a different result.
I know that this can be done with #at-root a#{&} but it is too ugly =) Is there a pretty way?
.btn {
background: red;
#at-root a#{&} {
background: blue;
}
}
This should work:
a {
&.btn {
background: blue;
}
}
.btn {
background: red;
}
You can't write that in a single block. In case if that's what you are trying to do.
Since .btn& is not a valid scss, it seems that #at-root a#{&} is your only option.

How to target the parent class from nested classes in SASS

Is there a way to achieve something like below in SASS without indicating .group-left twice?
.wrapper .group-left {
background-color: blue;
}
.wrapper-child:nth-child(2n+2) .group-left {
background: red;
}
I was trying to put ampersand after .group-left, but doesn't work. So, I have to re-select .group-left. Below is my current code.
.wrapper {
&:nth-child(2n+2) .group-left {
background-color: red;
}
.group-left {
background-color: blue;
}
}
Please advise. Thank you.
You could use parent selector and invert your nesting in sass
.group-left {
.wrapper & {
background-color: blue;
}
.wrapper-child:nth-child(2n+2) & {
background: red;
}
}
Try this.
.wrapper {
.group-left {
background-color: blue;
}
}
.wrapper-child {
&:nth-child(2n+2) {
.group-left {
background: red;
}
}
}

Sass to css output

I think this is the way to do it but my css output is not what I was expecting:
SOURCE CODE
This is my scss file:
footer.page-footer
{
margin-top: 0;
&,
nav
{
background-color: $blue;
}
}
This is the css output:
footer.page-footer
{
margin-top: 0;
}
footer.page-footer,
footer.page-footer nav
{
background-color: #50a4b1;
}
How can I make the second outputted css's selector be simply footer.page-footer, nav instead of footer.page-footer, footer.page-footer nav?
You can use the #at-root directive to produce a rule that is generated outside its definition scope but that retains the value of its parent (&)
footer.page-footer {
margin-top: 0;
#at-root {
#{&},
nav {
background-color: blue;
}
}
}
Output:
footer.page-footer {
margin-top: 0;
}
footer.page-footer,
nav {
background-color: blue;
}
<p class="sassmeister" data-gist-id="93b3b22a2888f2f5f86b" data-height="480" data-theme="tomorrow">Play with this gist on SassMeister.</p><script src="http://cdn.sassmeister.com/js/embed.js" async></script>
Sassmeister

in SASS, post selector ampersand doesnt work when used in a nested structure

my markup is let's say:
<div class="container marker">
<div class="parent">
<div class="child">
content
</div>
</div>
</div>
and my scss would be
.container {
.parent {
.child {
.marker & {
background: red;
}
}
}
}
As long as I put the child styling nested in parent's with the marker class, the ampersand (&) rule doesn't engage.
but if i write:
.parent {
.child {
.marker & {
background: red;
}
}
}
everything seems fine. why? what am I missing?
example in CodePen:
http://codepen.io/anon/pen/GgRvOV
Because the output of your sass would be:
.marker .container .parent .child {
background: red;
}
Because you are telling the sass to output .marker & which is saying this is the parent of this chain, so .container is being treat as the first child of .marker.
You need to do:
.parent {
.child {
.container.marker & {
background: red;
}
}
}
Which will output the vanilla CSS:
.container.marker .parent .child {
background: red;
}
A great tool to help you understand how you sass outputs is http://sassmeister.com/
Other alternative is by using variable(s) and SASS’s Interpolation Syntax, using this will keep your original nesting
.container {
$c: &; // store parent into variable
.parent {
.child {
#{$c}.marker & {
background: red;
}
}
}
}
output:
.container.marker .container .parent .child {
background: red;
}

Resources