why does LESS prints out arithmetic operations as text? - html

When i'm writing the following operations
#a: 2px
#variable: #a + 5;
.margin-style{
margin-left: #variable;
}
This above code compiles to
.margin-style{
margin-left: 2px + 5;
}
instead of
margin-left:7px;
What seems to be going wrong?

Using Bootstrap and Grunt
setting strictMath:false in the Gruntfile.js under the less compiler settings solved the issue

Related

SCSS: Send Attribute and Value to Function

Note:
I'm new to web development and object oriented programming. I am brand new to SCSS and haven't yet grasped a solid understanding of the syntax. I have a basic understanding of how to use functions in SCSS.
Let me start off by defining the result I want to achieve.
_body.scss
body {
background-color: red;
}
Now I know if I wanted to obtain this result in Javascript I could:
Option 1: write a string of HTML code and replace the existing html tag.
Not going to code this, as this is a messy way of writing Javascript, but essentially using document.write() method.
Option 2: use the "setAttribute()" method
// assuming <head> and <body> are the only tags within <html>
var bodyTag = document.firstElementChild.lastElementChild;
bodyTag.setAttribute( "bgcolor", "red" );
I know there are additional ways to do this in Javascript, but for this example, I will focus on these two.
So I want to create a SCSS function that can return both the attribute and the value.
_body.scss ( Pseudocode string example )
#function makeAttribute( $attribute, $value )
{
#return $attribute + ":" + $value + ";";
}
body {
makeAttribute( background-color, red );
}
I have yet to find a built in function that addresses this ( similar to the "setAttribute()" method in Javascript ), or the string example above.
I know that functions can take: number, string, bool, color, list, map or null; but what I don't know is if an attribute fits into any of these value types ( for instance: string ).
I feel as if the article: Bringing Configuration Objects To Sass may be explaining what I am trying to do, but I'm having difficulty understanding this article ( so it may not be an explanation to a solution ).
My end goal is to create a function that would write the following css. I did not mention the browser support previously as it adds another layer of complexity that may or may not be easily explained.
body {
background-color: red;
-o-background-color: red;
-ms-background-color: red;
-moz-background-color: red;
-webkit-background-color: red;
}
i don't know if this have to be a function, i found it more logic use a mixin instead:
// Option 1
#mixin makeRule($value: red, $property: background-color) {
#{$property}: $value;
}
// Option 2:
#mixin makeRuleWithPrefixes($value: red, $property: background-color) {
#{-ms- + $property}: $value;
#{-o- + $property}: $value;
#{-moz- + $property}: $value;
#{-webkit- + $property}: $value;
#{$property}: $value;
}
/////////
body {
#include makeRule;
}
article {
#include makeRule(black);
}
p {
#include makeRule(2px solid blue, border)
}
span {
#include makeRuleWithPrefixes;
}
i changed the name, because is no right say - makeAttribute, when you are creating a cssRule ( selector + property name + property value ), well this is up to you ;)
ok the first,you need interpolation to use a variable as a property name.
The value is the first argument, so now you can use the default property, and just pass different values ( like the article :) )
or you can now set all the properties you want it, just pass the property as the second value ( like p )
body {
background-color: red;
}
article {
background-color: black;
}
p {
border: 2px solid blue;
}
span {
-ms-background-color: red;
-o-background-color: red;
-moz-background-color: red;
-webkit-background-color: red;
background-color: red;
}
I made the option two, because you ask it but i warn you, this is not a good approach. You could use a build tool ( webpack, gulp, grunt.. whatever ) than use a autoprefixer package that do this prefix automatically, this way is a pain because you have to be updating the #mixin eventually.

LESS compilation error

I'm trying the following statement in LESS, but its giving me an error:
(~".table-column[width='#{size}']") {
// do something
}
----------
ERROR :
----------
*ParseError: Missing closing ')'*
I'm using lessc 2.5.3, with nodejs on windows.
LESS is new to me and any pointers would be helpful.
Thanks
No need for the parens, nor the string quotes, nor the ~ (unless you are trying to use a ~ sibling selector). Observe the following...
#size: 40px;
.table-column[width='#{size}'] {
background-color: tomato;
}
// -- conversion
.table-column[width='40px'] {
background-color: tomato;
}
Codepen link - working demo
Also check out the LESS variables docs - specifically, variable interpolation, for more information.

Jade: Best practice with classes and ids

I've searched for a while now, but I couldn't find an answer.
To create a div container with a class or id in Jade you can write:
.foo
#bar
or
div.foo
div#bar
Another thing is multiple classes:
div.foo.bar
or
div(class="foo bar")
What's best practice or is it just personal preference?
It is just a shorthand notation. Nothing wrong with it, just more readable for users who are unfamiliar with the shorter syntax to implicitly show that you are creating a div.
In some cases, using a shorthand syntax however causes the interpreter to perform better, because it works a bit different under the hood.
I'm not familiar with how Jade works, but maybe using just the dot notation saves some work behind the scenes, whilst using the more explicit instructions takes more time to parse.
Same as something similar in css:
border-style: solid;
border-width: 1px;
border-color: red;
/* shorthand */
border: 1px solid red;
Or javascript:
var foo;
if (true){
foo = "bar";
} else {
foo = "not bar";
}
// shorthand
var foo = true ? "bar" : "not bar";
var x = x + 1;
// shorthand, and might uses the processor or engine differently
var x += 1;

Sass lighten function issue

Well, I have a problem with Sass function lighten(), this is my code:
#for $i from 1 through 4{
.par-#{$i}{
background: lighten(#08725D, #{$i}0%);
padding: 10px;
border-radius: 5px;
}
}
I think it's pretty obvious what I want to do, I just want to go through that variable and increment the lightening of the bg color (while I increment the number in the class), but I have this error in console:
error main.scss (Line 111: $amount: "10%" is not a number for `lighten')
I need help please.
$i contains a number. Keep using it as a number instead of using concatenation :
#for $i from 1 through 4{
.par-#{$i}{
background: lighten(#08725D, $i * 10);
padding: 10px;
border-radius: 5px;
}
}

Change last letter color

Example code:
<p class="test">string</p>
I want to change the color on the last letter, in this case "g", but I need solution with css, I don't need a javascript solution.
I display the string letter by letter and i cant use static solution.
Everyone says it can't be done. I'm here to prove otherwise.
Yes, it can be done.
Okay, so it's a horrible hack, but it can be done.
We need to use two CSS features:
Firstly, CSS provides the ability to change the direction of the flow of the text. This is typically used for scripts like Arabic or Hebrew, but it actually works for any text. If we use it for English text, the letters are displayed in reverse order to how the appear in the markup. So to get the text to show as the word "String" on a reversed element, we would have to have markup that reads "gnirtS".
Secondly, CSS has the ::first-letter pseudo-element selector, which selects the first letter in the text. (other answers already established that this is available, but there's no equivalent ::last-letter selector)
Now, if we combine the ::first-letter with the reversed text, we can select the first letter of "gnirtS", but it'll look like we're selecting the last letter of "String".
So our CSS looks like this:
div {
unicode-bidi:bidi-override;
direction:rtl;
}
div::first-letter {
color: blue;
}
and HTML:
<div>gnirtS</div>
Yes, this does work -- you can see the working fiddle here: http://jsfiddle.net/gFcA9/
But as I say, it is a bit hacky. And who wants to spend their time writing everything backwards? Not really a practical solution, but it does answer the question.
Use ::after pseudo-element combined with attr() function:
p::after {
content: attr(data-end) ;
color: red ;
}
<p data-end="g">Strin</p>
p::after {
content: attr(data-end) ;
color: red ;
}
<p data-end="g">Strin</p>
Another solution is to use ::after
.test::after{
content: "g";
color: yellow;
}
<p class="test">strin</p>
This solution allows to change the color of all characters not only letters like the answer from Spudley that uses ::first-letter. See ::first-letter specification for more information. ::first-letter applies only on letters it ignores punctuation symbols.
Moreover if you want to color more than the last character you can :
.test::after{
content: "ing";
color: yellow;
}
<p class="test">str</p>
For more information on ::after check this link.
Without using javascript, your only option is:
<p class="test">strin<span class="other-color">g</span></p>
Edit for your fiddle link:
I'm not really sure why you said you didn't need a javascript solution, since you have quite a bit of it already. Regardless, in this example, you need to make only a couple small changes. Change line 10 from
elem.text(elem.text() + contentArray[current++]);
to
if ( current == contentArray.length-1 ) {
elem.html(elem.html() + "<span style='color:red'>"+contentArray[current++]+"</span>");
} else {
elem.html(elem.html() + contentArray[current++]);
}
Note that it's important to use .html() instead of .text() now, since there's actually HTML markup being inserted.
Working fiddle: http://jsfiddle.net/QTUsb/2/
It could be achieved using only CSS and an ::after pseudo-element without any changes in HTML:
.test {
font-size: 16pt;
position: relative;
}
.test::after {
bottom: 0;
color: red;
content: 'g';
position: absolute;
transform: translate(-100%, 0);
}
<p class="test">string</p>
In what way do you "display the string letter by letter"? If you're looping through the characters in a string (variable) you can certainly tell when you're at the last letter and wrap it in a whether doing so on the server side or client side.
Looking at the fiddles attached to another of your questions ...
If this is what you're talking about, you might have to set the .innerHTML of the element instead of the element.text()
From the fiddle at http://jsfiddle.net/SLKEn/ you would change it to something like this
if(current < contentArray.length) {
elem.html(
elem.html() +
(current == contentArray.length-1 ?
'<span class="lastchar">' + contentArray[current++] + '</span>' :
contentArray[current++])
);
}
along with CSS span.lastchar { color: red; }
Update: working fiddle based on your other question.
$(document).ready(function() {
var str=$("span").text();
strArr=str.split("");
for(var key=0;key<=strArr.length-1;key++) {
if(key==strArr.length-1) {
var newEle="<span id='lastElement'>"+strArr[key]+"</div>";
strArr[key]=newEle;
}
}
var newtext=strArr.join("");
$("span").html(newtext);
});
span#lastElement {
color: red;
}
i dont have the ability to comment on an answer thread but i wanted to point out an error in an answer provided by Marc_Alx that otherwise works wonderfully. that solution worked for me only after adding a semi-colon behind the content property... so it looks like content:"ing";
.test::after{
content:"ing";
color:yellow;
}
<p class="test">str</p>