It is easy to explain what I want using an example.
I want to achieve something like
.someClass {
#aVariable: 100px;
/*
if(along with .someClass .anotherClass is present) {
#aVariable = 200px;
}
*/
/*#aVariable is used here */
}
The point is to set #aVariable depending on the another class presence.
I saw the answer, but it did not work out for me.
.someClass {
#aVariable: 100px;
/*#aVariable should be used here */
&.anotherClass {
#aVariable: 200px;
/*2nd #aVariable should be used here. this will overide above css*/
}
}
i have:
#mydiv { height: 100px; }
i want to change height by replace, but i have to add e.g. 50 px
#mydiv { height: OLD_VALUE + 50px; }
Is it possible without js?
I don't think so. You have to use JS for this.
But you can use margins or paddings to increace distance in certain direction
P.S. In JS you can use +=50px for that
You can use CSS3 calc though you'll need to be wary of support
You can't -- CSS doesn't have any notion of this. While you may be able to do something like using CSS3 variables and calc, it would require the original CSS file to use the variables.
First file:
:root {
var-height: 100px;
}
#myDiv {
height: var(height);
}
Your file:
#myDiv {
height: calc(var(height) + 50px);
}
The best/typical approach to this would be to do it via Javascript, or otherwise something like SASS.
Friends,
can i use css as a nested functions and how to get the current css properties of element like as follow
.button1:active
{
#button2
{
width:width+20px;
}
}
Not with standard CSS.
You can do.
.button1:active #button2 {
width:20px;
}
However you can in LESS, SASS or SCSS.
With LESS you could do.
#elementWidth: 20px;
.button1:active {
#button2 {
width: #elementWidth + 20px; //Resulting width would be 40px
}
}
You can write like:
.button1:active #button2{
width:20px;
}
Use CSS pre-processors LESS or SASS to achieve this.
I'm using LESS CSS 1.3.3. Sorry if this question has already been asked, I didn't find anything relevant on the web.
I have several class generators that look like this (example extremely simplified, just enough to trigger the error):
#genMarginTop (#name, #size) {
.#{name} { margin-top: #size; }
}
Then I use them to generate some actual classes:
#genMarginTop(mtStandard, 40px);
#genMarginTop(mtHalf, 20px);
So far, so good, LESS correctly generates those classes and I can use them in the HTML.
However when I want to reuse such a generated class as a mixin somewhere else, I get an error:
.someClass {
.mtStandard; // won't work, see error below
// more stuff
}
The error I get is:
NameError: .mtStandard is undefined in /.../example.less:161:4
160 .someClass {
161 .mtStandard;
162 // more stuff
Of course I try to use the mixin after the class has been generated. It looks like LESS somehow won't register such generated classes internally after it generates them, but I could well be wrong.
Is there a way to reuse such generated classes as mixins in other classes? Being quite new with LESS, and their documentation being rather sparse about generated classes, I'm at a total loss (especially since this is the only syntax that seems to be accepted for mixins).
Thanks for reading me.
Note: The reason why I use such class generators is because they are much more complex than the example above (think nested classes that all depend on a common set of parameters), and I'm embedding the generated classes in various #media queries to support any device type in a "Zen" fashion. In the end I get something like:
#media (max-width: 1024px) {
#genSomething(something, somethingParam1, ...);
#genSomething(somethingElse, somethingElseParam1, ...);
#genStuff(stuff, stuffParam1, ...);
}
#media (max-width: 240px) {
#genSomething(something, somethingParam2, ...);
#genSomething(somethingElse, somethingElseParam2, ...);
#genStuff(stuff, stuffParam2, ...);
}
// etc
Solution / test case
Here's a test case for #MartinTurjak 's solution, I can confirm that this works as expected, nested classes and everything:
.explicit {
margin-top: 1;
input { margin-top: 1; }
}
.reuseExplicit {
.explicit;
margin-bottom: 1;
}
#generator (#arg) {
margin-top: #arg;
input {
margin-top: #arg;
}
}
.generated { #generator(1); }
.reuseGenerated {
.generated;
margin-bottom: 1;
}
Which correctly generates: (notice how explicit/generated yield the very same result)
.explicit {
margin-top: 1;
}
.explicit input {
margin-top: 1;
}
.reuseExplicit {
margin-top: 1;
margin-bottom: 1;
}
.reuseExplicit input {
margin-top: 1;
}
.generated {
margin-top: 1;
}
.generated input {
margin-top: 1;
}
.reuseGenerated {
margin-top: 1;
margin-bottom: 1;
}
.reuseGenerated input {
margin-top: 1;
}
Unfortunately. The selector interpolation is just string interpolation, and the string gets then printed into css, so no class object is generated in the less run.
So you can design a generator/mixin, that includes your operation:
#genMarginTop (#size) {
margin-top: #size;
}
But then build classes by calling the mixins / generators:
.mtStandard {#genMarginTop(40px);}
.mtHalf {#genMarginTop(20px);}
And this way they are class objects that you can use for mixin =)
.someClass {
background-color: #FFF;
.mtStandard;
//more of this stuff
}
This looks a bit silly in this simple example, but maybe something like this:
#bggenerator (#color) {
background-color: #color;
}
#bggenerator (#color, dark) {
#blend : #color + #842210;
background-color: darken(#blend, 30%);
}
#bggenerator (#color, #url, #rest) {
background: "#{color} url('#{url}') #{rest}";
}
.mtStandard {
#genMarginTop(40px);
}
.someClass {
.mtStandard;
#bggenerator(#FFF, "bgimage.png", left top no-repeat);
//more of this stuff
}
Or something that does even more exciting stuff with the arguments
UPDATE LESS 1.7+ (Works as Desired)
The .#{name} syntax will now work just as the original question had desired.
LESS 1.4+ Workaround to Actually Use Dynamic Class Names
I came up with a work around for this while working on another question, so I'm posting it as a second answer, since it goes in a totally different direction than my earlier answer.
This solution requires a couple of steps (so is not as convenient as a final fix in LESS would be), but would give actual functionality of being able to use dynamically generated class names.
First: Define your dynamic classes
This is just as you planned.
#genMarginTop (#name, #size) {
.#{name} { margin-top: #size; }
}
#genMarginTop(mtStandard, 40px);
#genMarginTop(mtHalf, 20px);
Second: Compile that file into CSS
So lets say you compile your dynamicClasses.less into dynamicClasses.css. This causes the dynamic class names to "resolve" to actual classes.
Third: Import that CSS as LESS into a 2nd LESS file that uses the dynamic class names
Using type casting for #import, we do this:
#import (less) dynamicClasses.css;
This takes those resolved class names in the dynamicClasses.css file and imports them as LESS, which makes all the class names now available as mixins. So you can do as you desired:
.someClass {
.mtStandard; // will work
// more stuff
}
I agree. It looks like LESS does not register those classes for mixin purposes.
Incomplete Solution
This LESS code:
#genMarginTop (#name, #size) {
#genMarginTopNameCheck: #name;
.get(#name) when (#name = #genMarginTopNameCheck) { margin-top: #size; }
.#{name} { .get(#name); }
}
#genMarginBot (#name, #size) {
#genMarginBotNameCheck: #name;
.get(#name) when (#name = #genMarginBotNameCheck) { margin-bottom: #size; }
.#{name} { .get(#name); }
}
#genMarginTop(mtStandard, 40px);
#genMarginBot(mbStandard, 20px);
#genMarginTop(mtSpecial, 80px);
.myClass {
.get(mtStandard);
.get(mbStandard);
}
.myClass2 {
.get(mtSpecial);
.get(mbStandard);
}
Generates this CSS
.mtStandard {
margin-top: 40px;
}
.mbStandard {
margin-bottom: 20px;
}
.mtSpecial {
margin-top: 80px;
}
.myClass {
/* NOTE the mtStandard definition is missing here !!! */
margin-bottom: 20px;
}
.myClass2 {
margin-top: 80px;
margin-bottom: 20px;
}
Explanation and Disscussion of Final Issue to Resolve
Each mixin is defining a guarded .get() mixin based off the #name to get the styles, and that is cross checked to a unique NameCheck variable name for that mixin. All your actual code is defined in the .get(), and that mixin is used to actually generate the .#{name} class code.
This works fine every time for generating the actual class name. However, the getter function at present is only working for the class name last defined by a use of the mixin. So as you can see above, my get call for mtStandard is not working because my setting of mtSpecial has apparently overwritten the #genMarginTop .get() mixin with the mtSpecial definition.
Now I assume you are going to want to call #getMarginTop and your other such mixins more than once, so obviously this is still an incomplete solution. I've figured out how you can get the class generated by the top level mixin to be used as a 'mixin' for another class using the .get(), but I haven't figure out how to make the .get() not get overridden when the top level mixin is called again.
I want to set a width in percentage in scss via calculation, but it gives me errors..
Invalid CSS after "...-width: (4/12)%": expected expression (e.g. 1px,
bold), was ";"
I want to do something like
$my_width: (4/12)%;
div{
width: $my_width;
}
how do I add the % sign in there?
Same question with px and em
Have you tried the percentage function ?
$my_width: percentage(4/12);
div{
width: $my_width;
}
UPDATE
This function was updated since version 1.33.0 and now this is a correct method to do it:
#use "sass:math";
div {
width: math.percentage(math.div(4,12));
}
Source: https://sass-lang.com/documentation/modules/math#percentage
Another way:
$my_width: 4/12 * 100%;
div {
width: $my_width; // 33.33333%
}
Sass will output the value in %.
I was able to make it work this way:
div{
width: (4/12)* 1%;
}
This way you don't need to use any special function.
If you wanna use a loop, maybe this solution will be working
#for $i from 1 through 12 {
.col-#{$i} {
width: #{calc(100 * $i / 12) + '%'};
}
}