Color white if background is black and vice-versa - less

I read about Properties as Variables in less
Now I like to have a h1-text-color depending of the background-color.
#black: black;
#white: white;
* when ($background = #black) > h1 {
color: #white;
}
* when ($background = #white) > h1 {
color: #black;
}
Unfortunately it does not work.
The processor (in java) drops me a:
org.lesscss.LessException: SyntaxError: expected condition in C:\Program Files\apache-tomcat-8.5.27\temp\tmp8751667891323027624less.tmp on line 11, column 9:
10
11 * when ($background = #black) > h1 {
12 color: #white;
at org.lesscss.LessCompiler.compile(LessCompiler.java:423)
at org.lesscss.LessCompiler.compile(LessCompiler.java:330)
at org.lesscss.LessCompiler.compile(LessCompiler.java:312)

The dependency
<dependency>
<groupId>org.lesscss</groupId>
<artifactId>lesscss</artifactId>
<version>LATEST</version>
</dependency>
Resolves compatible version of less 1.7. The feature is only available in 3.0.
dependency on github

Related

less function to generate css class

I try to do any less function which will be called to create some classes.
Here is the way I tried :
.makeCssColor{#couleur) {
.coul_#{couleur} {
background-color: fade(~"#{couleur}, 'Fonce'", 15%);
&.open, &:hover {
background-color: ~"#{couleur}, 'Fonce'";
}
.btMod {
background : url('/img/btModEvt_#{couleur}.png') left top no-repeat transparent;
}
}
}
And I try to call it to create the classes :
.makeCssColor("bleu");
.makeCssColor("rouge");
But it generate an error. I don't find the good way to do it... And it bothers me to repeat all these code for each color (there is more than these line code and more thant two colors !).
Can anyone give me a little help ? :)
[edit]
ok, thanks to your help, this code does not generate an error, but there is a mistake in the CSS file :
#marronFonce = #9d5a1e;
.makeCssColor(#couleur) {
.coul_#{couleur} {
.top {
background-color: #couleur, 'Fonce';
}
.mod {
background : url('/img/btModEvt_#{couleur}.png') left top no-repeat transparent;
}
}
}
.makeCssColor(marron);
Generate this into the css file :
.coul_marron .top{background-color:marron,'Fonce'}
.coul_marron background : url('/img/btModEvt_marron.png') left top no-repeat transparent;
So the background color isn't good :
.coul_marron .top{background-color:#9d5a1e}
.coul_marron background : url('/img/btModEvt_marron.png') left top no-repeat transparent;
I need to evaluate #couleur, 'Fonce' : #marronFonce => #9d5a1e.
I tried #{#couleur, 'Fonce'} but it doesn't works...
Fade function takes a colour and a fade percentage, in your case you are passing 2 colours. Pass them one at a time. I also made some adjustments on #couleur since i some cases they don't need to be escaped
.makeCssColor{#couleur) {
.coul_#{couleur} {
background-color: fade(#couleur, 15%), fade(Fonce, 15%);
&.open, &:hover {
background-color: #couleur, 'Fonce';
}
.btMod {
background : url('/img/btModEvt_#couleur.png') left top no-repeat transparent;
}
}
}
when you call the mixin use the below, no need to use quotes
.makeCssColor(bleu);
UPDATE - just pass it in
.makeCssColor(#couleur, #name) {
.coul_#{name} {
.top {
background-color: #couleur;
}
.mod {
background : url('/img/btModEvt_#{name}.png') left top no-repeat transparent;
}
}
}
then when you call it
.makeCssColor(#marronFonce, marron);
OR
other option is you can make a loop, it's more complicated but you can try it. I am using an example I already have on my computer
first define a variable with the colour and names
#sample:
~"0070" '#ebebe7',
~"08x2" '#00247a',
~"01k0" '#92918e';
then loops thru it
.sample-loop ( #l ) when ( #l > 0 ) {
#item: extract( #sample #l );
#code: extract( #item, 1 );
#colour: color(extract( #item, 2 ));
.ext-#{code} {
background-color: #colour;
}
.sample-loop( #l - 1 );
}
and finally call the loop to generate your classes
.sample-loop( 3 );
depending on which version of less you have, the 3 can coded so it is dynamic. If you have older version of less then you have to hard code the length of the variable, or assign the length to a variable so you can use it anywhere

Passing a variable list through .for loop using Less 2.6.1 is unable to compile

I have been using a Less mixin which makes looping in Less, less verbose and is really handy: https://github.com/seven-phases-max/less.curious/
I upgraded from Less 2.6.0 to Less 2.6.1 and now the Less will not compile.
Here's the Less code:
// ............................................................
// .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) when (#i > 0) {.-each(extract(#array, #i))}
#gray-base: #000;
#gray-darker: #222;
#gray-dark: #333;
#gray: #555;
#gray-light: #777;
#gray-lighter: #eee;
#gray-type:
gray,
gray-base,
gray-dark,
gray-darker,
gray-light,
gray-lighter;
.gray-type {
// Mixin to generate the gray font colours for p tags in the font stacks.
.for(#gray-type); .-each(#name) {
.#{name} {
color: ##name;
}
}
}
Here's the expected output:
.gray-type .gray {
color: #555;
}
.gray-type .gray-base {
color: #000;
}
.gray-type .gray-dark {
color: #333;
}
.gray-type .gray-darker {
color: #222;
}
.gray-type .gray-light {
color: #777;
}
.gray-type .gray-lighter {
color: #eee;
}
After upgrading to Less 2.6.1 I get the following error:
>> SyntaxError: variable #[object Object],[object Object] is undefined in less/style.less on line 41, column 3:
>> 40 // Mixin to generate the gray font colours for p tags in the font stacks.
>> 41 .for(#gray-type); .-each(#name) {
>> 42 .#{name} {
Warning: Error compiling less/style.less Use --force to continue.
I think the problem is related to the hyphens being stripped from the variables during compilation, therefore making the variables passed though the list invalid.
Any help would be greatly appreciated.

CSS Less -ms-filter mixin

I have the following CSS LESS mixin:
.transparency (#amount, #tranc) {
background: rgba(red(#amount), green(#amount), blue(#amount), #tranc);
}
and the way i use it is:
.transparency (#FFFFFF, 0.2);
but i need to find some way of including -ms-filter in the mixin... but i am not quiet sure, i used on online generator and it gave me this result:
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#B224417C,endColorstr=#B224417C)"; /* IE8 */
how would i include this? I mean the startColorstr and the endColorstr...
Any help Greatly Apreciated
Updated the function with the following:
.transparency (#colour, #alpha) {
#alphaColour: hsla(hue(#colour), saturation(#colour), lightness(#colour), #alpha);
#ieAlphaColour: argb(#alphaColour);
background-color: #colour; // Fallback for older browsers
background-color: #alphaColour;
// IE hacks
zoom: 1; // hasLayout
background-color: transparent\9;
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#{ieAlphaColour}, endColorstr=#{ieAlphaColour})"; // IE 8+
filter: ~"progid:DXImageTransform.Microsoft.gradient(startColorstr=#{ieAlphaColour}, endColorstr=#{ieAlphaColour})"; // IE 6 & 7
}

DecimalFormat : replace floats with spaces

We need to display currency amounts in a browser table and since those are numbers, they should be right aligned.
Problem is with currencies like Japan which do not have floating point currencies.
So for them, we cannot show 5.10 Yen
Now, the requirement is to show something like this:
(Note the alignment and the mixing of decimal currencies with non-decimal)
5.23
12.00
3.24
5
9
11.00
In the above, 5 and 9 are Japanese Yens while others are USD
So the requirement is to replace floating points with spaces for currencies like JPY. Spaces are required to have proper alignment of the currencies.
Offcourse, for other currencies, the 2 decimal places should be there.
Does anyone know how the above can be done?
Thanks a lot in advance!!
Based on the below replies:
1) The values are sent from a Java server and fed into a JavaScript library SlickGrid
2) We want to control values at the server level because the SlickGrid code is not very amenable for this kind of work.
3) Currencies are being stored as floats because customer wants to see them that way :( and that's kind of correct because mostly people are bothered about dollars not cents, but then, some people are concerned about cents too.
I was really hoping of some option with DecimalFormat only as that would have been the best solution.
Else I would have to resort to the ugly solution of parsing and string massaging.
Currency should never be stored as a floating point number. It should always be integer amounts of the lowest denomination you are working with (Yen, Cents, Paise).
If you need to work with amounts smaller than the lowest natural denomination, store currency as integer amounts representing multiples of a specified fraction. For example 6 tenths of a Yen.
As for the formatting, there is a discussion of simple options here.
following CSS is basically taken from the link in jsj's answer (extracting the most relevant portion)
HTML only version:
td { font-family: monospace; }
span.int {
text-align: right;
float: left;
width: 3em;
}
span.fractional {
text-align: left;
float: right;
width: 2em;
}
<table>
<tr><td><span class="int">5</span><span class="fractional">.23</span></td></tr>
<tr><td><span class="int">12</span><span class="fractional">.00</span></td></tr>
<tr><td><span class="int">3</span><span class="fractional">.24</span></td></tr>
<tr><td><span class="int">5</span><span class="fractional"></span></td></tr>
<tr><td><span class="int">9</span><span class="fractional"></span></td></tr>
<tr><td><span class="int">11</span><span class="fractional">.00</span></td></tr>
</table>
JavaScript version:
function spanInt(content){ var span = document.createElement('span');span.className = 'int'; span.textContent = content; return span; }
function spanFractional(content){ var span = document.createElement('span'); span.className = 'fractional'; span.textContent = content; return span;}
function tableCell_int(value){
var td = document.createElement('td');
td.appendChild(spanInt(value));
td.appendChild(spanFractional(''));
return td;
}
function tableCell_float(value){
var intPart = Math.floor(value);
var fracPart = value - intPart;
var td = document.createElement('td');
td.appendChild(spanInt(intPart));
td.appendChild(spanFractional('.' + Math.round(100*fracPart)));
return td;
}
function tr(cell){
var elt = document.createElement('tr');
elt.appendChild(cell);
return elt;
}
var theTable = document.getElementById('theTable');
function add_int(value){ theTable.appendChild(tr(tableCell_int(value))); }
function add_float(value){ theTable.appendChild(tr(tableCell_float(value))); }
add_float(5.23); add_float(12); add_float(3.24);
add_int(5); add_int(9); add_float(11);
td { font-family: monospace; }
span.int {
text-align: right;
float: left;
width: 3em;
}
span.fractional {
text-align: left;
float: right;
width: 2em;
}
<table id='theTable'></table>

Fallback background for browsers not supporting border-image

I'm trying to use CSS3 border-image for a simple button design: the left slice of the image should be the left border of the text, the right slice the right border, and the middle slice should be repeated (or stretched - it does not matter) as background. I need a fallback for browsers not supporting border-image - just using the middle slice as a background, without edges would be acceptable. The problem is, if I do this:
.button {
border: solid 1px white;
border-size: 0 5px;
background: ('button-slice.png') repeat;
border-image: url('button.png') 0 5 0 5 fill;
-moz-border-image: url('button.png') 0 5 0 5;
/* repeat for other vendor prefixes */
}
the image from the background property will overlap the borders and mess up the button for browsers which support border-image.
Is there a lightweight way of solving this problem (whithout introducing modernizr or similar javascript checks)?
change the border-image 0 5 0 5 to 1 1 5 1 :
border-image: url('button.png') 1 1 5 1 fill;
-moz-border-image: url('button.png') 1 1 5 1;
border-image generator online
border-image is tricky for fallbacks. Doing...
.button {
border: solid 1px white;
border-size: 0 5px;
background: ('button-slice.png') repeat;
background: rgba(0,0,0,0);
border-image: url('button.png') 0 5 0 5 fill;
-moz-border-image: url('button.png') 0 5 0 5;
/* repeat for other vendor prefixes */
}
Should work for all browsers except IE9.
Since you only have a left and right border, I would suggest using pseudo-elements...
.button {
border: solid 1px white;
background: ('button-slice.png') repeat;
position: relative;
}
.button:before, .button:after {
content: '';
width: 5px;
position: absolute;
height: 100%;
background: transparent url('button.png') 0 0 no-repeat;
top: 0;
}
.button:before {left: -5px;}
.button:after {right: -5px;}
This technique should show nice buttons in all modern browsers plus IE8. Older browsers fallback without the edges.
It seems that new versions of FF support both border-image parameters and one override another.
Try reversing the order of those lines as so:
-moz-border-image: url('button.png') 0 5 0 5;
border-image: url('button.png') 0 5 0 5 fill;
In this way, browsers that support both parameters and override one with the later will take the version with the fill.