Reuse selector in SCSS as suffix [duplicate] - css

This question already has an answer here:
Append the parent selector to the end with Sass
(1 answer)
Closed 8 years ago.
How can I use the ampersand in SCSS to reuse the parent selector as suffix?
I came from LESS CSS and are doing my first project in SCSS right now. In LESS I could use the ampersand & to reference the parent selector at any point in a selector. I seems to me like this operator has some quirks in SCSS.
Example:
.grid {
/* grid styles */
ul& {
/* grid styles if this class was set to an UL element */
}
}
In LESS CSS this compiles to the following and this is what I need in most cases:
.grid {
/* grid styles */
}
ul.grid {
/* grid styles if this class was set to an UL element */
}
But in SCSS this throws an exception. There is another notation in SCSS looking like this:
.grid {
/* grid styles */
ul#{&} {
/* using SCSS escaping syntax*/
}
}
But this again gives me the unexpected result of:
.grid {
/* grid styles */
}
.grid ul.grid {
/* Uh SCCS, what happened now? */
}
Is there a way in SCSS to reuse the parent selector when it is not the first part of a selector?

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 (&)
.grid {
/* grid styles */
#at-root {
ul#{&} {
/* using SCSS escaping syntax*/
}
}
}
Output
.grid {
/* grid styles */
}
ul.grid {
/* using SCSS escaping syntax*/
}
Tested on sassmeister
Further information on SASS documentation page

Related

how to use `or` in css selector to select its child?

I want to select a child dom with below css selector:
.parentA .child{
}
.parentB .child{
}
how can I combine them into one selector? I have tried below but doesn't work:
.parentA,.parentB .child{
}
To answer your specific question, there is no OR in CSS. There is only AND and you use , (comma) for it.
Which is to say whenever you want to assign the same set of rules to more than one selector, you can separate each case using a comma:
.parentA .child,
.parentB .child {
/* rules here */
}
They apply separately, which is to say the above is equivalent with this non DRY (hence wrong) way of writing it:
.parentA .child {
/* rules here */
}
.parentB .child {
/* rules here */
}
To apply the DRY principle to selectors, if they share a pattern, you could use SASS (or other pre-processors) and nest selectors, like this:
.parentA, .parentB {
.child {
/* rules here */
}
}
But SASS is a CSS pre-processor which, when parsed, will result in the CSS mentioned initially.
Have you tried?:
.parentA > .child,
.parentB > .child{
}
In plain CSS you have to repeat the entire selector, .parentA .child, .parentB .child, but if you use LESS, Sass or other preprocessors, you can do:
.parentA, .parentB {
.child {
color: red;
}
}
Which will get compiled out to the former for you so you don't have to repeat yourself.

How to #import without including all CSS but just the #extends ones

I'm using stylus with bootstrap-stylus. This is my app.styl code
#import "../../node_modules/bootstrap-stylus/lib/bootstrap.styl";
section
#extend .row
After i run gulp, I notice that complete bootstrap css is included to the target app.css. I want to dynamically include just the .row rule using #extend. what I'm trying to get is this..
section { //.row rules
zoom: 1;
margin-left: -20px;
}
Is it possible? What am I missing? Is it possible with SASS?
AFAIK both stylus and sass do not support importing only certain selectors of a file. If you have control over the imported file, though, you could use SASS placeholder selectors instead of classes/ids. A placeholder selector is some sort of abstract selector which simply doesn't render anything by default.
/* _partial.scss */
%some-selector {
prop: value;
}
%another-selector {
prop: value;
}
/* main.scss */
#import 'partial';
.some-class {
#extend %some-selector;
}
results in the not-extended placeholder selectors being ignored (in this case %another-selector)
/* output.css */
.some-class {
prop: value;
}

Shortest possible selector for multiple elements

I want to apply one CSS rule for multiple selectors. like this:
.btn-group.pull-right.with_space .btn + .btn, .btn-group.pull-right.with_space i + i{
margin-left: 10px;
}
Now my question is, if there's a shorter way to do it. (since the parent elements are the same for both selectors, and the different is only in the last child).
To expand on my comment, if you choose to use a CSS pre-processor such as SASS or LESS, you can do nested selectors, like so:
/* SASS example */
.btn-group.pull-right.with_space {
i + i, .btn + .btn {
/* ... */
}
}
After compiling, the resulting CSS will be similar to what you had already written.
Sometimes, it might be better to add a common class to the elements that are sharing styles. So, in your .btn + .btn and i + i elements, add a class, such as btn_and_i, so you can target them with a single selector:
/* CSS example */
.btn_and_i {
/* ... */
}
If you're hell-bent on making this the "shortest" selector possible, then add a single-character class to the targeted elements, such as "a".
.a {
/* ... */
}

SCSS Mixin append ::before styling [duplicate]

This question already has answers here:
Sass .scss: Nesting and multiple classes?
(6 answers)
Closed 7 years ago.
#mixin item {
/* Element Styling */
::before {
/* Element ::Before Styling */
}
:hover::before {
/* Hover animation to be performed by the before when the main element is in a hover state */
}
}
.item {
#include item;
}
This SCSS example produces the following in CSS
.item {
/* Element Styling */
}
item ::before {
/* Element ::Before Styling */
}
item :hover::before {
/* Hover animation to be performed by the before when the main element is in a hover state */
}
Because of the nature of how mixins work, it adds a space between item and ::before which causes those to not be associated with each other in the manner that is expected. When this space is removed the element behaves as expected.
How would I go about using the same or similar method to achive the following output?
.item {
/* Element Styling */
}
item::before {
/* Element ::Before Styling */
}
item:hover::before {
/* Hover animation to be performed by the before when the main element is in a hover state */
}
If you can't tell what the difference is, item ::before is now item::before and so on...
Use the &:
Referencing Parent Selectors: &
Sometimes it’s useful to use a nested rule’s parent selector in other
ways than the default. [...] In these cases, you can explicitly
specify where the parent selector should be inserted using the &
character.
#mixin item {
/* Element Styling */
&::before {
/* Element ::Before Styling */
}
&:hover::before {
/* Hover animation to be performed by the before when the main element is in a hover state */
}
}
You're looking for the ampersand:
#mixin item {
/* Element Styling */
&::before {
/* Element ::Before Styling */
}
&:hover::before {
/* Hover animation to be performed by the before when the main element is in a hover state */
}
}
.item {
#include item;
}

Is it possible to traverse nested SASS selectors to the parent selector? [duplicate]

This question already has answers here:
Modifying the middle of a selector in Sass (adding/removing classes, etc.)
(2 answers)
Closed 7 years ago.
Just a question about the nesting of SASS selectors, so Im inside a nested span that I want to apply the :hover pseudo to so the opacity changes to 0, I also want to use this style though when the parent a tag gets the class is-active. Right now I would move the is-active class outside of the span and reapply the style but I'm wondering can you move up a level from within the nested style like traversing?
My example SASS:
.btn-lang {
// styles...
> span {
// styles...
&:hover { // i want to use this when btn-lang has class is-active
opacity: 0;
}
}
// right now I would add these styles here but seems there could be an easier method?
&.is-active {
> span {
&:hover {
opacity: 0;
}
}
}
}
You want to reuse two selectors (.btn-lang and span) in a single construction. This is not possible with SASS.
This situation is where extends really shine:
// Declaring a reusable extend that will not appear in CSS by itself.
%span-with-hover-on-active-element {
& > span {
/* styles for span under btn-lang */ }
&.is-active > span:hover {
opacity: 0; } }
.btn-lang {
/* styles for btn-lang */
// Apply the span-on-hover thing.
#extend %span-with-hover-on-active-element; }
It makes complicated code reuable and easier to read.
Resulting CSS:
.btn-lang > span {
/* styles for span under btn-lang */
}
.is-active.btn-lang > span:hover {
opacity: 0;
}
.btn-lang {
/* styles for btn-lang */
}

Resources