I have a dropdown of 30 fonts where I'd like the font of the dropdown to also display the Google Font (for visual representation, of course!) example text.
I have the HTML with the ID's, for example: font-oswald-light
, font-oswald-reg
, font-oswald-bold
.
Using the @each directive, I wanted to do something like this:
@each $font-name, $font-mixin in (lato, Lato-Light),
(open_sans, Open_Sans-Light),
(oswald, Oswald-Light),
(raleway, Raleway-Light),
(roboto, Roboto-Light),
(source_sans_pro, Source_Sans_Pro-Light),
(ubuntu, Ubuntu-Light) {
#font-#{$font-name}-light {
@include #{$font-mixin};
}
}
create the font-family:
@import url('https://fonts.googleapis.com/css?family=......)
@mixin Lato-Light {
font-family: 'Lato', sans-serif;
font-weight: 300;
font-style: normal;
}
@mixin Lato-Reg {
font-family: 'Lato', sans-serif;
font-weight: 400;
font-style: normal;
}
@mixin Lato-Bold {
font-family: 'Lato', sans-serif;
font-weight: 700;
font-style: normal;
}
However, the @each does not like the @include
inside to display the font-family. I'm not using any libraries (bourbon, compass, etc) to create the font-face().
My question is: what would be a way to dynamically create the @each font-ID list so it doesn't error out when trying to @include the families?
#font-#{$font-name}-light {
@include #{$font-mixin};
}
First of all, this code can't work. Interpolation does not work this way in Sass. Sass expects an identifier after the @include
keyword and when it comes across this code, it evaluates $font-mixin
to the value represented by the variable and that's all it is, a value. Sass will not interpret that value as an identifier
Secondly you don't need to create a mixin for every single font. That approach is not flexible and even less maintainable.
I suggest one using one mixin
that will loop through a fonts map
to dynamically generate the css you want.
$fonts-list:(
lato-light: ("Lato", sans-serif) 300 normal,
lato-reg: ("Lato", sans-serif) 400 normal,
lato-bold: ("Lato", sans-serif) 700 normal,
oswald-light: ("Oswald", sans-serif) 200 normal,
oswald-reg: ("Oswald", sans-serif) 400 normal
);
@mixin fonts($family, $weight, $style) {
font-family: $family;
font-weight: $weight;
font-style: $style;
}
@each $font, $attributes in $fonts-list {
#font-#{$font} {
@include fonts(nth($attributes, 1), nth($attributes, 2), nth($attributes, 3));
}
}
The compiled CSS looks like this
#font-lato-light {
font-family: "Lato", sans-serif;
font-weight: 300;
font-style: normal;
}
#font-lato-reg {
font-family: "Lato", sans-serif;
font-weight: 400;
font-style: normal;
}
#font-lato-bold {
font-family: "Lato", sans-serif;
font-weight: 700;
font-style: normal;
}
#font-oswald-light {
font-family: "Oswald", sans-serif;
font-weight: 200;
font-style: normal;
}
#font-oswald-reg {
font-family: "Oswald", sans-serif;
font-weight: 400;
font-style: normal;
}
You can decide to have multiple font maps to store fonts based on variations i.e $fonts-light
, which stores all the light variations of the fonts, $fonts-reg
, which stores all the regular variations of the fonts... And then you could loop through each of them the same way. It all depends on the structure you prefer. I hope this helps