Dynamic CSS properties in LESS?
Below is the solution that lets you write your styles once using LESS, then compile them to be two different css stylesheets for both rtl, and ltr layouts.
basically we'll have three LESS files (they can be more!):
style-ltr.less // this where we hold the rtl variables
style-rtl.less // rtl variables
main.less // here we'll write our styles
in style-ltr.less
define the following variables:
@left: left;
@right: right;
@import "main.less";
while in style-rtl.less
they will have the following values:
// reflect variables
@left: right;
@right: left;
@import "main.less";
now in main.less
, we'll define the following mixins
.left(@distance) when (@left = left) {
left: @distance;
}
.left(@distance) when (@left = right) {
right: @distance;
}
.right(@distance) when (@right = right) {
right: @distance;
}
.right(@distance) when (@right = left) {
left: @distance;
}
// now we can style our elements using these mixins
div.something {
position: relative;
.left(10px);
float: @left;
}
now all we have to do is to include style-rtl.less
in rtl pages include (or the compiled css version),
as well to include style-ltr.less
in ltr pages, and div.something
will be floated to the left on ltr pages, while it will be floated to the right on the rtl pages
Note that you can define padding, margin, border-radius ...etc.
using the same way here.
UPDATE
I created two projects on github to help building a bi-directional applications
- bi-app-less
- bi-app-sass
Credits:
inspired by my dear friend Victor Zamfir
Best approach for dynamic properties in LESS compiled css
If you have preset color options, one possible method is to add a data-
attribute to the body
tag with the name of the preset color theme. Then use LESS to automatically generate the styles for all the color combinations.
The attribute is the only part that gets dynamically changed:
<body data-theme="blue">
In the LESS, first define your colors:
@theme-red: #f00;
@theme-orange: #ffa500;
@theme-green: #080;
@theme-blue: #00f;
@theme-purple: #800080;
@theme-pink: #ff69b4;
Then create an array of the theme names so you can loop through the options. Make sure the strings match the color variable names above:
@theme-options: 'red', 'orange', 'green', 'blue', 'purple', 'pink';
@theme-count: length(@theme-options);
Then create a mixin that is used to generate the styles for all themes.
Note that there is a default option supplied in case there is no valid data-theme
attribute. This way you can have one of your colors be the default and/or you can define other default styles easily. This part isn't totally necessary if you are already defining default styles, but I found it useful, so I included it just in case it can help you:
.theme-color (@property, @default: @theme-blue) {
& { @{property}: @default; }
.loop-themes();
}
.loop-themes (@i: @theme-count) when (@i > 0) {
.loop-themes((@i - 1));
@color: extract(@theme-options, @i);
@theme-var: 'theme-@{color}';
body[data-theme=@{color}] & { @{property}: @@theme-var; }
}
Anywhere in the rest of your CSS that you are defining a "dynamic" style, just use the mixin like this when you want to use the preset default:
a {
.theme-color(background-color);
}
... and like this when you want to use a custom value for the default:
a {
.theme-color(background-color, #000);
}
Of course, the one downside to this is that all of your styles for all the colors are loaded no matter which theme you're using, but it's up to you to decide if it's worth it or not.
Create dynamic less mixin setting property names
LESS does not currently support dynamic CSS properties. This lack of support for dynamic properties is one point of criticism which some argue is an advantage of SASS over LESS. There do exist pull requests on certain libraries (eg, less.js) which add this capability.
Otherwise, you are pretty much stuck doing what you didn't want to do, namely:
.margin (@px,@side,@abbr) when (@side = left) {
(~".m@{abbr}@{px}") { margin-left: ~"@{px}px"; }
}
.margin (@px,@side,@abbr) when (@side = right) {
(~".m@{abbr}@{px}") { margin-right: ~"@{px}px"; }
}
Can you use a variable as the CSS Property and Value with LESS?
Simple answer is not yet.
But seems like it might be soon (in the next LESS release perhaps). See this thread https://github.com/less/less.js/issues/36 and it seems like @seven-phases-max is working on it at the moment (see here)
So only a tiny bit more patience =)
Here I posted a possible workaround a while ago:
- Using variables in property names in LESS (dynamic properties / property name interpolation) (a bit hacky but it works, while waiting for the official release of property interpolation in LESS)
Update:
As of LESS 1.6 (changelog) property name interpolation is possible.
Your mixin would look like this in LESS:
.browserPrefix(@property; @value){
-webkit-@{property}: @value;
-moz-@{property}: @value;
-ms-@{property}: @value;
-o-@{property}: @value;
@{property}: @value;
}
Generate dynamic css based on variables angular
Direct approach available in angular is using ngstyle as follows
<div [ngStyle]="{'color': style.colorVal ? style.colorVal : '#000', 'font-size' : style.fontSize ? style.fontSize : '16px' }"></div>
After going through different methods and approached to add dynamic css to all pages on angular app I ended up with following solutions.
Requirement : generate dynamic css based on values returned from and API to change design and styling.
Solution :
- create a new component and create a service to load dynamic css variables from API.
- Add style tag in template file and use variable values for properties.
- Load this template on all pages or on main template.
- On app build style will be moved to head tag.
Code sample
import { CssService} from './Css.service';
@Component({
selector: 'DynamicCss',
templateUrl: './DynamicCss.component.html',
styleUrls: ['./DynamicCss.component.scss']
})
export class ServiceProviderComponent implements OnInit {
cssVariables: any;
constructor(private cssService:CssService){
/* call the service/api to get the css variable values in cssVariables */
}
}
Now apply css using jquery or javascript to append css with help of function like following
appendCss(customData)
{
let text = '.custom-form-1 {
background-image: url("`+customData.background_image+`");
}';
$(document).ready(function(){
$("style").append(text);
});
}
and call this function after loading custom data from service or other variable like I did it ngOnInit
ngOnInit(){
this.appendCss(this.customizeFormData);
}
Its using jquery but can be done with javascript/typescript as well if you dont want to use jquery in your angular app
Other useful resource https://github.com/angular/angular/issues/9343#issuecomment-312035896
less css calling dynamic variables from a loop
I have just been trying todo the same thing today with LESS. The solution I came up with is to use a Parametric Mixin to create (define) the variable, see updated exmaple:
@color1:#06A1C0;
@color2:#8F4F9F;
@color3:#ED1D24;
@color4:#5A9283;
@color5:#B38C51;
@color6:#EC008C;
@color7:#8F4F9F;
@iterations: 7;
.define(@var) {
@colorSet: 'color@{var}';
}
.mixin-loop (@index) when (@index > 0) {
color@{index}:hover{
.define(@index);
color: @@colorSet;
}
.mixin-loop(@index - 1);
}
.mixin-loop (0) {}
.mixin-loop(@iterations);
Hope this helps.
How have dynamic class names in LESS CSS and use them as values in function
You have to create a list of colors first before creating a loop:
.make-classes(@prefix, @list) {
.iter(length(@list));
.iter(@i) when (@i > 0) {
.iter(@i - 1);
@pair: extract(@list, @i);
@key: extract(@pair, 1);
@value: extract(@pair, 2);
.@{prefix}.color-@{key} {
color: @value;
}
}
}
@colors:
~'blue' #7FB3D4,
~'gray' #767676,
~'green' #8CC079,
~'red' #b35d5d;
.make-classes(link, @colors);
Output:
.link.color-blue {
color: #7fb3d4;
}
.link.color-gray {
color: #767676;
}
.link.color-green {
color: #8cc079;
}
.link.color-red {
color: #b35d5d;
}
Related Topics
Angular 6 Load CSS Folders in Angular.JSON
Put Title/Alt Attributes into CSS: After { Content: Image }
How to Style Radio Button or Checkbox Inside a Bootstrap Table
How to Make Cross Browser Gradient Mixin in Compass, with Ie9, Ie8, Ie7 and Opera
CSS Effect to Render a Font with "Rubber Stamp" Effect
How to Remove Extra Space After a Colon in CSS with Sublime Text 2
Difference Between Variable Fonts and Regular Fonts
How to Iterate Keyframe Percentages Less CSS
Javafx: Styling Application with CSS Selectors
How to Make a Gradient Flow in Multiple Directions
Custom CSS for Mobile Development Using Phonegap/Cordova
Position Relative, Float Takes Div Out of The Normal Flow
Sizing Width of an Element as a Percentage of Its Height or Vice Versa in a Fluid Design
Cache Busting Images Which Are Linked Inside SASS Files
What Is The Meaning of an Ampersand in Less Selectors