We have a large project where we're trying to implement ITCSS pattern (which works just fine) and add to it a custom icon font created by our graphists.
Here is the folder structure (not exhaustive):
.
├── build
│ └── webpack.config.js
└── src
├── components # Using React
│ ├── test.jsx
│ └── test.scss
└── styles
├── _objects # Components style reusable
│ ├── _all.scss
│ └── table.scss
├── _settings # Global variables
│ ├── _all.scss
│ ├── _custom-icons.scss # Define icon font (see below)
│ ├── _custom-icons-variables.scss # Define icon codes
│ ├── _colors.scss # Define colors
│ ├── _predefined-colors.scss # Define brand colors
│ └── _theme.scss # Define specific theme
├── _tools # Mixins / helpers
│ ├── _all.scss
│ ├── _animation.scss
│ ├── _breakpoints.scss
│ └── _transition.scss
├── _wins # Overrides
│ ├── _all.scss
│ ├── _display.scss
│ ├── _position.scss
│ └── _text.scss
├── assets
│ └── fonts
│ ├── custom-icons.eot
│ ├── custom-icons.svg
│ ├── custom-icons.ttf
│ └── custom-icons.woff
├── _base.scss # HTML Selectors
├── _generic.scss # Reset (normalize)
└── main.scss # Loads everything
OK, that's a pretty heavy file structure, but it does the job regarding what we want to achieve!
We started our app upon the react-redux-starter-kit by davezuko. We tweaked webpack config file to match our needs but didn't change the style part, so you can refer to the webpack.config.js from GitHub.
Now, here are our files:
_custom-icons-variables.scss
$fontPath: "./assets/fonts" !default;
$aw-happy: "\e9df";
$aw-smile: "\e9e1";
$aw-tongue: "\e9e3";
$aw-sad: "\e9e5";
$aw-wink: "\e9e7";
$aw-grin: "\e9e9";
$aw-cool: "\e9eb";
$aw-angry: "\e9ed";
…
_custom-icons.scss
The custom icon font is relying on Semantic-UI font icon styling.
@import "custom-icons-variables";
$fontName: 'custom-icons';
$fallbackSRC: url("#{$fontPath}/#{$fontName}.eot");
$src:
url("#{$fontPath}/#{$fontName}.eot?#iefix") format('embedded-opentype'),
url("#{$fontPath}/#{$fontName}.woff") format('woff'),
url("#{$fontPath}/#{$fontName}.ttf") format('truetype'),
url("#{$fontPath}/#{$fontName}.svg?##{$fontName}") format('svg')
;
@font-face {
font-family: $fontName;
src: $fallbackSRC;
src: $src;
font-weight: normal;
font-style: normal;
}
i.icon.aw {
font-family: $fontName !important;
}
.aw-happy {
&:before {
content: $aw-happy;
}
}
.aw-smile {
&:before {
content: $aw-smile;
}
}
.aw-tongue {
&:before {
content: $aw-tongue;
}
}
.aw-sad {
&:before {
content: $aw-sad;
}
}
.aw-wink {
&:before {
content: $aw-wink;
}
}
.aw-grin {
&:before {
content: $aw-grin;
}
}
.aw-cool {
&:before {
content: $aw-cool;
}
}
.aw-angry {
&:before {
content: $aw-angry;
}
}
…
main.scss
Everything in here is global so we avoid webpack adding a hash and allow us to use direct class names in our components (see below for an example).
:global {
@import "_settings/all";
@import "_settings/custom-icons";
@import "_tools/all";
@import "generic";
@import "base";
@import "_objects/all";
@import "_wins/all";
}
test.jsx
Here you can see we use both global and scoped styles.
import React, { Component } from 'react'
import s from './test.scss'
export default class Test extends Component {
render () {
return (
<div className={s['test']}>
<i className='icon aw aw-happy'></i>
<h1>Test</h1>
</div>
)
}
}
test.scss
Yes, for each component that uses our brand colors, we need to reimport the Sass file… I don't know if it's a bad thing, but it works :)
@import "src/styles/_settings/all";
.test {
background: $brown;
color: $white_smoke;
}
Now that background is set, here is the problem:
The aw-happy
icon is rendered as a square (like when your font is not loaded…) and I can't manage to make it work, I tried everything I could after browsing tons of resources :/
We are using Semantic-UI which is built and then bundled with webpack, so I tried to add the @font-face
rule to the semantic.min.css
and also moved fonts files to semantic folder:
semantic.min.css
@font-face {
font-family: 'custom-icons';
src: url(themes/default/assets/fonts/custom-icons.eot);
src: url(themes/default/assets/fonts/custom-icons.eot?#iefix) format('embedded-opentype'),
url(themes/default/assets/fonts/custom-icons.woff) format('woff'),
url(themes/default/assets/fonts/custom-icons.ttf) format('truetype'),
url(themes/default/assets/fonts/custom-icons.svg?#custom-icons) format('svg');
font-weight: normal;
font-style: normal;
}
// Semantic stuff…
And… It works!
I wonder if I'd better build and serve this custom font the same way we do with semantic, but it's annoying to move all the process apart from global styles stuff.
Any idea on how to solve this by keeping all the Sass/Webpack stuff?
Here is the solution I've found by browsing closed bug of react-redux-starter-kit project:
I moved the @font-face
definition to main.scss
, above :global
:
main.scss
$font-path: 'styles/assets/fonts';
$font-name: 'custom-icons';
$fallback-src: url("#{$font-path}/#{$font-name}.eot");
$src:
url("#{$font-path}/#{$font-name}.eot?#iefix") format('embedded-opentype'),
url("#{$font-path}/#{$font-name}.woff") format('woff'),
url("#{$font-path}/#{$font-name}.ttf") format('truetype'),
url("#{$font-path}/#{$font-name}.svg?##{$font-name}") format('svg')
;
@font-face {
font-family: $font-name;
src: $fallback-src;
src: $src;
font-weight: normal;
font-style: normal;
}
It also worked when I defined $font-path
to ../styles/assets/fonts
but not to ./assets/fonts
.
It's a known bug that is referenced at GitHub but davezuko didn't dig into it at this time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With