[theming] @font-face at-rule broken in styleOverrides
See original GitHub issue- The issue is present in the latest release.
- I have searched the issues of this repository and believe that this is not a duplicate.
Current Behavior 😯
When specifying multiple @font-face
at-rules via an array in MuiCssBaseline.styleOverrides
, a single @font-face
block is output rather than multiple @font-face
declarations. The final rule thus takes precedence, ignoring all previous rules.
Expected Behavior 🤔
Specifying multiple @font-face
at-rules should result in multiple @font-face
declarations, allowing us to specify multiple faces for different font variants.
Steps to Reproduce 🕹
This is tough to build on CodeSandbox since it involves theming and it’s hard to get that set up on there to render correctly. But you should be able to reproduce with the dummy code below in ANY theme in your local environment.
Steps:
- Build any theme using
createMuiTheme
- Specify
@font-face
with several values inMuiCssBaseline.styleOverrides
as designated below:
const theme = createMuiTheme({
MuiCssBaseline: {
styleOverrides: {
"@font-face": [
{
fontFamily: "Inter",
fontStyle: "normal",
fontDisplay: "swap",
fontWeight: 300,
src:
"url('/fonts/inter/Inter-Light.woff2?v=3.15') format('woff2'),url('/fonts/inter/Inter-Light.woff?v=3.15') format('woff')"
},
{
fontFamily: "Inter",
fontStyle: "italic",
fontDisplay: "swap",
fontWeight: 300,
src:
"url('/fonts/inter/Inter-LightItalic.woff2?v=3.15') format('woff2'),url('/fonts/inter/Inter-LightItalic.woff?v=3.15') format('woff')"
},
{
fontFamily: "Inter",
fontStyle: "normal",
fontDisplay: "swap",
fontWeight: 400,
src:
"url('/fonts/inter/Inter-Regular.woff2?v=3.15') format('woff2'),url('/fonts/inter/Inter-Regular.woff?v=3.15') format('woff')"
},
{
fontFamily: "Inter",
fontStyle: "italic",
fontDisplay: "swap",
fontWeight: 400,
src:
"url('/fonts/inter/Inter-Italic.woff2?v=3.15') format('woff2'),url('/fonts/inter/Inter-Italic.woff?v=3.15') format('woff')"
},
]
}
}
});
- Use the
CssBaseline
component inside yourThemeProvider
:
<ThemeProvider theme={theme}>
<CssBaseline />
{/* eslint-disable-next-line react/jsx-props-no-spreading */}
<Component {...pageProps} />
</ThemeProvider>
- Observe that the corresponding injected
<style>
tag contains the following:
<style data-emotion="css-global" data-s="">
@font-face{font-family:Inter;font-style:normal;font-display:swap;font-weight:300;src:url('/fonts/inter/Inter-Light.woff2?v=3.15') format('woff2'),url('/fonts/inter/Inter-Light.woff?v=3.15') format('woff');font-family:Inter;font-style:italic;font-display:swap;font-weight:300;src:url('/fonts/inter/Inter-LightItalic.woff2?v=3.15') format('woff2'),url('/fonts/inter/Inter-LightItalic.woff?v=3.15') format('woff');font-family:Inter;font-style:normal;font-display:swap;font-weight:400;src:url('/fonts/inter/Inter-Regular.woff2?v=3.15') format('woff2'),url('/fonts/inter/Inter-Regular.woff?v=3.15') format('woff');font-family:Inter;font-style:italic;font-display:swap;font-weight:400;src:url('/fonts/inter/Inter-Italic.woff2?v=3.15') format('woff2'),url('/fonts/inter/Inter-Italic.woff?v=3.15') format('woff');}
</style>
Notice that there’s only a single @font-face
at-rule containing each rule rather than a @font-face
at-rule for EACH object specified. This results in every font rendering using whatever the last rule is (in this case, italic).
What SHOULD happen is this:
<style data-emotion="css-global" data-s="">
@font-face{font-family:Inter;font-style:normal;font-display:swap;font-weight:300;src:url('/fonts/inter/Inter-Light.woff2?v=3.15') format('woff2'),url('/fonts/inter/Inter-Light.woff?v=3.15') format('woff');}
@font-face{font-family:Inter;font-style:italic;font-display:swap;font-weight:300;src:url('/fonts/inter/Inter-LightItalic.woff2?v=3.15') format('woff2'),url('/fonts/inter/Inter-LightItalic.woff?v=3.15') format('woff');}
@font-face{font-family:Inter;font-style:normal;font-display:swap;font-weight:400;src:url('/fonts/inter/Inter-Regular.woff2?v=3.15') format('woff2'),url('/fonts/inter/Inter-Regular.woff?v=3.15') format('woff');}
@font-face{font-family:Inter;font-style:italic;font-display:swap;font-weight:400;src:url('/fonts/inter/Inter-Italic.woff2?v=3.15') format('woff2'),url('/fonts/inter/Inter-Italic.woff?v=3.15') format('woff');}
</style>
Context 🔦
Trying to define multiple @font-face declarations in order to render multiple font variations of a single typeface.
Your Environment 🌎
`npx @material-ui/envinfo`
System:
OS: macOS 11.2
Binaries:
Node: 14.4.0 - /usr/local/bin/node
Yarn: Not Found
npm: 6.14.11 - /usr/local/bin/npm
Browsers:
Chrome: 88.0.4324.150
Edge: Not Found
Firefox: 84.0.2
Safari: 14.0.3
npmPackages:
@emotion/react: ^11.1.5 => 11.1.5
@emotion/styled: ^11.1.5 => 11.1.5
@material-ui/core: ^5.0.0-alpha.25 => 5.0.0-alpha.25
@material-ui/icons: ^5.0.0-alpha.24 => 5.0.0-alpha.24
@material-ui/styled-engine: 5.0.0-alpha.25
@material-ui/styles: 5.0.0-alpha.25
@material-ui/system: 5.0.0-alpha.25
@material-ui/types: 5.1.7
@material-ui/unstyled: 5.0.0-alpha.25
@material-ui/utils: 5.0.0-alpha.25
@types/react: ^17.0.2 => 17.0.2
react: ^17.0.1 => 17.0.1
react-dom: ^17.0.1 => 17.0.1
typescript: ^4.1.5 => 4.1.5
Using with Next.js though that shouldn’t matter. 😃
Issue Analytics
- State:
- Created 3 years ago
- Reactions:5
- Comments:10 (6 by maintainers)
Top GitHub Comments
for multiple font-faces the fallbacks syntax works fine;
@ZLevine Thanks for opening the issue. There are multiple aspects to it:
This works with emotion and styled-components. Without the change, it only works with emotion once wrapped with
import { css } from @material-ui/styled-engine
;cc @mnajdova