How do I write font in LESS CSS? - css

I'm in a bit of a pickle. I just picked up WinLess (the compiler I'm using) about two days ago and I've just vaguely learned the basis of LESS. Anyways, I'm having a problem with this bit of code:
// Font
#verdana: font-family:"verdana";
#sans: font-family:"sans-serif";
When I do compile this I get this message:
ParseError: Unrecognized input in on line 4, column 3:
3 // Font
4 #verdana: font-family:"verdana";
5 #sans: font-famlit:"sans-serif";
Can anyone give me a hand? Thanks!

For LESS 1.7+
They have now added rulesets that work like this:
#verdana: {font-family:"verdana"};
.myClass {
#verdana();
}
Note the syntax: you pass a bracketed {} set of properties, and access it with the parenthesis () after the variable name, much like a mixin. As you can see, it also functions a lot like a mixin (similar to lucian's answer), but it has the added value that it can be passed as an argument, so this is possible:
LESS
#verdana: {font-family:"verdana"};
.myMix(#font) {
#font();
}
.test {
.myMix(#verdana);
}
CSS Output
.test {
font-family: "verdana";
}

You can declare it like this: .myfont{ font-family:"some family, some generic family"} and then use it like this: div{ .myfont; }

i only know it in this way :
#variable_name: 'individual_font_name', Verdana, sans-serif;
a font variable with a name, a font name like "My_Verdana" and the main font and the second as example for a failure of the main-font.
hope this helps, greetings.

Related

CSS Variables and String concatenation

I'm trying to use CSS variables to generate a dynamic path.
Example:
:root {
--fonts-path: "/path/to/font";
}
#font-face {
font-family: "FontName";
src: url(var(--fonts-path) + "/FontName-Light.woff") format('woff');
font-weight: 100;
}
html {
font-family: 'Metric', Arial, sans-serif;
}
This is failing with a not-found module 'var(--hpe-fonts-path', this is the webpack log:
ERROR in ./~/css-loader?sourceMap&modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!./~/postcss-loader!./src/theme/fonts.css
Module not found: Error: Cannot resolve module 'var(--fonts-path' in /Users/project-sample/src/theme
# ./~/css-loader?sourceMap&modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!./~/postcss-loader!./src/theme/fonts.css 6:83-114 6:234-265 6:403-434 6:576-607
Any pointers?
I see some problems with your approach:
#font-face rules don't inherit CSS variables set on :root.
You can't use + to concatenate CSS strings. See string concatenation in css
Not all implementations support var() inside url() yet.
A similar issue is described in this post:
CSS native variables not working in media queries
where the user tries to use a variable inside a #font-face rule.
As described in the accepted answer (https://stackoverflow.com/a/40723269/4879632) you cannot use variables inside of rules, because the variables are inherited by :root (html) child elements. # Rules (font faces, media queries, etc) are not elements, so they do not inherit from the root. Thus, you cannot reference a variable from there.
Try incluiding the url inside the variable, This works in a background context, but not sure if it does inside font-face
:root {
--url:url("https://picsum.photos/id/1/200/300");
}
.box {
background:var(--url);
}
You can't concatenate variable in CSS (refer here):
Since you can't concatenate in CSS (aside from the content property), CSS variables can not be concatenated. This means, for example, you can't combine a CSS variable that is a number with a unit.
// No version of this will work
div {
--height: 100;
height: var(--height) + 'px';
}

Get Less variable value from string

I am trying to create a function to switch themes. When I transpile my Less to CSS, the CSS file shows the literal string interpolation rather than the variable value. The variables file looks something like:
#beach-font-color: #3d3d3d;
#ocean-font-color: #d3d3d3;
#theme: "beach";
#symbol: "#";
#currentTheme-font-color: ~"#{symbol}#{theme}-font-color";
In the stylesheet:
body { color: #currentTheme-font-color; }
The generated css produces:
body { color: #beach-font-color; }
instead of:
body { color: #3d3d3d; }
One thing I thought might be required is:
#font: ~"#{symbol}#{theme}-font-color";
#currentTheme-font-color: ~"#{font}";
But this just produces the same results.
Why does the Less compiler use the string literal instead of the variable value?
How would I be able to get the value of the variable, going along these lines?
(I cannot skip this to not provide an alt. answer since such "namespace emulation via variable name concatenation" is my most favourite bloody wrong Less pattern (unfortunately it is also the most widely spread one :().
Instead of emulating namespaces via using looong global variable names (doh#1 in most of programming languages and paradigms global variables are considered harmful since 1970's... :) and then assembling those variable names via the ugly concatenation syntax (doh#2, ~"#{#{#foo}}-#{bar}-seriously}?"), one can use normal namespaces with much more clean syntax:
.theme(beach) {
#font-color: #3d3d3d;
// other beach variables
}
.theme(ocean) {
#font-color: #d3d3d3;
// other ocean variables
}
#theme: beach;
.theme(#theme);
body {color: #font-color}
This is just one of possible variations (for more examples see:
Dynamic Variable Names with Less -> gist
How to thematize in lesscss
etc.)

Less Mixin using variable in attribute selector

EDIT: The issue might be with a bug in dotless, which is what we're using.
I'm trying to write a Less Mixin method for writing out a lot of CSS styles. The general format of the method is:
.icon-styles(#name) {
.#{name}-icon {
background-image: url('../images/icon-#{name}.png');
display: none;
}
[data-#{name}="true"] .#{name}-icon {
display: inline-block;
}
}
Such that the icon is only visible if a containing object has the related attribute set.
However, I'm getting an error at the attribute selector saying:
Expected ']' but found '{'
Pointing to the # inside the square brackets.
I've found this post:
LESS mix variable into attribute name in an attribute selector expression
With a similar issue, and the answer suggests it might be a bug, but unfortunately the workaround doesn't work for me. I'm getting the same error on trying to write out attr inside the brackets.
I've also tried writing it like this:
[~'data-#{name}'="true"] .#{name}-icon {
Which gets rid of the error, but then #{name} is not resolved in the resulting css.
Does anyone know if there's any way to achieve what I want?
The trick is the same as suggested in LESS mix variable into attribute name in an attribute selector expression. You're just missing the main point of it: "concatenation of interpolated variables is not supported inside [attr] blocks", so you need to move out of it:
.icon-styles(#name) {
.#{name}-icon {
background-image: url('../images/icon-#{name}.png');
display: none;
}
#data-name: ~'data-#{name}';
[#{data-name}="true"] .#{name}-icon {
display: inline-block;
}
}

How to change SASS output style in order to make a new line after each ending curly brace?

The processed code looks like this:
.body {
color: #eeeeee;
}
.someting {
color: #dddddd;
}
I want it to be:
.body {
color: #eeeeee;
}
.someting {
color: #dddddd;
}
Is there such a possibility? Google can't find an answer.
I bet you could write a simple regex find-replace looking for }'s and replacing with }\n, and have Grunt execute that on your css (post-compilation from SASS).
This looks like it'd do the trick:
https://npmjs.org/package/grunt-regex-replace
I think the closest you can get is expanded. The extra line break won't be there when you're nesting but your example code would output exactly like you demonstrated.
To answer this question, you can go to rubygems/gems/sass-3.4.9/lib/sass/tree/visitors/to_css.rb (or anywhere your to_css file is), and edit this:
output("}" + trailer) to output("}\n" + trailer)
And then remove this newline:
trailer = "\n" if node.group_end
It might have been an oversight when parsing the nesting, because the newline set on "trailer" applies to every other line (so you'd have double the lines without removing it if you don't nest anything).

How to make ctags + scss play nice

UPDATE:
This question has been modified to reflect the very helpful comments and answer below. I've accepted the answer, but the full functionality is not working to-date.
Contents of .ctags (in ~/)
-R
--exclude=.git
--exclude=log
--verbose=yes
--langdef=scss
--langmap=scss:.scss
--regex-scss=/^[ \t]*([^\t {][^{]{1,100})(\t| )*\{/| \1/d,definition/
--regex-scss=/^[#]mixin ([^ (]+).*/\1/m,mixing/
When I place my cursor under the target, vim says E426 tag not found: tag_name
Consider the following pattern:
footer{
.wrapper{
.general-info{
.footer-links{
a{#include ticker($bg, $white);}
}
}
}
}
In a separate file (modules.scss) in the directory, I have the definition for ticker:
#mixin ticker($color, $bg-color) {
color: $color;
background-color: $bg-color;
}
When I place my cursor under the target, vim still says E426 tag not found: tag_name
ctags does not index the ticker mixin. However I can use ctags to find methods from SCSS gem directly (e.g. darken).
adding a \ before the last { gives no warning when using ctags.
I don't know if the tags produced give the desired result since I don't know the language.
The result would be:
--langdef=scss
--langmap=scss:.scss
--regex-scss=/^[ \t]*([^\t {][^{]{1,100})(\t| )*\{/| \1/d,definition/
Update: like I mentioned above, I don't know the language, so it is hard to check the actual definition of the tags.
I looked online and the following code is listed as scss in some webpage.
Suppose the tags you want to get are the words following mixing.
#mixin table-scaffolding {
th {
text-align: center;
font-weight: bold;
}
td, th { padding: 2px; }
}
#mixin left($dist) {
float: left;
margin-left: $dist;
}
#data {
#include left(10px);
#include table-scaffolding;
}
then with the following:
--langdef=scss
--langmap=scss:.scss
--regex-scss=/^[ \t]*([^\t {][^{]{1,100})(\t| )*\{/| \1/d,definition/
--regex-scss=/^[#]mixin ([^ (]+).*/\1/m,mixin/
--regex-scss=/^[#]function ([^ (]+).*/\1/f,function/
you get the two new tags left and table-scaffolding.
So if I am in the word left inside data hit ctrl+] it jumps to the line where data is defined.
You have to be careful for the other keyword because it has a - in the word. So if you are on table and press ctrl+] you will get the same error tag not found. For this to work you have to add the following in your .vimrc
set iskeyword+=-
You should be able to generalize the above for other tags you need, or even build a general regular expression to handle all the tags, as you initially meant.
If you post a specific example of how the file you are trying to work with looks like, and what are the tags you are trying to obtain I am sure I or other people would be able to help figure out a expression for that.

Resources