5

There have been a bit of talk about issues with cssless and font-face already, for example here: How we can use @font-face in Less

But this problem seems to be a different one, and I wonder whether anyone has found workaround to this? I think my less syntax is right though.

If I write the following:

.setFont (@fontName) {
    @font-face {
        font-family: '@{fontName}';
        src: url('../fonts/@{fontName}.eot'); 
        src: url('../fonts/@{fontName}.eot?#iefix') format('embedded-opentype'), 
        url('../fonts/@{fontName}.ttf')  format('truetype');
    }
}
.setFont ('myfont1');   
.setFont ('myfont2');   
.setFont ('myfont3');

It will output the following:

@font-face {
  font-family: 'myfont1';
  src: url('../fonts/myfont1.eot');
  src: url('../fonts/myfont1.eot?#iefix') format('embedded-opentype'),
  url('../fonts/myfont1.ttf') format('truetype');
}
@font-face {
  font-family: 'myfont1';
  src: url('../fonts/myfont1.eot');
  src: url('../fonts/myfont1.eot?#iefix') format('embedded-opentype'),
  url('../fonts/myfont1.ttf') format('truetype');
}
@font-face {
  font-family: 'myfont1';
  src: url('../fonts/myfont1.eot');
  src: url('../fonts/myfont1.eot?#iefix') format('embedded-opentype'),
  url('../fonts/myfont1.ttf') format('truetype');
}

It only takes the first variable. I wonder whether it is because they aren't called inside an element - though I did try to call it inside an element as well, with identical results.

How do you use cssless with font-face?

Thanks.

Community
  • 1
  • 1
Dusty
  • 125
  • 4
  • 11
  • Which compiler are you using? This could be an issue with support for font-face specific to that LESS compiler, or the version of LESS it supports. – prodigitalson Mar 24 '12 at 15:26
  • I'm using the Less.app version 2.6 from http://incident57.com/less/ That could be it of course, but isn't it essentially just a less.js wrapper. – Dusty Mar 24 '12 at 15:30
  • I have no idea what it uses internally... i typically use the `Node.js` or php compilers from the command line or built directly into my webapp's caching/service layer :-). – prodigitalson Mar 24 '12 at 15:32
  • 1
    Ok, I just updated to version 2.7, but no difference regarding this problem. – Dusty Mar 24 '12 at 15:33
  • Looking at the release notes, it looks like the current version supports the current version of LESS, and that the internals were just upgraded to this version as of March 12, so make sure your app is up to date and if it is, the version probably isnt the problem. – prodigitalson Mar 24 '12 at 15:34
  • Do those mixin calls actually compile at all? – prodigitalson Mar 24 '12 at 15:35
  • What do you mean? It does take the first variable. I use similar method on several other situations. For example rounded-corners(@parameters), box-shadow(@parameters) etc. But the difference here is that they aren't called inside an element, which might be the issue, but then again there wouldn't be a point to output the font-face declarations inside an element. – Dusty Mar 24 '12 at 15:44
  • Hmmm now that you mention it... im pretty sure mixins can only be used to mixin properties, not to bring in entire blocks like a font-face definition. Why exactly are you trying to do this? Just define all the potential faces and then use them on the selectors you need. – prodigitalson Mar 24 '12 at 16:34
  • You might be right. I'm doing this for the same reasons as the other mixins. No reason to declare the same thing over and over again, when you could have it in one place and use it multiple times. But I guess you just have to define manually as many font-face blocks as you need fonts. A shame it doesn't work that way, as you'd logically expect it to work. – Dusty Mar 24 '12 at 16:43
  • But its not like you would ever declare the same font face over and over again - you only ever need to declare it once. The functionality you are looking for is provided by fontface itself where `font-family` in the rule for a selector is like the call to the mixin. Its kinda redundant. But the bigger picture here is a common misconception - that `mixin` is another word for `function` and/or `variable`. Its not - its extremely similar but not the same :-) – prodigitalson Mar 24 '12 at 17:25

1 Answers1

2

It is doing this because variables are not technically variables in LESS but constants, and therefore can not be redefined.

So when you are are defining @fontName the first time, it can not be redefined. Which is why you are getting duplicates. Unfortunately, you cannot use them like parameters (like setting border-radius(@radius), which it looks like what you were hoping to do. Its nuanced, but there is a difference.

The way you are using it is as a variable(constant), the way you'd like to use it, but can't, is as a parametric mixin. If its easier to think about it in terms of scope. You are setting a global variable in this case, as opposed to a local variable for that particular selector. When you are setting border-radius for example, you are setting it within a selector, thus making it a local variable for that selector. In your example above you are not applying .setFont to a selector, where it can be used as a local variable, but instead setting it as a global one.

The only way you might be able to pull this off is using @arguments, but it may take just as much code as just writing out the individual @font-face statements. Since @font-face is technically a selector itself, it will always be used in a manner that treats variables used in reference to it as global.

Brian Hough
  • 563
  • 2
  • 8