My dev environment is working great, but when I tried building the app, some of the styles are missing. Here is an example
<style lang="scss">
.badge {
display: inline-block;
padding: 5px 15px;
border-radius: 25px;
font-size: 0.75em;
#apply tw-bg-border tw-text-primary tw-font-bold;
&--danger {
color: white;
#apply tw-bg-danger-alt;
}
&--info {
color: white;
#apply tw-bg-info;
}
&--warning {
color: white;
#apply tw-bg-warning;
}
}
.badge--success {
color: white;
#apply tw-bg-success-alt;
}
</style>
I need to move .badge--success outside for it to work, but all other CSS modifiers are not working.
I'm trying to merge the style into one class but its showing an error. Look at the example below.
%banner-style{
banner {
padding: 140px 0 210px;
background: url(https://im2.ezgif.com/tmp/ezgif-2-92c6382d82ba.jpg) top center/cover no-repeat;
&.row {
margin: 0;
}
.main-heading {
font-size: 40px;
letter-spacing: -1px;
font-weight: 600;
padding-right: 20px;
sup {
font-size: 10px;
vertical-align: super;
}
}
}
}
And I want it to merge with the parent class .parent
.parent{
color: red;
&_#extend %banner-style;
}
using & to merge into one class name. but showing error unless i do this
.parent{
color: red;
&_{#extend %banner-style};
}
Which is same as if I remove &_.
I wanted .parent_banner {...} but instead got .parent_ banner{...};
Does anyone know how I can accomplish this?
You are getting exactly what is supposed to happen. Extend does not "merge" classes, it extends another class/placeholder into a new selector's styles.
What that means is if I write:
%banner-style {
background: black;
}
.parent {
#extend %banner-style;
}
.other-selector {
#extend %banner-style;
color: red;
}
The css I get will be
.parent {
background: black;
}
.other-selector {
color: red;
background: black;
}
So you are getting expected results. If you'd like to make this "work" the way you want, you can just change your code to:
%banner-style {
padding: 140px 0 210px;
background: url(https://im2.ezgif.com/tmp/ezgif-2-92c6382d82ba.jpg) top center/cover no-repeat;
&.row {
margin: 0;
}
.main-heading {
font-size: 40px;
letter-spacing: -1px;
font-weight: 600;
padding-right: 20px;
sup {
font-size: 10px;
vertical-align: super;
}
}
}
.parent{
color: red;
&_banner {
#extend %banner-style;
};
}
Note: I took out the banner block because it seems you don't want that (and banner isn't a normal html element).
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;
}
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 :)
I have a link which has a small drop down arrow after it, added using :after.
What I want to do is change the color of the arrow when I hover over the link, is this possible?
This is what I'm trying but doesn't work:
.detail__changer {
color: #333;
cursor: pointer;
text-decoration: underline;
font-size: 33px;
}
.detail__changer:after {
color: #333;
content: ' ▾';
}
~ .detail__changer:hover:after {
color: red !important;
}
Here's a fiddle
Also, I have seen this question, my question is not the same
Remove the tilde
.detail__changer {
color: #333;
cursor: pointer;
text-decoration: underline;
font-size: 33px;
}
.detail__changer:after {
color: #333;
content: ' ▾';
}
.detail__changer:hover:after {
color: red !important;
}
<div class="detail__changer">Hover over me</div>