How to set the CSS class name dynamically in LessCSS? - css

I need to add a dynamic name to a CSS class to create a more specific decendent selector.
Here is my Less code:
#scope: name; //line1
.#scope .ui-widget{ color: #fff} //line2
But I am getting a parser error at line2.
Is there any way to set the CSS class name dynamically in LessCSS?

Support was added to less.js and dotless in version 1.3
You have to use brackets and an escaping string.. e.g.
(~".#{scope} .another") {
color: #fff;
}
Edit
This format is deprecated. less 1.3.1 (currently just trunk build of less.js) supports a simpler syntax
.#{scope} .another-class {
color: white;
}

Try the below code to get the expected output
#scope: name;//line1
(~".#{scope} .ui-widget") { color: #ffbbff} //line2

Related

SassError: Undefined variable

I have a variable file that has two definitions of themes I want to overwrite:
_vars.scss
body {
$bg-color: #fff
}
body.theme-dark {
$bg-color: #333
}
I´m calling the variables in my Angular button component:
button.scss
#import '_vars.scss';
.button {
background-color: $bg-color;
}
But I´m getting the following compiling error:
SassError: Undefined variable.
background-color: $bg-color;
Whats is the right way to overwrite variables depending on my body theme class?
Thanks
You define $bg-color depending on the theme, but never $font-size-18.
On a side note, I would consider to use CSS Custom Properties instead of SASS variables if I was in your shoes. Codyhouse have an interesting and easy to understand article about this, which also talks about color themes.
If you want to dig deeper into this topic you may want to read this article.
First of all variables inside scope valid only in that scope not universally. Now for your question see below :-
_vars.scss
Instead of making variables inside body scope create it in global scope.
$bg-color: #fff;
body {
background-color: $bg-color;
}
and then import it in your button.scss without underscore "_"
#use "vars" as *;
button {
background-color: $bg-color;
}

What design philsophy led CSS away from class-level inheritance? (and reliance on #extend/#apply in sass)

It sounds like this is something that sass/less/mixins/jquery are required for right now.
What I'm looking to do is something like this:
.myClass {
color: blue;
}
h1 {
class: myClass;
}
I'm curious why this was not done already, given that CSS seems to be about inheritance/aggregation if nothing else.
Does it not make sense for some reason?
Or maybe it's just too complex?
Thanks!
...I don't know if this is the first '#extend' proposal, but it comes out because of its popularity in sass, apparently: http://tabatkins.github.io/specs/css-extend-rule/
and there is an early discussion of the proposal in this list thread: https://lists.w3.org/Archives/Public/public-houdini/2015Jan/0005.html
Not sure if it is going to be a future CSS standard. But you can already do it with SASS and SCSS. Here is SCSS syntax:
.myClass {
color: blue;
}
h1 {
#extend .myClass;
...
}
Documentation: https://sass-lang.com/documentation/at-rules/extend
Well, in effect what you are trying to do is to make your CSS properties defined in the .myClass block, apply in your h1 block, (correct me if I'm wrong).
If that's what you meant, you can already do that by simply adding myClass to your h1 tag like <h1 class="myClass">Header</h1> and in your CSS you would do this:
.myClass {
color: blue;
}
// or
h1.myClass {
color: blue; // To only target h1 that have the 'myClass' class
}
Will future CSS standard allow applying classes to elements in a style declaration?
Well as you can see we can already do that with HTML, so I doubt it.

Sass Selector: When a tag is not in another tag

I'm attempting to style different code blocks depending on which tag they are present in:
code blocks that are inside a pre tag, and
code blocks that are NOT inside a pre tag
I know that I can just use the :not selector in plain css:
pre > code {
color: red;
}
:not(pre) > code {
color: blue;
}
But using it in sass throws an error and fails to compile:
:not(pre) > code
color: blue
Error:
Generating development JavaScript bundle failed
^
Invalid CSS after "...size: 1.5rem; }": expected 1 selector or at-rule, was "not(pre) : {"
in /Users/Psy/my-app/src/styles/v3/base.sass (line 111, column 23)
File: src/styles/v3/base.sass
failed Re-building development bundle - 0.339s
What is the correct way to do the same in Sass?
To be clear: I'm not looking for other ways for "reorganizing" my Sass code. Instead, looking for an explicit selector where a tag is not inside another tag.
Okay, I probably should've done this sooner, but I searched Github to see how other sass projects do the same.
Looks like while the :not selector works in SCSS the same way it works in CSS, we need to prefix the :not selector with * for SASS files:
*:not(pre) > code
color: blue
This works without errors.
You don't have to use :not selector. You can simply style the code and code under pre tag. This will provide the intended result:
code {
color: blue;
}
pre > code {
color: red;
}

Workaround for CSS variables in IE?

I'm currently developing a web application in Outsystems in which I have the need to customize the CSS, in which I'm using variables. I need to guarantee the app works cross-browser, including in Internet Explorer. IE doesn't support CSS variables, as you can see in the picture below from this source.
Since I have to use CSS variables, is there any workaround for the usage of variables in IE?
Yes there is a way, the same way you make any css compatible: use a specific css fallback that is supported by the browser.
body {
--text-color: red;
}
body {
color: red; /* default supported fallback style */
color: var(--text-color); /* will not be used by any browser that doesn't support it, and will default to the previous fallback */
}
This solution is incredibly redundant and 'almost' defeats the purpose of css variables....BUT it is necessary for browser compatibility. Doing this would essentially make the css variables useless but I implore you to still use them because it will serve as an important reminder to the fact that these values are referenced elsewhere and need to be updated in all cases, otherwise you forget to update every related occurrence of 'color' and then you have inconsistent styling because relevant css values are out of sync. The variable will serve more as a comment but a very important one.
There is a polyfill, which enables almost complete support for CSS variables in IE11:
https://github.com/nuxodin/ie11CustomProperties
(i am the author)
The script makes use of the fact that IE has minimal custom properties support where properties can be defined and read out with the cascade in mind.
.myEl {-ie-test:'aaa'} // only one dash allowed! "-"
then read it in javascript:
getComputedStyle( querySelector('.myEl') )['-ie-test']
From the README:
Features
handles dynamic added html-content
handles dynamic added , -elements
chaining --bar:var(--foo)
fallback var(--color, blue)
:focus, :target, :hover
js-integration:
style.setProperty('--x','y')
style.getPropertyValue('--x')
getComputedStyle(el).getPropertyValue('--inherited')
Inline styles: <div ie-style="--color:blue"...
cascade works
inheritance works
under 3k (min+gzip) and dependency-free
Demo:
https://rawcdn.githack.com/nuxodin/ie11CustomProperties/b851ec2b6b8e336a78857b570d9c12a8526c9a91/test.html
In case someone comes across this, has a similar issue where I had it set like this.
a {
background: var(--new-color);
border-radius: 50%;
}
I added the background colour before the variable so if that didn't load it fell back on the hex.
a {
background: #3279B8;
background: var(--new-color);
border-radius: 50%;
}
Yes, so long as you're processing root-level custom properties (IE9+).
GitHub: https://github.com/jhildenbiddle/css-vars-ponyfill
NPM: https://www.npmjs.com/package/css-vars-ponyfill
Demo: https://codepen.io/jhildenbiddle/pen/ZxYJrR
From the README:
Features
Client-side transformation of CSS custom properties to static values
Live updates of runtime values in both modern and legacy browsers
Transforms <link>, <style>, and #import CSS
Transforms relative url() paths to absolute URLs
Supports chained and nested var() functions
Supports var() function fallback values
Supports web components / shadow DOM CSS
Watch mode auto-updates on <link> and <style> changes
UMD and ES6 module available
TypeScript definitions included
Lightweight (6k min+gzip) and dependency-free
Limitations
Custom property support is limited to :root and :host declarations
The use of var() is limited to property values (per W3C specification)
Here are a few examples of what the library can handle:
Root-level custom properties
:root {
--a: red;
}
p {
color: var(--a);
}
Chained custom properties
:root {
--a: var(--b);
--b: var(--c);
--c: red;
}
p {
color: var(--a);
}
Nested custom properties
:root {
--a: 1em;
--b: 2;
}
p {
font-size: calc(var(--a) * var(--b));
}
Fallback values
p {
font-size: var(--a, 1rem);
color: var(--b, var(--c, var(--d, red)));
}
Transforms <link>, <style>, and #import CSS
<link rel="stylesheet" href="/absolute/path/to/style.css">
<link rel="stylesheet" href="../relative/path/to/style.css">
<style>
#import "/absolute/path/to/style.css";
#import "../relative/path/to/style.css";
</style>
Transforms web components / shadow DOM
<custom-element>
#shadow-root
<style>
.my-custom-element {
color: var(--test-color);
}
</style>
<div class="my-custom-element">Hello.</div>
</custom-element>
For the sake of completeness: w3c specs
Hope this helps.
(Shameless self-promotion: Check)
Make a seperate .css file for your variables. Copy/paste the contents of the variable.css file to the end of your main.css file. Find and replace all the variable names in the main.css file to the hex code for those variables. For example: ctrl-h to find var(--myWhiteVariable) and replace with #111111.
Side note: if you keep the :root{ } in the main.css file and just comment it out, you can use that to track those hex codes later if you want to update your fallback colors.
Another way to do it is declaring colors in a JS file (in my case I'm using react) and then just use the variable you defined in the JS file.
For example:
in globals.js
export const COLORS = {
yellow: '#F4B400',
yellowLight: '#F4C849',
purple: '#7237CC',
purple1: '#A374EB',
}
in your file
import { COLORS } from 'globals'
and then just use COLORS.yellow, COLORS.purple, etc.
body {
--text-color : red; /* --text-color 정의 */
}
body {
color: var(--text-color, red); /* --text-color 정의되지 않으면 red로 대체됨 */
}
body {
color: var(--text-color, var(--text-color-other, blue));
/* --text-color, --text-color-other 가 정의되지 않으면 blue로 대체됨 */
}
There is no way yet in "normal" css but take a look at sass/scss or less.
here is a scss example
$font-stack: Helvetica, sans-serif;
$primary-color: #333;
body {
font: 100% $font-stack;
color: $primary-color;
}
I recommend setting your css variables as sass variables, then using sass interpolation to render the color in your elements.
:root {
--text-color: #123456;
}
$text-color: var(--text-color);
body {
color: #{$text-color};
}
If im not wrong there is a workaround, the CSS #ID Selector. Which should work for IE > 6 I guess.. So you can
.one { };
<div class="one">
should work as
#one {};
<div id="one">

Compass - include one value for another property

I want to include a value from another class - and use this for something different:
I have this class:
.sourceClass {
color: red;
}
And I have this class:
.destinationClass {
border-color: ###should be the color from .sourceClass => red
}
is this possible? And how can I do that?
You tagged your post with "Sass". Are you using the Sass/SCSS preprocessor? If so, you'd declare and use a variable like this:
$myColor: red;
.sourceClass { color: $myColor; }
.destinationClass { border-color: $myColor; }
If you're not using Sass, you can read about native CSS variables - which are currently working in Firefox and Chrome, but not IE/Edge.
Lastly, there is a possible solution supported in all current browsers, which would be applicable depending on your DOM hierarchy: currentColor.
If your .destinationClass is a child of .sourceClass, and therefore is inheriting color: red, you could simply use border-color: currentColor to take that color and use it as the border color.
Hope this helps!

Resources