LESS get inheritable property value - css

How to get LESS inheritable property value
ex:
.btn {
color: #000;
&:after {
color: darken(inherit, 15%);
}
}

The Less compiler compiles Less code into static CSS code and does not compute any property value. The Browser use the static CSS code to compute the value for the CSS properties.
The inherit property value is a reference to the computed value of the same property of its parent. At (Less) compile time this reference, and even the computed value of the parent do not exist. The darken() function is a built in of Less and run at compile time. So the darken() function can not have inherit as input value (a color value is required).
In the comments #seven-phases-max tells you to use variables, than your code should look something like that shown below:
#buttoncolor: #000;
.btn {
color: #buttoncolor;
&:after {
color: darken(#buttoncolor, 15%);
}
}
Notice that the use of the inherit property value it self is not forbidden in Less. For instance the following Less code will compile in valid and working CSS code:
a {
color: red;
&:hover{
color: inherit;
}
}
For the same reasons one could expect that you should be allowed to use the inherit property value in CSS(3) functions, such as width: calc(inherit - 2em); Also that is not possible although for different reasons, see CSS calc with inherit

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;
}
}

How to refer parent property within nested rule with the same name

I am trying to reuse a background-color definition of the parent rule set in background-color definition of a child rule set. However, Less evaluates the lookup as a recursion.
I would like this:
.button {
background-color: whitesmoke;
&:hover {
background-color: darken($background-color, 10%);
}
}
to work the same way as this:
#the-color: whitesmoke;
.button {
background-color: #the-color;
&:hover {
background-color: darken(#the-color, 10%);
}
}
but without the need for an extra variable.
The documentation isn't very specific on this. Am I missing something or is this just not possible?
I am aware of other solutions to changing the tint of a button on hover (e.g. using the filter property).
EDIT 1:
The closest I can get to is this. I just need it to be background-color instead of color.
.button {
background-color: whitesmoke;
&:hover {
color: darken($background-color, 10%);
}
}
The problem is the lookup of $background-color evaluates to the background-color of the same row (which, I think, doesn't ever make sense) and refuses to compile instead of evaluating to a rule in the parent rule set or just simply evaluating to one of the previous rows.

Is there a way to assign the same value to 2 css properties at once?

Using CSS, LESS, or Sass can you assign the same value to 2 css properties at once?
Just like:
.c1, c2 {sameValue}
But instead like this:
.c2 { background-color:, color: sameValue}
You can't do this with CSS.
The easiest way to do this is use a variable. Here's how you'd do that in LESS
#color: red;
.demo {
background-color: #color;
color: #color;
}
and the same thing in Sass
$color: red;
.demo {
background-color: $color;
color: $color;
}
But you can also achieve the power you want. Here's one way you could do it in LESS:
.properties(#properties, #value, #i: 0) when (#i < length(#properties)) {
#property: extract(#properties, #i + 1); // get the property
#{property}: #value; // write the style
.properties(#properties, #value, (#i + 1)) // loop
}
.demo {
#props: background-color, color;
.properties(#props, red)
}
will compile to your desired
.demo {
background-color: red;
color: red;
}
How's it work?
.demo calls the .properties parametric LESS mixin, passing a list (sometimes called an array in other SO questions about CSS/etc) of properties (.properties's #properties parameter; in this example, #props) and the value to assign to all of them (.properties's #value parameter; in this example, red).
note that .properties has a counter parameter #i with a default value of 0.
.properties has a LESS CSS guard that checks to see if #i is less than the number of properties it was passed (held in #properties). It is! (#i is 0, and the properties' list is certain to be at least 1) Okay, so we're allowed past the guard.
Get the name of the property: use LESS's extract() on the first item in the list (we need to say #i + 1 because we started the #i counter at 0. we could have also started #i at 1, and guarded with when (#i < (length(#properties) + 1)) but that's harder to read)
At last: write the style. interpolate the variable holding the property name (#property) as a string (#{property}), and give it the value we originally passed to .properties in .demo (#value)
LESS loop! Run .properties again, but advance the counter #i one: .properties(staysTheSame, staysTheSame, (#i + 1))
.properties will run until it's looped through all the items in its #properties list. After that, #i will equal length(#properties), so we won't pass the when (#i < length(#properties)) guard.
Note that #props could be defined within .test, as above, or anywhere where .test will have access to it, and same for the value. You might end up with
#props: background-color, color;
#val: red;
#val2: green;
.properties {...}
.demo {
border-color: #val2;
.properties(#props, #val)
}
.demo2 {
.properties(#props, #val2)
}
If your browser supports Custom Properties (AKA CSS Variables) you can define a custom property for reuse:
.foo {
--example: red;
background-color: var(--example);
color: var(--example);
}
Otherwise you'll need to rely on a preprocessor such as LESS:
.foo {
#example: red;
background-color: #example;
color: #example;
}
or Sass:
.foo {
$example: red;
background-color: $example;
color: $example;
}
As far as being able to chain properties, I'm not aware of any preprocessor or specification that allows for that syntax.
I don't think you can in the way you described, you would need to use a variable. However you can achieve something similar with properties that share the same namespace.
.funky {
font: {
family: fantasy;
size: 30em;
weight: bold;
}
}
http://sass-lang.com/documentation/file.SASS_REFERENCE.html#nested_properties
In Stylus is possible to do the Property lookup, which allows you to use properties in the current or closest parent ancestor and use it for calculations.
For you specific case you could write:
.demo
color: red
background-color: #color
which produces this CSS:
.demo {
color: red;
background-color: red;
}
It is a feature asked also for LESS but currently there are not plans to develop it. Currently in LESS (and in SASS) you must use one of already suggested solutions, passing by an additional variable.
With Stylus you can do this way using iteration and interpollation :
.modal
position : absolute
for bord in top bottom left right
{bord}: 1em
for larg in width min-width height min-height
{larg}: auto
for maxl in max-width max-height
{maxl}: none

Is it valid to assign a value twice to the same property within one rule?

Consider this:
h1 { color: red; color: blue }
Or, a more complex example (taken from a SVG file, stroke is twice):
style="fill:none;stroke:#ffffff;stroke-width:20;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke:#555555"
It seems that the answer is “it’s legal, the last assignment wins”, but I’d really like to know: Is there something written in the CSS specification about this topic?
It is valid to have multiple declarations that assign a value to a property so that the assignments apply to the same element, e.g.
h1 { color: red; }
h1 { color: blue }
Combining the declarations in the same rule does not change this.
There is no explicit statement about this in CSS specifications, so it is allowed simply because there is no rule that forbids it. Multiple declarations are very common, though mostly so that they are in different rules, often even in distinct style sheets. But they can also be used within a rule. A common technique is
p { max-width: 25em; max-width: 60ch }
which means that older browsers that do not recognize the ch unit will use the setting max-width: 25em, whereas in newer browsers, the latter declaration takes effect.
A general rule in CSS is that all other things being equal, latter declaration wins; this is part of the cascade rules. In the case of h1 { color: red; color: blue }, all other things are equal. But in h1 { color: red !important; color: blue }, the first declaration would win.
It is COMPLETELY VALID, h1 { color: red; color: blue } here color will simply be overridden by the next property value i.e blue
Even I use that while my website is in development mode, I often use border: 1px solid #f00; to create a blueprint of the page.

Is it possible to use previous class declaration in new definition in CSS?

I've tried to find the answer, and can't seem to do so, which is leading me to believe that it isn't possible. With my minimal knowledge of how CSS works, I also don't think it would be possible, but I just want to ask before I start working around a problem that may or may not exist.
Basically what I'm trying to do is use a previously defined attribute in a new class in my CSS stylesheet. For instance, say I had a couple of classes that just held background or font colors, like this:
.black { background-color: #000000; color: #000000; }
.white { background-color: #FFFFFF; color: #FFFFFF; }
Now if I was defining a new class (or using any selector for that matter), would it be possible to use the value of an attribute from an already existing class? Here is what my idea would look like:
.newClass {
width: 100%;
height: 100%;
background-color: .black; /* this would just get the background-color attribute from the .black class definition */
}
background-color: .black; is basically just a placeholder for "get the background-color attribute from the .black class definition". Is that possible using purely CSS? I'm aware of a ton of alternatives with PHP/JS, but I'd like to know if CSS can tackle this by itself. Thanks guys.
SASS is a thing to go. Your code will be like
#mixin black-theme {
.black { background-color: #000000; color: #000000; }
}
.newClass {
width: 100%;
height: 100%;
#include black-theme;
}
SASS
PHP compiler for SASS PHPSASS
There are javascript based solutions too like LESS but I generally don't recommend them as if Javascript load slow then presentation becomes jerky.
No, this is not currently possible in CSS. CSS does not have variables or the ability to reference values from previous rules. You would have to look for a CSS preprocessing language that gets processed into plain CSS before going onto the web site.
If you're willing to go the preprocessed way, you can look at SASS or LESS.
Yea possible using SASS or LESS css
#bgcolor : black;
.newClass {
width: 100%;
height: 100%;
background-color:#bgcolor;
}

Resources