How to generate #page with loop in less - css

I am not familiar with complex script in less but, I search to use a loop in order to create the following CSS:
#page page_00_recto {
....
size: A4
margin-top: 00mm;
}
#page page_01_recto {
....
size: A4
margin-top: 00mm;
}
...
I have tried this
each(range(1, 100, 1), {
#page page_{#index}_recto {
size: 110mm 240mm;
margin-top: #value;
};
});
...
But I obtains always this error
#page tab_{#index}_recto {
#index rule is missing block or ending semi-colon
Where is my error? thank you in advance for your help

You must be using Less >3.9
You must escape # in #page
You should be using dynamically built selector
So final LESS code looks like this:
each(range(1, 100, 1), {
#selector: ~"#page page_#{index}_recto";
#{selector} {
size: 110mm 240mm;
margin-top: #value;
};
});

Related

How to get division and math function to work on variable map item(s) in less

I'm relatively new to less and I have this less code which I want to compile down to css (the .song block specifically). I'm learning through a course.
Less code:
#breakpoints: {
desktop: 989px;
tablet: 767px;
phone: 480px;
};
#media only screen and (min-width: #breakpoints[desktop]) {
#minWidth: #breakpoints[desktop];
.container {
width: #minWidth;
}
/*Division*/
.song {
width: #breakpoints[desktop] / 3;
}
/*With ceil function*/
.song {
width: ceil(#breakpoints[desktop] / 3);
}
}
When I divide the number, it doesn't give an error but doesn't work as intended.
Instructors css output:
.song {
width: 329.66666667px;
}
My own css output:
.song {
width: 989px / 3;
}
When I'm using a math function like ceil, it gives an error:
Instructors css output:
.song {
width: 330px;
}
My own result (error):
ArgumentError: Error evaluating function ceil: argument must be a number
I have knowledge of javascript so I get what the error means. What I don't understand is how, for the same code I wrote above, the instructor's code compiled fine but mine doesn't. I tried browsing but I haven't gotten any answer that addresses this issue. The instructor used lessc version 3.8.1, I'm using lessc version 4.1.0. Any help will be really appreciated. Thanks.
I've been able to get the calculation to work by inserting the expressions in parenthesis like so:
Division:
.song {
width: (#breakpoints[desktop] / 3);
}
Ceil function:
.song {
width: ceil((#breakpoints[desktop] / 3));
}
Got answer at github issue/thread from this particular comment.

How to change ag-grid row group indent?

I want to change (increase/decrease) the magnitude of indent (current default is 28px) for each inner group in my Tree Data. However, I could not find any configuration options for the same in the documentation. The closest thing I could find was suppressPadding, which disables padding altogether. I tried using DOM piercing CSS but found that every level has a different CSS class (ex. ag-row-group-indent-2), which makes writing a general CSS rule in my container component difficult.
Currently, I'm overriding the style in a loop, which seems to be working
// Taken from https://github.com/ag-grid/ag-grid/blob/master/dist/styles/ag-theme-base/sass/parts/_grid-layout.scss
// support 20 levels here because row group indentation is used for tree data which can be quite deep
#for $i from 1 to 20 {
.ag-row-group-indent-#{$i} {
padding-left: $i * 8px;
}
.ag-row-level-#{$i} .ag-row-group-leaf-indent {
margin-left: 40px;
}
}
You can add a cellStyle callback that computes the padding-left value for each cell based on its current group level.
defaultColDef: {
cellStyle: (params) => {
const { level } = params.node;
const groupCell = params.value === params.node.key;
const indent = 28; // change this value to your liking
if (groupCell) {
return {
paddingLeft: (level + 1) * indent + "px"
};
}
}
},
If you use this approach, remember to suppress the initial css padding value from agGrid or both agGrid and your padding values will add up.
::ng-deep .ag-cell-wrapper.ag-row-group[class*="ag-row-group-indent"],
::ng-deep .ag-cell-wrapper.ag-row-group-leaf-indent[class*="ag-row-group-indent"] {
padding-left: 0;
}
Live Demo
If you're using SCSS and theming, you can change the indent by setting the value of row-group-indent-size, like this:
:root {
#include ag-theme-balham((
row-height: 20px,
cell-horizontal-padding: 8px,
row-group-indent-size: 18px
));
}
Reference: https://www.ag-grid.com/javascript-data-grid/global-style-customisation-variables/

Display page length and pagination in the same line jquery dataTables

Is there any way to display the page-length option and paginate option in the same line? This is how I got:
Is there any way to override their css and display them in the same line? They both are in two separate div. I've added "jquery.dataTables.min.css" and "bootstrap.min.css".
Use dom option to construct the layout for Bootstrap framework.
var table = $('#example').DataTable({
dom: "<'row'<'col-sm-12'tr>>" +
"<'row'<'col-sm-4'l><'col-sm-8'p>>"
});
See this jsFiddle for code and demonstration
edit: Ah, I realized I can't reply to a comments in comment, I hope the OP can sees this.
simply add the character i for information
as example, if you want to have i after l, then put as below
var table = $('#example').DataTable({
dom: "<'row'<'col-sm-12'tr>>" +
"<'row'<'col-sm-4'li><'col-sm-8'p>>"
});
else you can even let i have it's own col-sm, as follows (note that I decreases pagination, p from 8 to 4 in order to fit into 12 division of 'row' by bootstrap standard.
var table = $('#example').DataTable({
dom: "<'row'<'col-sm-12'tr>>" +
"<'row'<'col-sm-4'l><'col-sm-4'i><'col-sm-4'p>>"
});
on bootstrap 4 I overide by
"language": {
"sProcessing": "กำลังดำเนินการ...",
"sLengthMenu": "แสดง_MENU_ แถว",
"sZeroRecords": "ไม่พบข้อมูล",
"sInfo": "แสดง START ถึง END จาก TOTAL แถว",
"sInfoEmpty": "แสดง 0 ถึง 0 จาก 0 แถว",
"sInfoFiltered": "(กรองข้อมูล MAX ทุกแถว)",
"sInfoPostFix": "",
"sSearch": "ค้นหา:",
"sUrl": "",
"oPaginate": {
"sFirst": "เิริ่มต้น",
"sPrevious": "ก่อนหน้า",
"sNext": "ถัดไป",
"sLast": "สุดท้าย"
}
},
Just override Datatable CSS class .dataTables_wrapper .dataTables_length by adding new property as per below.
.dataTables_wrapper .dataTables_length {
white-space: nowrap;
}
In my case i've tried to achieve length,info and paginate at the bottom of the table. You can see the result below.
To achieve this, first you should set dom property of your DataTable.
dom: "<'row'<'col-sm-12'tr>><'row'<'col-sm-3'l><'col-sm-3'i><'col-sm-6'p>>"
After that put and customize the code below for your own needs, in your CSS file or between the <style> tags.
div.dataTables_wrapper div.dataTables_info {
padding-top: 1.7em;
}
div.dataTables_wrapper div.dataTables_length {
padding-top: 0.3em;
}
This solved my problem. But in case you need to style other properties of datatable, you are free to use the selectors below.
div.dataTables_wrapper div.dataTables_filter {
padding-top: 0.8em;
}
div.dataTables_wrapper div.dataTables_paginate {
padding-top: 0.8em;
}

& as sibling for mixin in LESS

I built a mixin to handle icon sprites in my solution, which basically loops through a list of class names and sets the background position relative to it's index in the sprite
#icon_size-small: 16;
#icon_size-medium: 24;
#icon_size-large: 32;
.commonIcons(#iconSize, #y: 1, #x: 0) {
#posY: (#iconSize * #y);
#posX: (#iconSize * #x);
background: url('images/icons/commonIcons#{iconSize}x#{iconSize}.png') -#posX + 0px -#posY + 0px no-repeat;
height: #iconSize + 0px;
width: #iconSize + 0px;
}
I then call this mixin inside of another one like this
.icons_list-small(#modifier, #x) {
.icon-clock { .commonIcons(#icon_size-small, 1, #x); }
.icon-checkmark { .commonIcons(#icon_size-small, 2, #x); }
.icon-stop { .commonIcons(#icon_size-small, 3, #x); }
etc
and the whole thing is then actually used like this
.small-button {
.icons_list-small(0);
}
So the background position is calculated based on which .icons_list-xxx I use, and the parameter I'm sending in in .small-button decides which y-index is shown (the sprite has 3 variants in a row).
This all works fine when generated as children inside of .small-button, but I've now run up against a case where I need the list generated as sibling selectors to .small-button (giving me .small-button.icon-clock { })
Implementing it like these examples gives me parse errors, understandably:
.small-button.icons_list-small(0);
or
.small-button {
&.icons_list-small(0);
}
So the question: does anyone have a suggestion for what I can do in this instance?
Thanks for any help guys!
Edit: I found a fix myself, but if anyone has a more elegant solution I'd be happy to hear it!
What I did was extend the .icons_list-small mixin like this
.icons_list-small(#modifier, #x) {
#{modifier}.icon -clock { .commonIcons(#icon_size-small, 1, #x); }
Which is then called like this
.icons_list-small(~".icon--inverted", 0);
One solution would be to use the & in your mixin:
.icons_list-small(#x) {
&.icon-clock {
.commonIcons(#icon_size-small, 1, #x);
}
&.icon-checkmark {
.commonIcons(#icon_size-small, 2, #x);
}
&.icon-stop {
.commonIcons(#icon_size-small, 3, #x);
}
}
And when you want to obtain the previous behaviour, to use:
.small-button {
& * {
.icons_list-small(0);
}
}
Which would generate
.small-button *.icon-clock {...}
...
that is equivalent (in CSS) to
.small-button .icon-clock {...}
...
And using it without the & *:
.small-button {
.icons_list-small(0);
}
will generate:
.small-button.icon-clock {...}
...

Defining Variable Variables using LESS CSS

Say I have three separate color schemes that are used on various pages in a site. Each color has a a light, medium and dark tint defined, and the color scheme is defined by a class in the body. Assume that the "red" color scheme is the default. Like this:
Color Definitions:
#red-lt: #121;
#red-md: #232;
#red-dk: #343;
#green-lt: #454;
#green-md: #565;
#green-dk: #676;
#blue-lt: #787;
#blue-md: #898;
#blue-dk: #909;
Basic Default Style Example
body { background-color: #red-dk;
#container { background-color: #red-md;
p { color: #red-dk; }
}
}
Different Color Scheme Style Example
body.green { background-color: #green-dk;
#container { background-color: #green-md;
p { color: #green-dk; }
}
}
I'd like to use variables so that I don't have to re-write all of the color variations for each scheme, so that I can just write something like this:
body.[color-var] { background-color: #[color-var]-dk;
#container { background-color: #[color-var]-md;
p { color: #[color-var]-dk; }
}
}
…but I can't quite wrap my head around how to accomplish that. Help…?
Use interpolation and escaping, parentheses in the selector and parametric mixins to get the desired effect:
Dynamic variables by interpolation: In a string, "#{variable}" is replaced with the value of the variable. They can also be nested: Given #{#{var}-foo} and #var: bar;, the result is "barfoo".
The resulting value is quoted. To remove these quotes, prefix ~.
Dynamic selectors by Selector interpolation: body.#{var} turns into body.bar.
Example:
#red-md: #232;
#red-dk: #343;
.setColor(#color) {
body.#{color} { background-color: ~"#{#{color}-dk}";
#container { background-color: ~"#{#{color}-md}";
p { color: ~"#{#{color}-md}"; }
}
}
}
.setColor(~"red"); // Escape to prevent "red" turning "#FF0000"
//.setColor(~"blue"); etc..
Turns into:
body.red {
background-color: #334433;
}
body.red #container {
background-color: #223322;
}
body.red #container p {
color: #223322;
}
Note: When the answer was originally written, selector interpolation did not exist. See the previous revision for the solution if you're working with an old LESS compiler (before LESS 1.3.1a). Support for the old method will be dropped in LESS 1.4.0.
If those values really follow a predictable format like that, seems like a perfect case for a parametric mixin:
Less:
#red: #232;
#green: #565;
#blue: #898;
.theme (#color) {
background-color: #color - #111;
#container {
background-color: #color;
p { color: #color + #111; }
}
}
body.red {
.theme(#red);
}
Compiled CSS:
body.red{background-color:#112211;}
body.red #container{background-color:#223322;}
body.red #container p{color:#334433;}
I know this question is pretty old, but for those that come to this post my answer maybe can help
I`m not really sure for what you want to use this, but one of my suggestion is based on #ScottS answer. On my real world, I need to create a web app, where it would show several brands and each brand have their own text color, background and so on... so I started to chase a way to accomplish this in LESS, what I could easily do on SASS and the result is below:
LESS
// Code from Seven Phase Max
// ............................................................
// .for
.for(#i, #n) {.-each(#i)}
.for(#n) when (isnumber(#n)) {.for(1, #n)}
.for(#i, #n) when not (#i = #n) {
.for((#i + (#n - #i) / abs(#n - #i)), #n);
}
// ............................................................
// .for-each
.for(#array) when (default()) {.for-impl_(length(#array))}
.for-impl_(#i) when (#i > 1) {.for-impl_((#i - 1))}
.for-impl_(#i) {.-each(extract(#array, #i))}
// Brands
#dodge : "dodge";
#ford : "ford";
#chev : "chev";
// Colors
#dodge-color : "#fff";
#ford-color : "#000";
#chev-color : "#ff0";
// Setting variables and escaping than
#brands: ~"dodge" ~"ford" ~"chev";
// Define our variable
.define(#var) {
#brand-color: '#{var}-color';
}
// Starting the mixin
.color() {
// Generating the loop to each brand
.for(#brands); .-each(#name) {
// After loop happens, it checks what brand is being called
.define(#name);
// When the brand is found, match the selector and color
.brand-#{name} & {
color: ##brand-color;
}
}
}
.carColor {
.color();
}
Te result will be:
CSS
.brand-dodge .carColor {
color: "#fff";
}
.brand-ford .carColor {
color: "#000";
}
.brand-chev .carColor {
color: "#ff0";
}
This is very tricky and I had to use several elements to get what I needed, first used a set of mixins provided by Seven Phase Max and you can find it here and than, the #ScottS answer was the piece that was missing fro my puzzle... hope this helps you and others that need to create a set of Variables to be part of another variable and create a more dynamic less file.
You can copy my entire code and test at http://lesstester.com/
Try this
#red-lt: #121;
#red-md: #232;
#red-dk: #343;
#green-lt: #454;
#green-md: #565;
#green-dk: #676;
#blue-lt: #787;
#blue-md: #898;
#blue-dk: #909;
#color: 'red-lt';
div{
background: ##color;
border: 1px solid lighten(##color,20%);
}
To my knowledge, variable variable names are not supported in LESS. You could however restructure your declarations in a more semantic manner:
/* declare palette */
#red-lt: #121;
#red-md: #232;
#red-dk: #343;
#green-lt: #454;
#green-md: #565;
#green-dk: #676;
#blue-lt: #787;
#blue-md: #898;
#blue-dk: #909;
/* declare variables based on palette colors */
#lt: #red-lt;
#md: #red-md;
#dk: #red-dk;
/* ...and only use them for main declarations */
body { background-color: #dk;
#container { background-color: #md;
p { color: #dk; }
}
}
This should let you switch between palettes quite painlessly by avoiding explicit color references.

Resources