Using CSS #Variables [duplicate] - css

This question already has answers here:
How can I define colors as variables in CSS?
(19 answers)
Closed 4 years ago.
I am trying to use CSS Variables. I look online for tutorials and all of them worked so far.
Here's my CSS:
#variables {
defaultColor: #8E5050;
defaultBackGround: #E1DBC3;
}
body {
background: var(defaultBackGround);
}
a {
color: var(defaultColor);
}
I also tried:
body {
background: #defaultBackGround;
}
a {
color: #defaultColor;
}
None of them works, What am I doing wrong? Thanks

I would use a CSS preprocessor such as Sass or Less.

The variables you are using are not part of the normal CSS specification. It looks like you are writing in some CSS framework.
If you do want to use pure CSS, you are stuck with setting the values of colors / margins / padding manually every time. But a good "Search & replace"-function in your favorite text editor may help you there. :)
If you want to use these variables, #Petah has the right answer for you. :)

Use Native CSS3 Variables!
Variables are actually a native feature in CSS3 - you can read the spec at MDN. However, they are still a relatively new feature, so you may want to check out the Browser Support charts here before using them.
That being said, CSS Variables are supported by the latest versions of Chrome, Firefox, Opera, Safari and Microsoft Edge.
The following code shows an example of how CSS variables can be used:
:root {
--name: #ff0000;
}
p {
color: var(--name);
}
How does this work?
Variables can be used if they are defined on the parent container of the element - here I use :root so that the variable is accessible everywhere.
A variable can be defined using --name:content; where name is the name of the variable and content is the contents of the variable (this can be a color, like #ff0000, a size like 1em, or one of many more possible values).
Then, simply use var(--name) instead of a property in your CSS code, where name is again the name you called the variable.

From what I understand, variables aren't fully supported yet, but this is how you will set them when they are:
/* declare in :root with the usual browser prefixes */
:root {
var-myVariableColor: #f00;
-webkit-var-myVariableColor: #f00;
-moz-var-myVariableColor: #f00;
-ie-var-myVariableColor: #f00;
}
/* to reference encase in var() */
body {
background-color: var(myVariableColor);
}

Related

Using attr to set css variable inline that work with CSP

I was thinking how I can use css variables without using inline styles. I thought that I can use this:
[data-color] {
--color: attr(data-color color, green);
}
* {
color: var(--color, blue);
}
<div data-color="red">hello</div>
It seems that attr work only in pseudo selectors (and probably only on content: property), but MDN attr page says:
The attr() CSS function is used to retrieve the value of an attribute of the selected element and use it in the stylesheet. It can also be used on pseudo-elements, in which case the value of the attribute on the pseudo-element's originating element is returned.
There is even demo but it don't work in Chrome on Linux, so it's of no use to me. It even don't work in Firefox on Linux.
Is there any other way to use css variables without inline styles and without writing dynamic <style></style> and nonce?
Not yet. In the same link you can read:
Note: The attr() function can be used with any CSS property, but support for properties other than content is experimental, and support for the type-or-unit parameter is sparse.
Still no browser support the attr() for properties different than content and also no support for the type-or-unit.
Worth to note that you can use attr() inside a CSS variable but it need to be later used with content. CSS variables is only an intermediate so we don't evaluate the support based on the variable but based on the property that will use the variable.
[data-color] {
--color: attr(data-color);
}
*::before {
content: var(--color, "default");
color:blue;
}
<div data-color="red">hello</div>
An interesting use of the CSS attr property, but as the question states, the support for it outside of the pseudo element property is sparse see for example https://developer.mozilla.org/en-US/docs/Web/CSS/attr
It's actually slightly worse than that because if you have:
* {
color: var(--color, blue);
}
[data-color] {
--color: green;
--color: attr(data-color);
}
<div data-color="red">hello</div>
similar to in the question but separated out to be more explicit. The --color: attr(data-color) does not flag a warning and get ignored and the green used. Instead it is accepted and --color set to the string. It's as if the browser sort of recognises the attr and that it should do something with it but doesn't actually do it fully.
For everyone who still want to manage CSS variable on HTML you can do it like that:
* {
color: var(--color, blue);
}
<div style="--color: red">hello</div>
<div>hello</div>

Use CSS wildcard as a parameter [duplicate]

It is possible to pass parameters for CSS in class name? For example:
.mrg-t-X {
margin-top: Xpx;
}
<span class="mrg-t-10">Test</span>
In this example X should be 10.
No it isn't. The closest we have to this is the attr() function, but that only works within the content property:
figure::before {
content: attr(data-before) ', ';
}
figure::after {
content: attr(data-after) '!';
}
<figure data-before="Hello" data-after="world"></figure>
Perhaps one day this will be expanded so that we can use it elsewhere, but for now this isn't possible.
Currently as I'm sure you're aware if you want to be able to use the .mrg-t-X class, you'll need to define separate style rules for each X you wish to allow:
.mrg-t-1 { ... }
.mrg-t-2 { ... }
.mrg-t-3 { ... }
...
Nowdays you can use CSS variable inside a style attribute instead generating a specific class:
Custom properties (sometimes referred to as CSS variables or cascading variables) are entities defined by CSS authors that contain specific values to be reused throughout a document. They are set using custom property notation (e.g., --main-color: black;) and are accessed using the var() function (e.g., color: var(--main-color);).
Complex websites have very large amounts of CSS, often with a lot of repeated values. For example, the same color might be used in hundreds of different places, requiring global search and replace if that color needs to change. Custom properties allow a value to be stored in one place, then referenced in multiple other places. An additional benefit is semantic identifiers. For example, --main-text-color is easier to understand than #00ff00, especially if this same color is also used in other contexts.
Custom properties are subject to the cascade and inherit their value from their parent.
example
span {
display: block;
margin-top: var(--m-t);
}
html {
background: repeating-linear-gradient(to bottom, transparent, 10px, lightgrey 10px, lightgrey 20px);} /* see 10px steps */
<span style="--m-t:50px">one</span>
<span style="--m-t:85px">two</span>
<span style="--m-t:110px;">three</span>
Maybe you are looking for SCSS or LESS. It have mixins, variables, etc, and it autocompile real and long css. It was maded to this purposes and write less and less css with the same result.
http://sass-lang.com/guide
http://lesscss.org/
#size: 10px;
.class { font-size: #size; }
Good luck!
It isn't possible to directly pass parameters using just CSS but you're not the first person to ask - check out this question which looks at CSS and JavaScript options and also this might be helpful regarding attribute selection.
This will only help if you are looking at a few variables of margin-top but I don't know what context you're using this in. Depending on what you're using it for there might be better ways.
The simplest way would probably be just to add the style inline to your span <span style="margin-top:10px"> but I try to stay away from inline CSS!
no your code is wrong
but you can write css inside the tag
*<span style="margin-top:Xpx;">*

How to use CSS custom variables for properties

My stylesheets have large amounts of styles declared, often with a lot of repeated values. I read about variables in CSS to solve that problem.
I tried to use them, but it is not working:
element {
--main-bg-color: brown;
}
body {
background-color: var --main-bg-color;
}
What am I doing wrong?
You did everything right, just keep the variables in (put variable here)
element {
--main-bg-color: brown;
}
body {
background-color: var(--main-bg-color);
}
var() notation works like a method
var(<custom-property-name>)
might consider putting your variables in a :root selector...
:root {
--main-bg-color: brown;
}
/* The rest of the CSS file */
body {
background-color: var(--main-bg-color);
}
:root is similar to global scope, but the element itself (ie body { --myvar: ... }) or ancestor elements (ie html { --myvar: ... }) can also be used to define variables
Refer to MDN reference page. A brief, to use custom variables you need to place them inside :root selector:
:root {
--main-bg-color: brown
}
In order to use it in another selector yo use var():
body {
background-color: var(--main-bg-color)
}
For me, the problem was that #charset "UTF-8"; was not the very first characters in the css file, and this messed up the :root{--my-variable: large }.
You need to add var(--my-variable) when using the variables.
But that's not something you should use CSS custom properties (variables) for.
Bear in mind some browser can't understand CSS variables, most noticeably IE. So using any pre-processor instead will be better for compatibility, as they are compiled to regular CSS values. Either SASS, LESS, POSTCSS... whatever floats your boat.
CSS custom properties are much more powerful than pre-processor ones, as they can be changed at runtime with javascript and be used in all sorts of awesome ways, but when you're using them as regular variables, pre-processor variables are always better for compatibility.
If you want to declare them globally, I would recommend to use it in:
* { --var : #colorName; }.
This has actually helped me in Angular application.

nested css rules [duplicate]

This question already has answers here:
Nesting CSS classes
(8 answers)
Closed 4 years ago.
Some time ago I saw an example of a css file, where the css rules/selectors where specified in a nested way, e.g. something like this:
div.a {
color: red;
div.b {
font-weight: bold;
}
}
I'm not sure where I saw that (probably in a SO question), or whether it was exactly as shown above.
My questions: Is the above CSS correct/valid? Is it a standard way to specify CSS rules or is this a browser-dependent hack?
That is not valid standard CSS, but it's an example of nesting class declarations using Sass/SCSS or LESS and I believe other CSS extensions out there, which expand it to something like this (which is valid CSS), before serving it to the browser to use:
div.a {
color: red;
}
div.a div.b {
/* Inherits color from div.a */
font-weight: bold;
}
What you are probably referring to is LESS.
The example, you gave is not valid CSS, but is valid with LESS. LESS will "compile" the nested CSS and convert it to something which is valid CSS.
You can nest rules with SASS, http://sass-lang.com/
Maybe that was it?
Seems there is a proposal over at https://tabatkins.github.io/specs/css-nesting/
but I can't find the status of it

CSS Equivalent of the "if" statement

Is there any way to use conditional statements in CSS?
I'd say the closest thing to "IF" in CSS are media queries, such as those you can use for responsive design. With media queries, you're saying things like, "If the screen is between 440px and 660px wide, do this". Read more about media queries here: http://www.w3schools.com/cssref/css3_pr_mediaquery.asp, and here's an example of how they look:
#media screen and (max-width: 300px) {
body {
background-color: lightblue;
}
}
That's pretty much the extent of "IF" within CSS, except to move over to SASS/SCSS (as mentioned above).
I think your best bet is to change your classes / IDs within the scripting language, and then treat each of the class/ID options in your CSS. For instance, in PHP, it might be something like:
<?php
if( A > B ){
echo '<div class="option-a">';
}
else{
echo '<div class="option-b">';
}
?>
Then your CSS can be like
.option-a {
background-color:red;
}
.option-b {
background-color:blue;
}
No. But can you give an example what you have in mind? What condition do you want to check?
Maybe Sass or Compass are interesting for you.
Quote from Sass:
Sass makes CSS fun again. Sass is CSS, plus nested rules, variables, mixins, and more, all in a concise, readable syntax.
CSS itself doesn't have conditional statements, but here's a hack involving custom properties (a.k.a. "css variables").
In this trivial example, you want to apply a padding based on a certain condition—like an "if" statement.
:root { --is-big: 0; }
.is-big { --is-big: 1; }
.block {
padding: calc(
4rem * var(--is-big) +
1rem * (1 - var(--is-big))
);
}
So any .block that's an .is-big or that's a descendant of one will have a padding of 4rem, while all other blocks will only have 1rem. Now I call this a "trivial" example because it can be done without the hack.
.block {
padding: 1rem;
}
.is-big .block,
.block.is-big {
padding: 4rem;
}
But I will leave its applications to your imagination.
The #supports rule (92% browser support July 2017) rule can be used for conditional logic on css properties:
#supports (display: -webkit-box) {
.for_older_webkit_browser { display: -webkit-box }
}
#supports not (display: -webkit-box) {
.newer_browsers { display: flex }
}
The only conditions available in CSS are selectors and #media. Some browsers support some of the CSS 3 selectors and media queries.
You can modify an element with JavaScript to change if it matches a selector or not (e.g. by adding a new class).
I would argue that you can use if statements in CSS. Although they aren't worded as such. In the example below, I've said that if the check-box is checked I want the background changed to white. If you want to see a working example check out www.armstrongdes.com. I built this for a client. Re size your window so that the mobile navigation takes over and click the nav button. All CSS. I think it's safe to say this concept could be used for many things.
#sidebartoggler:checked + .page-wrap .hamb {
background: #fff;
}
// example set as if statement sudo code.
if (sidebaretoggler is checked == true) {
set the background color of .hamb to white;
}
CSS has become a very powerful tool over the years and it has hacks for a lot of things javaScript can do
There is a hack in CSS for using conditional statements/logic.
It involves using the symbol '~'
Let me further illustrate with an example.
Let's say you want a background to slide into the page when a button is clicked. All you need to do is use a radio checkbox.
Style the label for the radio underneath the button so that when the button is pressed the checkbox is also pressed.
Then you use the code below
.checkbox:checked ~ .background{
opacity:1
width: 100%
}
This code simply states IF the checkbox is CHECKED then open up the background ELSE leave it as it is.
css files do not support conditional statements.
If you want something to look one of two ways, depending on some condition, give it a suitable class using your server side scripting language or javascript. eg
<div class="oh-yes"></div>
<div class="hell-no"></div>
There is no native IF/ELSE for CSS available. CSS preprocessors like SASS (and Compass) can help, but if you’re looking for more feature-specific if/else conditions you should give Modernizr a try. It does feature-detection and then adds classes to the HTML element to indicate which CSS3 & HTML5 features the browser supports and doesn’t support. You can then write very if/else-like CSS right in your CSS without any preprocessing, like this:
.geolocation #someElem {
/* only apply this if the browser supports Geolocation */
}
.no-geolocation #someElem {
/* only apply this if the browser DOES NOT support Geolocation */
}
Keep in mind that you should always progressively enhance, so rather than the above example (which illustrates the point better), you should write something more like this:
#someElem {
/* default styles, suitable for both Geolocation support and lack thereof */
}
.geolocation #someElem {
/* only properties as needed to overwrite the default styling */
}
Note that Modernizr does rely on JavaScript, so if JS is disabled you wouldn’t get anything. Hence the progressive enhancement approach of #someElem first, as a no-js foundation.
Changing your css file to a scss file would allow you to do the trick. An example in Angular would be to use an ngClass and your scss would look like:
.sidebar {
height: 100%;
width: 60px;
&.is-open {
width: 150px
}
}
While this feels like a bit of a hack, and may not work perfectly in all browsers, a method I have used recently combines the fact that CSS (at least in Chrome) seems to ignore invalid values set on properties, and we can set custom properties that fall back to their default value when invalid.
(Note: I haven't deeply tested this, so treat it as a hacky proof of concept/possible idea)
The following is written in SCSS, but it should work just as well in standard CSS:
.hero-image {
// CSS ignores invalid property values
// When this var is set to an image URL, the browser will ignore it
// When this var isn't set, then we will use the default fallback for the var, which is 'none'
display: var(--loading-page-background-image, none);
// This part isn't directly relevant to my 'if' example, but shows how I was actually using this custom property normally
background-image: var(--loading-page-background-image, none);
}
I'm setting the custom property from JavaScript / React, but it would likely work regardless of how you set it:
// 'true' case
const chosenLoaderUrl = "https://www.example.com/loader.png";
// 'false' case
//const chosenLoaderUrl = "";
// containerRef is just a reference to the div object, you could get this with
// jquery or however you need. Since I'm in React, I used useRef() and attached
// that to my div
containerRef.current.style.setProperty(
"--loading-page-background-image",
`url(${chosenLoaderUrl})`
);
When chosenLoaderUrl is set to my url, that url is an invalid value for the display property, so it seems to get ignored.
When chosenLoaderUrl is set to an empty value, it falls back to the default value in my var() statement, so sets display to none
I'm not sure how 'generalisable' this concept it, but figured I would add it to the other suggestions here in case it is useful to anyone.
Your stylesheet should be thought of as a static table of available variables that your html document can call on based on what you need to display. The logic should be in your javascript and html, use javascript to dynamically apply attributes based on conditions if you really need to. Stylesheets are not the place for logic.
You can use combination of jquery and css classes i.e. I want to change a font color of certain element depending on the color of the background:
CSS:
.h3DarkMode{
color: lightgray;
}
.h3LightMode{
color: gray;
}
HTML:
<h3 class="myText">My Text Here...</h3>
JQuery:
var toggleMode = localStorage.getItem("toggleMode");
if (toggleMode == "dark"){
$(".myText").removeClass("h3LightMode").addClass("h3DarkMode");
}else{
$(".myText").removeClass("h3DarkMode").addClass("h3LightMode");
}
No you can't do if in CSS, but you can choose which style sheet you will use
Here is an example :
<!--[if IE 6]>
Special instructions for IE 6 here
<![endif]-->
will use only for IE 6 here is the website where it is from http://www.quirksmode.org/css/condcom.html , only IE has conditional comments. Other browser do not, although there are some properties you can use for Firefox starting with -moz or for safari starting with -webkit. You can use javascript to detect which browser you're using and use javascript if for whatever actions you want to perform but that is a bad idea, since it can be disabled.

Resources