Material-ui: MaterialUI Icon fontSize overwrriten by Materialicons font CSS when using injectFirst

Created on 16 Feb 2020  ยท  9Comments  ยท  Source: mui-org/material-ui


I am using injectFirst so I can overwrite some MUI styles in my stylesheets. The problem is that the .material-icons class from https://fonts.googleapis.com/icon?family=Material+Icons now overwrites the CSS that <Icon fontSize='small'> sets. So the font-size is always the 24px.

  • [X] The issue is present in the latest release.
  • [X] I have searched the issues of this repository and believe that this is not a duplicate.

Current Behavior ๐Ÿ˜ฏ

.material-icons {} CSS overwrites the one generated my MUI for icons (such as font-size).

Expected Behavior ๐Ÿค”

The Google MaterialIcons CSS is included before any changes made by MUI.

Steps to Reproduce ๐Ÿ•น

Steps:

  1. Use injectFirst on StylesProvider .
  2. Include Material Icons in your CSS (head):
    <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
  3. Use an Icon component and try to change the size: <Icon fontSize='small'>help</Icon>.
  4. The fontSize is still the initial 24px from the .material-icons CSS class.

Context ๐Ÿ”ฆ

Your Environment ๐ŸŒŽ

Windows 10, Chrome 80.

| Tech | Version |
| ----------- | ------- |
| Material-UI | v4.9.3 |
| React | v16.2|
| Browser | Chrome 80|
| TypeScript | 3.7.5|

I don't have a perfect solution for , maybe injectFirst should somehow only inject after the MUI CSS dependencies.

question

All 9 comments

I don't have a perfect solution for , maybe injectFirst should somehow only inject after the MUI CSS dependencies.

You could just set a custom injection point for MUI and put it after your link. Something like this if you use create-react-app:
.env

REACT_APP_MUI_INJECTION=mui-injection

index.html

  <head>
    <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
    <!--%REACT_APP_MUI_INJECTION%-->

Where you have your stylesprovider
```TSX
import { jssPreset, StylesProvider } from '@material-ui/core'
import { create } from 'jss'

const jss = create({
...jssPreset(),
insertionPoint: process.env.REACT_APP_MUI_INJECTION,
})

export function MaterialSetup({children}) {
return ()
}

Thanks @larsenwork, that sounds like a good solution. I am not using react-create-app, I assume I have to also add jss to my project for this? Or is it already used by MUI?

Also, not using react-create-app, I assume I can just use a string instead of the environment variable, right?

@Cristy94 yes, jss is used by MUI so should already be in your project. (And as such shouldn't add to you bundle size since it's already included).

yarn why jss
yarn why v1.22.0
[1/4] ๐Ÿค”  Why do we have the module "jss"...?
[2/4] ๐Ÿšš  Initialising dependency graph...
[3/4] ๐Ÿ”  Finding dependency...
[4/4] ๐Ÿšก  Calculating file sizes...
=> Found "[email protected]"
info Reasons this module exists
   - "@material-ui#styles" depends on it
   - Hoisted from "@material-ui#styles#jss"
   - Hoisted from "@material-ui#styles#jss-plugin-camel-case#jss"
   - Hoisted from "@material-ui#styles#jss-plugin-default-unit#jss"
   - Hoisted from "@material-ui#styles#jss-plugin-global#jss"
   - Hoisted from "@material-ui#styles#jss-plugin-nested#jss"
   - Hoisted from "@material-ui#styles#jss-plugin-props-sort#jss"
   - Hoisted from "@material-ui#styles#jss-plugin-rule-value-function#jss"
   - Hoisted from "@material-ui#styles#jss-plugin-vendor-prefixer#jss"
info Disk size without dependencies: "564KB"
info Disk size with unique dependencies: "2.87MB"
info Disk size with transitive dependencies: "2.91MB"
info Number of shared dependencies: 5
โœจ  Done in 0.92s.

If you don't mind hardcoding a variable name twice you can do:
index.html

  <head>
    <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
    <!--mui-insertion-point-->

Where you have your stylesprovider

import { jssPreset, StylesProvider } from '@material-ui/core'
import { create } from 'jss'

const jss = create({
  ...jssPreset(),
  insertionPoint: 'mui-insertion-point',
})

export function MaterialSetup({children}) {
  return (<StylesProvider jss={jss}>{children}</StylesProvider>)
}

@Cristy94 remember to close issue if it fixed your problem ๐Ÿ™‚

@larsenwork Thanks for helping!

I just now tried your solution and it worked. Thank you!

This worked great in development, but there's an issue: in production when you bundle and minify everything that <!--mui-insertion-point--> is removed, as all comments are removed. What's the best way to ensure this still works in production and is not removed when minifying with terser?

@Cristy94 We document alternatives to the HTML comment.

Thanks a lot! Ended up doing this:

const muiInsertionFlag = 'mui-insertion-point';
const styleNode = document.createComment(muiInsertionFlag);
document.head.insertBefore(styleNode, document.head.firstChild);

const jss = create({
    ...jssPreset(),
    insertionPoint: muiInsertionFlag,
});

I spent a lot of time trying to make terser (with ParcelJS) keep the HTML comments but it didn't work. This worked and it also solves the identifier name syncing issue mentioned above.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

TimoRuetten picture TimoRuetten  ยท  3Comments

sys13 picture sys13  ยท  3Comments

revskill10 picture revskill10  ยท  3Comments

rbozan picture rbozan  ยท  3Comments

ryanflorence picture ryanflorence  ยท  3Comments