I don't understand the difference between CSS custom properties (variables) and SCSS variables (I am new to Sass by the way).
If this CSS code:
:root {
--someColor: coral;
}
body {
background: var(--someColor);
}
achieves the same results as this SCSS code:
$someColor: coral;
body {
background: $someColor;
}
Why were SCSS variables introduced? Are they really the same as CSS variables, or am I missing something?
SCSS is a preprocessor. That means it is not CSS, but is converted into CSS at 'compile time'. In the resulting CSS code there is no resemblance to the original SCSS code. Hence you cannot change the variable values at CSS 'runtime'.
Historically SCSS is a fairly old technique. Actually it dates back to as far as 2007. It was invented by the motivation that CSS lacks certain features amongst which are variables (and nesting and loops and mixins etc.).
CSS variables are a quite recent addition to the CSS standard (The last call working draft seams to be from 2014). They didn't render SCSS variables useless, because you can do things to SCSS variables which you can't do with CSS variables (to my knowledge) like color calculations.
On the other hand you can do things with CSS variables that you can't do with SCSS variables like changing at runtime.
BTW: CSS variables are not the official jargon. They should be called custom properties. But everyone calls them variables.
Addendum 1
One difference I was not talking about. You can't change SCSS variables with JavaScript. CSS Custom Properties however can be accessed and changed with JS
Addendum 2
This article on CSS Tricks has a good overview: https://css-tricks.com/difference-between-types-of-css-variables/
Related
i feel like this may be simple enough and I'm just missing it. I recently went to 7-1 folder structure instead of a single scss file. What i'm having difficulty with is referencing .panel(or h2 or span) in _typography.scss to do font-styling and reference the same .panel(h2,span, etc) in my _layout.scss.
I understand from a CSS pov this wouldn't be logical to have them broken up as of sequencing, however, from a sass pov, I feel like there should be a way to structure this so my CSS doesn't have .nav-container mentioned twice.
Just to note, I'm using NPM, not an ide compiler. Maybe I'm just going about structuring generally incorrect and shouldn't separate them.
Please advise,
UPDATE ANSWER
I've marked Frish's answer here correct because the way that they set it up is correct, but after several and i mean several days of research, i've decided to add some context as I see many others have created simiar threads.
The way I initially looked at SASS was incorrect. I was trying to make SASS work in a way i thought would eliminate complexity: (having .nav-container {} typography rules in a typography partial, then .nav-container {} layout in a layout partial.) This isn't the right way of thinking.
The real benefits are all the built in functions (placeholders,mixins, extends) that drive the magic of making SASS more effective.
However, there is a way to still do what you're looking to do, styling selectors across different partials, for example, separating typography styling from layout styling, and so forth, for particular selector. This was a major wakeup call. Passing Style Blocks (or Content Blocks) to a mixin or whatever. So for example:
#mixin button {
font-size: 1em;
padding: 0.5em 1.0em;
text-decoration: none;
color: #fff;
#content;
}
.button-green {
#include button {
background: green
}
}
Finally,
this link(https://openclassrooms.com/en/courses/5625786-produce-maintainable-css-with-sass/5951856-write-cleaner-code-with-sass-extensions) is where it really clicked for me
Look at the section paragraph that starts with "extensions are a lot like mixins." Review this example as it should be easy to apply its setup and way of structuring to what you're trying to do.
Getting deeper into this, i did some googling on "passing style blocks" and "sass passing content blocks" and that helped a ton on how to leverage placeholders, mixins, and extends effectively while still maintaining the simplicity of sass structuring.
This isn't a concrete answer as there are many ways to approach this (as you are undoubtedly aware), but here are my thoughts.
I typically use generic stylesheets (_typography, _layout) for generic elements (h1,h2,h3, .section, .container perhaps). Any element that merits special mention in multiple files potentially merits being its own component (e.g. panel.scss).
This does increase the numbers of folders and files floating around, but I still find this preferable to one, or a few, big files. I usually end up with a main.scss file that looks like this:
// main.scss
#import "_variables.scss";
#import "_typography.scss";
// etc....
#import "./components/panel.scss";
#import "./components/navContainer.scss"; // or, nav-container.scss!
// etc....
Components happily override generic styles, and I can track their CSS in individual files. Happy dev! You can sub-divide components or other files as you see fit.
I am gonna use css global variables in scss file so that I can change the button colour in any time.
I want to do like this:
:root {
--button-color: #FF0000;
}
$button-color: var(--button-color);
...
But this makes the issue now.
SASS variables are compile time and final value depends on all files were #import in line. CSS variables are run-time and are calculated based on cascade(say if any parent element redeclares variable - it will be applied to children).
Also take a look into docs section on difference between
You can use css-vars to compile SASS variables into CSS custom properties. But you still cannot use CSS custom properties in SASS code, say, to calculate some value - since CSS property is not initialized yet.
Even with css-vars plugins, things are rather messy, because SASS files does not describe how component tree looks like finally so we cannot see cascade.
TL;DR; don't mix SASS variables and CSS custom properties. Use first for compile-time variables/calculation only and use latest one for run-time/cascade-based styling. Probably prefer using CSS custom properties only.
This question is less of a code question and more of a best-practices question. I am working on a custom bootstrap theme based on https://github.com/HackerThemes/theme-kit. I have a working theme that I like, however, I am overriding some styles in the original Bootstrap theme. Even in the minified CSS, these are duplicated. For example, Bootstrap defines...
.btn-danger:hover {
color: #fff;
background-color: #ae130b;
border-color: #a2120a;
}
...but my code also defines...
.btn-danger:hover {
border-color: #0000;
}
In the final stylesheet, both of these styles are present. The second style overrides Bootstrap and it looks just fine. However, this leads to useless code. First of all, is there a postprocessor of some sort that I can use with Gulp to eliminate these duplicates and consolidate them? Second, should I just fork the Bootstrap repository and modify the original SCSS directly?
It depends on what you #import. Looking at mytheme.scss, the entire Bootstrap SASS is imported, creating full duplicate code in the final CSS.
Instead you can pick specific SASS files to import and look at the option variables which also effects what CSS is generated. For example, setting $enable-grid-classes: false will prevent duplication of the entire grid system in the generated CSS.
I have several styles that use Sass' #extend or #include to inherit properties from selectors imported from Bootstrap scss files.
I would like to convert all of the Bootstrap selectors to #extend-Only placeholders, so I do not have to include any original Bootstrap selectors in my final .css output. The goal is to write my own css classes, extend from Bootstrap only where desired.
For example, I wish to have a navbar called .super-freaky-nav:
.super-freaky-nav{
#extend .navbar;
#extend .navbar-default;
#extend .navbar-top-fixed;
}
Ideally, my final .css output will not have a single reference to .navbar, .navbar-default, or .navbar-top-fixed.
Is there a way to do this without going into the _navbar.scss file and converting all of the selectors to #extend-Only classes (%navbar, %navbar-default, %navbar-top-fixed, etc)?
Thanks!
No. Sass does not have the ability to do what you're asking for. There's still a legitimate need to be able to extend normal classes and Sass has no way of differentiating between classes that should or shouldn't be extended.
One potential implementation I'm exploring uses custom importers in ruby-sass or the experimental importers feature in node-sass (2.0+) to apply a sed (find and replace) transform to the Bootstrap Sass files, replacing leading class definitions with % syntax. I haven't gotten much past experimentation, though, and I don't know what I might break without a comprehensive visual test suite. Happy to have some help with it.
I am just getting started with less. In an attempt to mmake less ugly Bootstrap's multitude of classes on tags, I have attempted to write some simple wrappers in less.
The entireity of my code is below.
// Import boostrap.
#import "./less/bootstrap.less";
// General classes for content.
focus {
.span12;
}
content {
.span8;
}
side {
.span4;
}
The purpose of this less file is to provide nice looking wrappers that do a single thing, such as Bootstrap's .span12 class. I will, in time, extend this to buttons of sorts.
Either way, I am running into a problem when compiling the less file using lessc style.less.
The error it gives is:
NameError: .span12 is undefined in /srv/http/www/style.less on line 6, column 5:
5 focus {
6 .span12;
7 }
I have found some documentation with the .makeColumn(i) class but the problem with that is Bootstrap already has perfectly good media queries and I wanted to avoid writing my own.
Is there anyway to wrap the classes that already have the media queries or do I need to just suck it up and write my own for my wrappers?
You are going to run into a few major problems in this approach.
First, there are issues in that Bootstrap is dynamically generating the .spanX series of classes, so they are not immediately accessible as mixins, as I note in this answer.
Second, some of Bootstrap's span code is not set by the .spanX series, but is done through an attribute selector of [class*="span"] (see, as of this writing, line 602 of the mixins.less file; they are also extensively used in the responsive files for the #media rules). This selector code would not be picked up by a .span12 inclusion of code, and if you are not putting .span12 in your code, then your code will not have those properties applied. So you need to work around that.
There may be other issues not immediately obvious, but the point is, if you want to use Bootstrap for grid purposes (especially responsive), it is probably best to use it as it is designed. If you do not, then it is best to go and copy the Bootstrap code and modify it as you desire to make your own reduced grid code (if your intent is to use less overall classes in your html).