10

Using Less I am defining font-families as follows:

@georgia: georgia, times, 'times new roman', 'nimbus roman no9 l', serif; 

Then I have the less mixin:

.font(@family: arial, @size: 1.0em, @lineheight: 1.0, @weight: normal, @style: normal, @variant: normal) {
  font: @style @variant @weight @size~"/"@lineheight @family;
} // font

Finally I use it like this:

p {
  .font(@georgia, 1.0em, 1.5)
}

But I would also like to define font families with custom fonts:

@something: 'custom-font', arial, ...;

But first I need to register custom-font:

@font-face {
  font-family: 'custom-font';
src:url('fonts/custom-font.eot');
src:url('fonts/custom-font.eot?#iefix') format('embedded-opentype'),
    url('fonts/custom-font.woff') format('woff'),
    url('fonts/custom-font.ttf') format('truetype'),
    url('fonts/custom-font.svg#icon') format('svg');
font-weight: normal;
font-style: normal;
}

Is it possible to create a LESS mixin for @font-face so I can pass the font name and path and register fonts without repeating all this code?

I am not sure how to integrate this with my font mixin ...

Or if there is even a better way to do this ...

Thank You, Miguel

Slipp D. Thompson
  • 33,165
  • 3
  • 43
  • 43
Miguel Moura
  • 36,732
  • 85
  • 259
  • 481

7 Answers7

17

You could define your custom mixin for including custom fonts, but since LESS does not implement any control directives, only guards for mixins (which are useless in the current question's aspect), you cannot shorten the mixin's code for the font-face definition.

.include-custom-font(@family: arial, @weight: normal, @style: normal){
    @font-face{
        font-family: @family;
        src:url('fonts/@{family}.eot');
        src:url('fonts/@{family}.eot?#iefix') format('embedded-opentype'),
            url('fonts/@{family}.woff') format('woff'),
            url('fonts/@{family}.ttf') format('truetype'),
            url('fonts/@{family}.svg#icon') format('svg');
        font-weight: @weight;
        font-style: @style;
    }
}
Lajos Mészáros
  • 3,756
  • 2
  • 20
  • 26
4

I know its an old post BUT, I solved this issue like this, hope it helps somebody else.

First I created a parametric mixin with everythign that will repeat inside the @font-face:

.loadFont(@Weight; @Name; @Local; @Eot:'@{Local}.eot'; @Woff:'@{Local}.woff'){
    font-family: 'Open Sans';
    font-style: normal;
    font-weight: @Weight;
    src: url(@Eot);
    src: local(@Name), local(@Local), url(@Eot) format('embedded-opentype'), url(@Woff) format('woff');
}

Then loaded all my web fonts (in this case open sans)

@font-face {.loadFont(100;'Roboto Thin';'Roboto-Thin')}
@font-face {.loadFont(300;'Roboto Light';'Roboto-Light')}
@font-face {.loadFont(400;'Roboto Regular';'Roboto-Regular')}
@font-face {.loadFont(500;'Roboto Medium';'Roboto-Medium')}
@font-face {.loadFont(700;'Roboto Bold';'Roboto-Bold')}
@font-face {.loadFont(900;'Roboto Black';'Roboto-Black')}

Then created a second parametric mixin with the CSS rule to apply to the elements

.font(@weight:400; @size:14px; @font-family:'Open Sans', sans-serif){
    font:@arguments;
}

And finally I use it on my elements like this

div.someClass{
    .font(); //to accept all default parameters 
}
div.otherClass{
    .font(100; 40px); //to specify weight and size
}

As a side note. I have all my *.eot and *.woff files next to the LESS file and named as the @Local parameter (Open-Sans.woff || Open-Sans.eot)

Zero Dragon
  • 131
  • 3
3

I like to structure my fonts on folders, like this:

/fonts/OpenSans-Bold/OpenSans-Bold.eot
/fonts/OpenSans-Bold/OpenSans-Bold.svg
/fonts/OpenSans-Bold/OpenSans-Bold.ttf
/fonts/OpenSans-Bold/OpenSans-Bold.woff

And i use this LESS MIXIN for font-face:

.font-face(@fontName: sans-serif; @fontWeight: normal; @fontStyle: normal) {
    @font-face {
        font-family: @fontName;
        src: url('@{pTheme}/fonts/@{fontName}/@{fontName}.eot');
        src: url('@{pTheme}/fonts/@{fontName}/@{fontName}.eot?#iefix') format('embedded-opentype'),
             url('@{pTheme}/fonts/@{fontName}/@{fontName}.woff') format('woff'),
             url('@{pTheme}/fonts/@{fontName}/@{fontName}.ttf') format('truetype'),
             url('@{pTheme}/fonts/@{fontName}/@{fontName}.svg#@{fontName}') format('svg');
        font-weight: @fontWeight;
        font-style: @fontStyle;
    }
}

Where:

@pTheme: "../../themes/[THEME NAME]";

Mixin call example:

.font-face('OpenSans-Bold');

I've made the @pTheme variable so i can use it also on background images, like this:

background: url("@{pTheme}/images/logo.png") no-repeat;
PAdrian
  • 412
  • 3
  • 9
1

LESS does indeed support having mixins with parameters. See here: http://lesscss.org/#-parametric-mixins

0

I know this question is a little old, but I ran with Mészáros Lajos' answer. It needed to account for a few things that it doesn't currently:

  1. Your font family and font filename do not need to match; in fact, for "bold" and "italics" you may want to use Style Linking. See: http://www.smashingmagazine.com/2013/02/14/setting-weights-and-styles-at-font-face-declaration/. This prevents "faux bold" and "faux italic" that happens when a browser doesn't understand the relationship between your fonts (e.g, it doesn't know that MyFont-Bold is the correct font to use when you have a strong tag inside text that is using MyFont).
  2. The font family name and the SVG id do not need to match; e.g., the file montserrat-regular.svg may have an SVG ID of montserratregular. Yes, you could fix this by renaming your files, and maybe you should, but if you're getting the files remotely (CDN), you may not have that luxury.
  3. Personal preference, I switched the order of variant and weight. In CSS font shorthand, variant comes first, so to keep things similar, I put it first here.
  4. Again, personal preference, I removed the defaults, because I didn't want to call this method without being explicit. When you have to specify everything, you're less likely to forget that you did in fact need to change the SVG ID for that font.
  5. Since Chrome-windows doesn't currently anti-alias WOFFs, I switched the order to move SVG right after the EOT (old IE needs EOT first or will break). Credit

.fontface(@family, @filename-base, @style, @weight, @svgID){
    font-family: @family;
    src:url('@{filename-base}.eot');
    src:url('@{filename-base}.svg#@{svgID}') format('svg'),
        url('@{filename-base}.eot?#iefix') format('embedded-opentype'),
        url('@{filename-base}.woff') format('woff'),
        url('@{filename-base}.ttf') format('truetype');
    font-weight: @weight;
    font-style: @style;
}

Community
  • 1
  • 1
Carl Bussema
  • 1,684
  • 2
  • 17
  • 35
0

U can try this mixin for font-face (font Proxima Nova as expl):

.fontFace(@fontWidth) {
    @fontName: "Proxima Nova @{fontWidth}";
    @fileName: "../fonts/ProximaNova-@{fontWidth}";
    @font-face {        
        font-family: '@{fontName}';
        font-weight: 400;
        font-style: normal;
        src: url('@{fileName}.eot');
        src: url('@{fileName}.eot?#iefix') format('embedded-opentype'),
             url('@{fileName}.woff') format('woff'),
             url('@{fileName}.ttf') format('truetype'),
             url('@{fileName}.svg#@{fontName}') format('svg');
    }
}

.fontFace('Regular');
.fontFace('RegularIt');
.fontFace('Bold');

@fontName: Proxima Nova;
@font:          "@{fontName} Regular";
@font_italic:   "@{fontName} RegularIt";
@font_bold:     "@{fontName} Bold";

h2 {
    font: 400 50px @font_bold;  
}

And, as the same thing, this staff at SASS/SCSS:

@mixin font ($weight) {
    @font-face {
        $fontName: 'Proxima Nova ' + $weight;
        $fileName: '../fonts/ProximaNova-' + $weight;

        font-family: $fontName;
        font-weight: 300;
        font-style: normal;
        src: url($fileName + '.eot ');
        src: url($fileName + '.eot?#iefix') format('embedded-opentype'),
           url($fileName + '.woff2') format('woff'),
           url($fileName + '.ttf') format('truetype'),
           url($fileName + '.svg##' + $fontName) format('svg');
    }
}
@include font(regular);
@include font(bold);
@include font(light);

$fontName: 'Proxima Nova ';
$font: $fontName + regular, "Helvetica Neue", sans-serif;
$font_bold: $fontName + bold;
$font_light: $fontName + light;

h2 {
    font: 300 15px $font_bold;
}
GrimCap
  • 31
  • 5
-5

Here's my rendition for SASS, tested and working.

@mixin fontface($family: sans-serif, $weight: normal, $style: normal, $path: '../fonts', $filename: 'font'){ @font-face{ font-family: $family; src:url('#{$path}/#{$filename}.eot'); src:url('#{$path}/#{$filename}.eot?#iefix') format('embedded-opentype'), url('#{$path}/#{$filename}.woff') format('woff'), url('#{$path}/#{$filename}.ttf') format('truetype'), url('#{$path}/#{$filename}.svg#icon') format('svg'); font-weight: $weight; font-style: $style; } }

Karl
  • 1
  • 3
    Question is about LESS. You should consider finding a similar question about SASS, posting this answer there, and deleting this answer. – Chris Moschini Jul 24 '14 at 20:24