Invalid CSS in Sass - css

Whenever I try to compile Sass code to CSS with either the terminal or the program Koala I get this error message:
Error: Invalid CSS after "body ": expected selector, was "{"
on line 5 of style.sass
Use --trace for backtrace
Here's the piece of code the error seems to be referring to:
body {
background {
color: $background-color
}
}
How can I fix my code to make it compile correctly?

The way your selector reads is that it is looking for the <body> element, and then a <background> element (which isn't a thing that exists in HTML, to my knowledge), and then you are setting the text inside that element to the color in your var $background-color. I think either one of two things:
Either you meant for background to be a class or id, like .background, in which case your code becomes:
body {
.background {
color: $background-color;
}
}
Or, more likely, you are very tired and just got your wires crossed, and mean to be setting the background-color property like this:
body {
background-color: $background-color;
}
Please note that you were also missing an ending semi-colon, which I added.

You cloud try adding a colon after background.
body {
background: {
color: $background-color;
}
}

Sass, unlike Scss, uses indentation instead of curly braces.
body {
background {
color: $background-color;
}
}
becomes
body
background
color: $background-color
Though, I'm quite sure you mean to have background as a property instead of a selector.
body
background-color: $background-color

background must be class name or id or simply background css property.
body {
.background {
color: $background-color;
}
}
body {
#background {
color: $background-color;
}
}
body {
background : $background-color;
}

Related

Targeting BEM-formatted CSS selectors with Sass

I'm trying to slightly modify the styles of a block formatting plugin in Wordpress by overriding them in my own theme stylesheet. I use Sass but I'm new to it.
Pasting all of the selectors right out of Developer Tools works, but I know that's not the elegant/modular way to do it:
.an-accordion.an-accordion--v2.an-accordion.an-accordion--design-basic .an-accordion__heading {
color: gold
}
What's the right way to do this in Sass? I've tried something like this:
.an-accordion {
&--v2 {
&--design-basic {
&__heading {
color: gold;
}
}
}
}
but it doesn't work. I can tell I'm missing something about the way .an-accordion repeats.
You can use the power of local scoped string variables $something:... combined with the power of string interpolation #{...} and combine it with the current selector string & to create a compound selector for any combination of block, element, and modifier. Which I think is quite nice and readable:
.an-accordion {
$modifier-v2: #{&}--v2;
$modifier-design-basic: #{&}--design-basic;
$element-heading: #{&}__heading;
&#{$modifier-v2}#{$modifier-design-basic} {
#{$element-heading} {
color: gold;
}
}
}
which will result in:
.an-accordion.an-accordion--v2.an-accordion--design-basic .an-accordion__heading {
color: gold;
}
I tried it out on sassmeister.com
Note that I omitted the duplicated .an-accordion class in the selector; if this is important for you to increase the specifity you can insert it with #{&}.
BEM is about blocks, elements, and modifiers. Block scope is the biggest one, the element is some part inside the block and the modifier is optional and represents the status of your block-element. In Sass you can nest elements if they are parent and children and you don't need to repeat the parent element, in your stlesheet, if the beginning of your property is the same for both parent and child, but if the beginning is different you must repeat.
In a html like this:
<div class=" an-accordion an-accordion--v2 .an-accordion--design-basic .an-accordion__heading"></div>
You could have some scss code like this:
.an-accordion{
color: #000;
&__heading{
background-color: tomato;
}
&--v2{
font-weight: bold;
}
&--design-basic{
border: none;
}
}

Sass: Using Ampersand '&' for body tag which has a specific class

Demo: https://codepen.io/moradxd/pen/WJpPyQ
Assume i have this HTML code:
<body class="boxed">
<div class="text-white">
Button
</div>
</dody>
I'm using this sass code as following:
.boxed {
// error with using "Ampersand"
body& {
}
}
But it results a compiling error which says:
Although the result i want is as following:
// This the result i want
body.boxed {
}
I know that i can use it like this, and it will result what i'm looking for:
// I know i can use this
body {
&.boxed {
}
}
But i want to separate the .boxed class code from inside the body css code for orgnization purpose.
So why this is not allowed although the similar code for element and it's parent is working for the following:
// Although this similar code for element and
// it's parent is working
.btn-featured {
.text-white & {
font-size: 30px;
}
}
In fact i hope to know why this not allowed!
Hello morad you need to use #at-root
.boxed {
#at-root body#{&} {
color: red;
}
}
codepen
You need to swap your selectors around for it to work like you've said.
body {
&.boxed {
background: red;
}
}
The issue is that the ampersand connects the previous selector to the current selector. So when you do something like this:
.boxed {
body & {
background: red;
}
}
It's trying to add 'nothing' to the body tag inside an element with the boxed class on it. The best way is to do it how you've already stated.
More info on referencing parent selectors.

CSS Modules: selecting child class through selectors

So,
I have appended a home class to body like so:
document.body.classList.add("home")
I want to select appContainer a child element of body class by doing
html body.home #appContainer { ..... }
This works without CSS Modules but was wondering how I can do it with CSS modules. Thanks
You need to use wrap the class that you want to be global into :global(). If your selector uses an element you must write it directly after the element with no space in between, like element:global(.class) which translates into element.class.
Therefore, in your case html body:global(.home) #appContainer is the answer.
For anyone else that comes across this issue, I am using postcss-preset-env and I had to do this:
Worked ✅
.toolTipTest :global .rc-tooltip-arrow {
color: blue;
}
This did not work ❌
.toolTipTest:global(.rc-tooltip-arrow) {
color: blue;
}
And neither did this ❌
.toolTipTest:global(.rc-tooltip-arrow) {
color: blue;
}
// Neither Did this
.toolTipTest {
&:global(.rc-tooltip-arrow) {
color: blue;
}
}

Howto use SASS parent selector for keeping declaration atomic in a structure with imports

As mentioned here it's possible to set properties based on e.g a class on a parent element.
I've tried it a while without luck to specify the color of a paragraph based on the sections background containing the paragraph to have all style definitions in the file for that paragraph to keep it atomic.
If I looked into the compiled CSS and saw something happens. I guess my filestructure broke things here because I created a lot of files and included them on the levels where these were needed.
Here's what I did:
// Main.scss
html{
body{
#wrapper{
#import "areas/section";
}
}
}
// _section.scss
section{
width:100%;
height:100%;
&.black{
background-color:#000;
}
&.white{
background-color:#fff;
}
#import "paragraph";
}
// paragraph.scss
p{
section.black &{
color:#fff;
}
section.white &{
color:#000;
}
}
And the generated outout looks like this:
section.white html body div#wrapper section p {
color: #000;
}
And I expect an output like this:
html body div#wrapper section.white p {
color: #000;
}
Is that possible or is my interpretation completely wrong?
The parent selector isn't a reference to the next level up, but the entire composed selector after all imports/extends/mixin calls are resolved.
.one {
.two {
.three & {
color: red;
}
}
}
The output will be this:
.three .one .two {
color: red;
}
In this example, & is equal to .one .two, not .two. It doesn't matter what method you use to nest your rules (extending, importing, or using mixins), the result is still the same.

How to conjoin selectors

Is there a way to write this css:
div.some-class{
...
}
span.some-class{
...
}
as something like this using scss?
.some-class{
&div{
...
}
&span{
...
}
}
I tried the above, but it returns an error.
I know there's a real desire to have your code grouped together in nice neat little blocks like that, but it just isn't possible. The error you get when you compile the code is quite clear:
>>> Change detected at 14:46:18 to: test.scss
error sass/test.scss (Line 2: Invalid CSS after " &": expected "{", was "div{"
"div" may only be used at the beginning of a compound selector.)
Of course, if you reverse it so that it is div&, then you get this error:
>>> Change detected at 14:48:01 to: test.scss
error sass/test.scss (Line 2: Invalid CSS after " div": expected "{", was "&{"
"&" may only be used at the beginning of a compound selector.)
Your only option is to not nest at all.
.some-class {
...
}
div.some-class {
...
}
span.some-class {
...
}
It depends what you're trying to do.
The example you show will be interpreted as .some-classdiv and .some-classspan which will result in a compilation error. Essentially the ampersand represents the parent selector.
If div.some-class and span.some-class don't share the same styles, the first block you have is still the most effective way to write it.
If they share some of the same styles, you could write a mixin.
// Shared Styles
#mixin some-class {
background: #f00;
color: #fff;
}
div.some-class {
#include some-class;
... other styles
}
span.some-class {
#include some-class;
... other styles
}
You could also #extend an existing class:
.some-class {
background: #f00;
color: #fff;
}
div.some-class {
#extend .some-class;
... other styles
}
span.some-class {
#extend .some-class;
... other styles
}
If you extend an existing class, the class must be a root class included in the file (i.e. it can't be a nested class).
That said, since both elements have the class some-class, you could just as easily define regular CSS:
.some-class {
background: #f00;
color: #fff;
}
div.some-class {
... other styles
}
span.some-class {
... other styles
}

Resources