I've a generic class like:
button {
color: dimgray;
& > * {
display: inline-block;
vertical-align: middle;
}
}
So i'm trying a simple extend:
button.new {
&:extend(button all);
color: green;
&:hover {
color: darkgreen;
}
}
Why i've a .new.new select in extended class?
button,
button.new {
color: dimgray;
}
button > *,
button.new > * {
display: inline-block;
vertical-align: middle;
}
button.new {
color: green;
}
button.new:hover,
button.new.new:hover {
color: darkgreen;
}
This is not correct i think, i'm using last version of less (js library)
button.new.new:hover
Related
I have this scss:
.nav {
&__item {
color: black;
}
}
This compiles to:
.nav__item
Is it possible to modify the above sccs so that it compiles with a tag in front of it, like the following?
a.nav__item
OR
li.nav_item
Here is one way using #at-root. This way avoids having to declare &__item twice.
.nav {
&__item {
color: black;
#at-root {
ul#{&} {
display: block;
}
}
}
}
Complies to
.nav__item {
color: black;
}
ul.nav__item {
display: block;
}
Try this:
.nav {
a#{&}__item {
color: black;
}
}
Output
.nav a.nav__item {
color: black;
}
Even though this is possible using
.nav {
a#{&}__item {
color: black;
}
}
I would highly encourage you to write it like this
a,
li {
&.nav {
&__item {
color: black;
}
}
}
I would like to contain all relevant styles for a selector within a single code block, so that it can be easily referenced.
In my application, a selectors effective styles will be altered dramatically depending on the context in which it sits. For instance, let's assume this CSS:
.container.theme-dark .message
{
font-size: 16px;
background-color: black;
color: white;
}
.container.theme-light .message
{
font-size: 16px;
background-color: white;
color: black;
}
Then, imagine I have the following HTML:
<div>
<div class="container theme-dark">
<div class="message">Hello World</div>
</div>
<div class="container theme-light">
<div class="message">Hello World</div>
</div>
</div>
Right now with SCSS, I would create the relevant CSS like this:
.container
{
&.theme-dark
{
.message
{
background-color: black;
color: white;
}
}
&.theme-light
{
.message
{
background-color: white;
color: black;
}
}
.message
{
font-size: 16px;
}
}
I want to be able to generate that CSS using SCSS, with all of the relevant information for the .message element in one place. For instance (using a made-up $ operator that would do what I'm trying to accomplish):
.container
{
.message
{
font-size: 16px;
$.theme-light
{
background-color: white;
color: black;
}
$.theme-dark
{
background-color: black;
color: white;
}
}
}
Any ideas?
I'm thinking this might work, and is like what you're saying? (It would help me currently if you labeled each example as "Ideal CSS output", "Current SCSS, too many .message blocks", and "Ideal SCSS format")
.container
{
#at-root .message
{
font-size: 16px;
.theme-light &
{
background-color: white;
color: black;
}
.theme-dark &
{
background-color: black;
color: white;
}
}
}
With the #at-root there, it will generate .theme-light .message, which might be too permissive for some usages, so not the ideal solution...
https://codepen.io/anon/pen/ZMxjEq
Basically & gets replaced with the full tree-path, so .container .message, which without #at-root, will generate .theme-light .container .message, which does not work with the structure. Perhaps also consider this, which makes a reasonable compromise I would say:
.container
{
.message
{
font-size: 16px;
}
#at-root .message
{
.theme-dark
{
...
}
.theme-light
{
...
}
}
}
It's apparently a kind of hacky solution, but apparently works
This page might have some better guidance as well
This organization can be achieved if you use sass programatically:
$themes: light dark;
.container {
#for $i from 1 through length($themes) {
&.theme-#{nth($themes,$i)} {
.message {
font-size: 16px;
#if nth($themes,$i) == light {
background-color: white;
color: black;
} #else if nth($themes,$i) == dark {
background-color: black;
color: white;
}
}
}
}
}
This generates:
.container.theme-light .message {
font-size: 16px;
background-color: white;
color: black;
}
.container.theme-dark .message {
font-size: 16px;
background-color: black;
color: white;
}
The nested looping automatically groups the details at each level in the same block of code. This also scales to multiple levels of nesting. The critical point is that at inner loops you can reference the selectors of outer loops.
I eventually found this GitHub:
https://github.com/imkremen/sass-parent-append/blob/master/parrent-append.scss
Which I have adapted into this solution:
#function str-to-list($string, $separator: ' ', $startAt: 1)
{
$workStr: str-slice($string, $startAt);
$list: ();
$indexOfFirstSpace: str-index($workStr, $separator);
#if ($indexOfFirstSpace == null)
{
$list: ($workStr);
}
#else
{
$list: (str-slice($workStr, 1, $indexOfFirstSpace - 1));
$list: join($list, str-to-list($workStr, $startAt: $indexOfFirstSpace + 1));
}
#return $list;
}
#function getBase($appendix)
{
$parentSelector: str-to-list(#{&});
$pos: (length($parentSelector) - 1);
$selector: set-nth($parentSelector, $pos, nth($parentSelector, $pos) + $appendix);
#return $selector;
}
#mixin base($appendix)
{
#at-root #{getBase($appendix)}
{
#content;
}
}
Which I can then use like this:
.container
{
.message
{
font-size: 16px;
}
#include base(".theme-light")
{
background-color: white;
color: black;
}
#include base(".theme-dark")
{
background-color: black;
color: white;
}
}
which compiles into this:
.container .message
{
font-size: 16px;
}
.container.theme-light .message
{
background-color: white;
color: black;
}
.container.theme-dark .message
{
background-color: black;
color: white;
}
Hi can you check please following code? I want define some styles for class, and next apply same styles for another class. I've used inheritance for that but styles from parent aren't used:
.parent-item {
&:not(:last-child) {
margin-right: 20px;
}
}
.child-item {
&:extend(.parent-item);
//...
}
just add the word all next to the name of the class
.child-item {
&:extend(.parent-item all);
//...
}
for example
.parent-item {
color: green;
background: red;
&:not(:last-child) {
margin-right: 20px;
}
&:last-child {
color: red;
}
&:hover {
color: red;
}
}
.child-item {
&:extend(.parent-item all);
//...
}
result will be
.parent-item,
.child-item {
color: green;
background: red;
}
.parent-item:not(:last-child),
.child-item:not(:last-child) {
margin-right: 20px;
}
.parent-item:last-child,
.child-item:last-child {
color: red;
}
.parent-item:hover,
.child-item:hover {
color: red;
}
Given this scss
.root {
color: red;
&-child {
color: blue;
small & {
font-size: 80%;
}
}
}
This is the CSS I get:
.root {
color: red;
}
.root-child {
color: blue;
}
small .root-child {
font-size: 80%;
}
I want to style .root-child on small differently so the rule I need is:
small.root-child {
font-size: 80%;
}
(Notice no whitespace after small)
How can I do that?
You need to use #at-root and that will remove the white space in your selector, as well as it will be a valid syntax so no issues while you try to compile.
.root {
color: red;
&-child {
color: blue;
#at-root small#{&} {
font-size: 80%;
}
}
}
You can use #at-root like this:
SCSS
.root {
color: red;
&-child {
color: blue;
#at-root {
small#{&} {
font-size: 80%;
}
}
}
}
Compiled:
.root {
color: red;
}
.root-child {
color: blue;
}
small.root-child {
font-size: 80%;
}
I have to convert some SCSS files to LESS. For most part it is just case of changing $ with # but there are style that use the scss parent selector & that I don't know how to convert.
Here is example
// Sidebar
.sidebar {
.block {
&.newsletter {
.btn {
&:before {
background: transparent;
}
}
}
&.filter {
ol {
li {
a {
color: #blue;
&:before {
display: none;
}
}
}
}
}
.filter-options-title, .block-title {
color: #444;
padding-bottom: 10px;
font-size: 12px;
&:after {
color: #666;
}
}
}
}
How would I replace out those parent selectors to make it the same generated CSS?
The & parent selector is actually the same syntax in Less and SCSS!
From the Less Documentation on Parent Selectors:
The & operator
represents the parent selectors of a nested rule and is most commonly
used when applying a modifying class or pseudo-class to an existing
selector
In comparison, here's the SASS/ SCSS documentation on parent selectors for pseudo classes: http://sass-lang.com/documentation/Sass/Selector/Pseudo.html
So in the case of your code, it would be:
SCSS
$blue: blue;
.sidebar {
.block {
&.newsletter {
.btn {
&:before {
background: transparent;
}
}
}
&.filter {
ol li a {
color: $blue;
&:before {
display: none;
}
}
}
.filter-options-title, .block-title {
color: #444;
padding-bottom: 10px;
font-size: 12px;
&:after {
color: #666;
}
}
}
}
(try compiling/ validating here: https://www.sassmeister.com/)
LESS
#blue: blue;
.sidebar {
.block {
&.newsletter {
.btn {
&:before {
background: transparent;
}
}
}
&.filter {
ol li a {
color: #blue;
&:before {
display: none;
}
}
}
.filter-options-title, .block-title {
color: #444;
padding-bottom: 10px;
font-size: 12px;
&:after {
color: #666;
}
}
}
}
(try compiling/ validating here: http://winless.org/online-less-compiler)
As well as the official documentation, this article on CSS Tricks is helpful too: https://css-tricks.com/the-sass-ampersand
Hope that helps :)