I've been wondering what the CssBaseline class in the Material-UI React library does, but I can't seem to find an answer anywhere, and the page I linked doesn't do much explaining about what the class does. Does anyone here know what this component is supposed to do?
CssBaseline is sort of css reset added to the <head /> of your document. If you are familiar with similar approaches like normalize.css which adds some default visual styling to default elements, resets paddings and etc ...
Material-UI provides some reset styles as you can observe here CssBasline.js mainly box-sizing and body font color and background color
'#global': {
html: {
WebkitFontSmoothing: 'antialiased', // Antialiasing.
MozOsxFontSmoothing: 'grayscale', // Antialiasing.
// Change from `box-sizing: content-box` so that `width`
// is not affected by `padding` or `border`.
boxSizing: 'border-box',
},
'*, *::before, *::after': {
boxSizing: 'inherit',
},
'strong, b': {
fontWeight: 'bolder',
},
body: {
margin: 0, // Remove the margin in all browsers.
color: theme.palette.text.primary,
...theme.typography.body2,
backgroundColor: theme.palette.background.default,
'#media print': {
// Save printer ink.
backgroundColor: theme.palette.common.white,
},
},
The docs say that its a collection of HTML element and attribute style-normalizations. It's based on normalize.js, which is a modern cross-browser CSS reset for your HTML elements that preserves some of the defaults.
Basically, it resets your CSS to a consistent baseline. That way, you can restyle your HTML doc so that you know you can expect all of the elements to look the same across all browsers.
What normalize.js does, from the readme linked above:
Preserves useful defaults, unlike many CSS resets.
Normalizes styles for a wide range of elements. Corrects bugs and common browser
inconsistencies.
Improves usability with subtle modifications.
Explains what code does using detailed comments.
import { createMuiTheme } from "#material-ui/core/styles";
const theme = createMuiTheme({
overrides: {
MuiCssBaseline: {
"#global": {
"*, *::before, *::after": {
boxSizing: "content-box",
},
body: {
backgroundColor: "#fff",
},
},
},
},
});
export default theme;
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import { BrowserRouter } from "react-router-dom";
import { MuiThemeProvider } from "#material-ui/core/styles";
import theme from "./Theme/Theme";
ReactDOM.render(
<MuiThemeProvider theme={theme}>
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
</MuiThemeProvider>,
document.getElementById("root")
);
serviceWorker.unregister();
Basically, The MUI provides MuiCssBaseline that overrides some of our CSS styles. But MUI
provides the flexibility to override its default style. Here is what I have implemented
1: Create a theme.js and import createMuiTheme. Then override the styles of MuiBaseline based on your requirements and export the theme.js.
2.If you want the overridden style all over your application then import theme.js, MuiThemeProvider from material-ui/core/styles into your index.js, MuiThemeProvider takes the theme as an argument and then applies the style to its children components.
Related to - but I can't seem to find an answer anywhere.
You can find code for CssBaseLine in the repository for the Material-UI library on Github by following link.
By putting at top of your component is used for providing a lot of default styling for your material UI applications so that you don't have to worry about basic styles of your component
Related
I am using Ant Design in a React project of mine, and I am attempting to make use of their custom theming available in version 5 (5.1.2 installed) according to documentation here. However, the custom theme appears to only apply to certain components while skipping others altogether. In the below example, the darker background color is applied to the Content and Footer components while the Header and Sider components are left with the default color, and the Header and Footer components have updated foreground colors, but the Sider and Content components do not. What am I missing to make this theme apply in full to each of these components?
Example:
src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import { ConfigProvider } from 'antd';
import theme from './theme';
import reducers from './reducers';
import App from './components/App';
const store = createStore(reducers)
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<ConfigProvider theme={theme}>
<React.StrictMode>
<App />
</React.StrictMode>
</ConfigProvider>
</Provider>
);
src/theme.js
import { theme } from 'antd';
const custom_theme = {
algorithm: theme.darkAlgorithm,
token: {
colorPrimary: '#e02820',
borderRadius: 5,
wireframe: false
},
}
export default custom_theme;
src/components/App.js
import React from 'react';
import { Layout } from 'antd';
const { Header, Footer, Sider, Content } = Layout;
class App extends React.Component {
render() {
return (
<Layout>
<Header>header</Header>
<Layout>
<Sider>sider</Sider>
<Content>content</Content>
</Layout>
<Footer>footer</Footer>
</Layout>
);
}
}
export default App;
Result:
I have been playing around with AntD custom theme as well and have found that not every attribute can be updated. The main changes allowed are colorPrimary and according to the documentation based on this color their algorithm chooses the rest of the color pallet that matches.
From documentation - "Brand color is one of the most direct visual elements to reflect the characteristics and communication of the product. After you have selected the brand color, we will automatically generate a complete color palette and assign it effective design semantics."
That being said you can try to be even more specific. By that I mean you can specify the style for each separate component.
<ConfigProvider
theme={{
components: {
Header: {
colorPrimary: '#00b96b',
},
Footer: {
colorPrimary: '#fff',
},
},
}}
>
Just change and add your desired styles to each component. If it still does not change, then that is the color AntD will let you have based for each component based on your choice of primary color.
Another option would be to use styled-components library to further provide the styles to AntD components that are not possible using Ants Config API.
If this provides the valid solution would you please click the green arrow on my response to inform others of the solution.
Hi I was looking in a way to change the hover color from IconButton However the solution-sandbox that I found doesn't seem to be working anymore
This is what I have Code-Sandbox
From https://mui.com/guides/migration-v4/#style-library:
The style library used by default in v5 is emotion. While migrating from JSS to emotion, and if you are using JSS style overrides for your components (for example overrides created by makeStyles), you will need to take care of the CSS injection order. To do so, you need to have the StyledEngineProvider with the injectFirst option at the top of your component tree.
If I change your index.js to the following, the style overrides work:
import { StyledEngineProvider } from "#mui/material/styles";
import ReactDOM from "react-dom";
import App from "./App";
const rootElement = document.getElementById("root");
ReactDOM.render(
<StyledEngineProvider injectFirst>
<App />
</StyledEngineProvider>,
rootElement
);
In addition to adding <StyledEngineProvider injectFirst>, I also removed StrictMode since makeStyles doesn't support it -- styles generated by makeStyles will not get maintained in the DOM reliably in strict mode.
Since you're using v5, the better option would be to avoid makeStyles (which is deprecated in v5) entirely and use styled instead. Then you don't need the index.js changes and can keep strict mode.
import React from "react";
import { styled } from "#mui/material/styles";
import IconButton from "#mui/material/IconButton";
const StyledIconButton = styled(IconButton)(`
&:hover, &.Mui-focusVisible {
background-color: yellow;
}
`);
You should add !important to your style then it should work
const useStyles = makeStyles((theme) => ({
customHoverFocus: {
"&:hover, &.MuiIconButton": { background: "yellow !important" }
}
}));
Using Material-UI DataGrid, the default font in table is too small to see text.
My code is literally a copy/paste of their demo on the page:
https://material-ui.com/components/data-grid/
My fonts are very small in the table. Rest of page not using Mui (menu etc.) are fine.
In Firefox dev tools Inspector I see
Inherited from div:
.MuiDataGrid-root { font-size: 0.875rem; }
Changing that in the browser tool to something like 10px, or disabling it completely, confirms thats the value needing change.
It's being automatically added at end (inline) when compiled so it overwrites my previous style. The silly thing is, I can't find where this is being added.
I've looked at several sites using this same table as examples and none have this issue.
Can someone enlighten me where to look, how to fix the table having incorrect default font size?
I have these relevant bits:
package.json:
"#material-ui/core": "^4.11.0",
"#material-ui/data-grid": "^4.0.0-alpha.6",
"fontsource-roboto": "^3.0.3",
Index.html
<meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width" />
Abbreviated .jsx code:
import React from 'react';
import { DataGrid } from '#material-ui/data-grid';
const DemoTableMui = () => {
...
const columns = [{ field: 'id', headerName: 'ID', width: 70 } ]
const rows = [{ id: 1, lastName: 'Smith', firstName: 'Jon', age: 35 } ]
return (
<div style={{ height: 600, width: '100%' }}>
<DataGrid rows={rows} columns={columns} pageSize={5} checkboxSelection />
</div>
);
};
export default DemoTableMui
Since the dev tool indicated it is inherited from div I did stuff like:
return (
<div style={{ height: 600, width: '100%', fontSize:25 }}>
...
But nothing had effect. I'm sure the div it is referring to is buried down in the <DataGrid/> component...
Based on OP feedback, putting an answer here.
Isolating the CSS problem.
if you are using a theme, start with the file that has the DIV root. That is where styles are included.
start looking the specific CSS class that is affecting, and instead of changing the value - which won't work as you have already seen.
Make a copy of the CSS class, give it a different name, and set the desired value and then use this new class.
Alternatively (based on the OP update in the comments)
Consider abandoning any usage of themes just use the standard themes such as bootstrap (or react strap, if you are on react js), which wont have these problems.
Themes tend to have a mix of native components and also standard components. In most cases, they will have two folders. one for bootstrap css files and another for theme css files.
Unless you are already experienced with the theme, making changes can become tricky. Use the standard bootstrap components, which use standardized names and hence, no complications.
So the best way to use material-UI IMO is to customize the theme at the root level, and then all of the components should inherit the styling in a uniform kind of way. This is what my App.tsx looks like
import {
createMuiTheme,
MuiThemeProvider
} from "#material-ui/core/styles";
const theme = createMuiTheme({
palette: {
type: 'dark'
},
typography: {
fontSize: 12
},
// overrides: {
// MuiTypography: {
// colorInherit:{
// color: "#fff"
// }
// }
});
function App() {
return (
<MuiThemeProvider theme={theme}>
<LeadPage/>
</MuiThemeProvider>
);
}
export default App;
Setting the typography will trickle down to the class .MuiDataGrid-root.
I left the palette up there which changes the font color of the grid, and the commented out code is a an example of overriding the class at the theme level, in case you need to tweak that grid further. My example would be if you saw .MuiTypography-colorInherit in the debugger.
import { MuiThemeProvider } from "#material-ui/core/styles";
...
import { createTheme } from '#material-ui/core';
export const muiTheme = createTheme({
typography: {
fontFamily: 'Poppins Regular',
},
});
...
<MuiThemeProvider theme={muiTheme}>...</MuiThemeProvider>
Focused, checked classes seems to not work properly.
I need to always use !important or use jss styles provided by material-ui.
For example:
https://codesandbox.io/s/css-modules-nvy8s?file=/src/CssModulesButton.js
CssModulesButton.module.css
.checkboxtest {
color: blue;
}
.checkboxtestworking {
color: blue !important;
}
CssModulesButton.js
import React from "react";
// webpack, parcel or else will inject the CSS into the page
import styles from "./CssModulesButton.module.css";
import Checkbox from "#material-ui/core/Checkbox/Checkbox";
export default function CssModulesButton() {
return (
<div>
<Checkbox classes={{ checked: styles.checkboxtest }}>testasd</Checkbox>
<Checkbox classes={{ checked: styles.checkboxtestworking }}>
testasd
</Checkbox>
</div>
);
}
index.js
import React from "react";
import { render } from "react-dom";
import { StylesProvider } from "#material-ui/core/styles";
import CssModulesButton from "./CssModulesButton";
import CssBaseline from "#material-ui/core/CssBaseline";
const App = () => <CssModulesButton />;
render(<App />, document.querySelector("#root"));
I cant overwrite Checkbox color in any other way than using !important.
The problem persists when using classes={{focused:styles.focused}} and many others.
Is there a way to simply overwrite components with classes without !important? Sometimes even !important doesnt work
inb4 im using injectFirst
You mentioned injectFirst in your question, though your sandbox example wasn't using it. You should use it since this will make sure that the CSS from your CSS modules is inserted after the Material-UI CSS in the <head> element. When specificity is the same, the styles that occur later will win over earlier styles.
The default styles for the checkbox colors are as follows:
colorSecondary: {
'&$checked': {
color: theme.palette.secondary.main,
'&:hover': {
backgroundColor: fade(theme.palette.secondary.main, theme.palette.action.hoverOpacity),
// Reset on touch devices, it doesn't add specificity
'#media (hover: none)': {
backgroundColor: 'transparent',
},
},
},
'&$disabled': {
color: theme.palette.action.disabled,
},
},
Below is the corresponding CSS generated by JSS:
.MuiCheckbox-colorSecondary.Mui-checked {
color: #f50057;
}
.MuiCheckbox-colorSecondary.Mui-disabled {
color: rgba(0, 0, 0, 0.26);
}
.MuiCheckbox-colorSecondary.Mui-checked:hover {
background-color: rgba(245, 0, 87, 0.04);
}
#media (hover: none) {
.MuiCheckbox-colorSecondary.Mui-checked:hover {
background-color: transparent;
}
}
The important aspect to notice is that the checked style is done via two classes. In order to override these styles you need that same degree of specificity or greater.
Below is a full working example overriding the checked color of the checkbox:
index.js (important part here is <StylesProvider injectFirst>)
import React from "react";
import { render } from "react-dom";
import { StylesProvider } from "#material-ui/core/styles";
import CssModulesButton from "./CssModulesButton";
const App = () => (
<StylesProvider injectFirst>
<CssModulesButton />
</StylesProvider>
);
render(<App />, document.querySelector("#root"));
CssModulesButton.module.css
Uses two classes in the style declaration -- the checkboxtest CSS module class and Mui-checked (the global class which Material-UI adds for the checked state)
.checkboxtest:global(.Mui-checked) {
color: blue;
}
CssModulesButton.js
import React from "react";
import styles from "./CssModulesButton.module.css";
import Checkbox from "#material-ui/core/Checkbox";
export default function CssModulesButton() {
return (
<div>
<Checkbox className={styles.checkboxtest} />
</div>
);
}
Follow-up question from the comments:
Could you explain why can't I use classes? Shouldn't classes={{checked:styles.AnyClass}} overwrite the styles successfully? I understand why it doesn't, but what is the purpose of classes then?
You can use the classes prop, but there isn't any compelling reason to do so in this case. The following will also work, so long as the declaration for the styles is the same (using two CSS classes) so that you have the appropriate degree of specificity:
<Checkbox classes={{ checked: styles.checkboxtest }} />
As far as the second part of your question ("what is the purpose of classes then?"), there are two main reasons to use the classes prop. Some of the CSS classes for the classes prop get applied to different elements within the component, and some only get applied when the component is in a particular state, or when certain props have been used on the component. In this case, you are trying to target these styles for a particular state of the component. In v3 of Material-UI, you would have needed to use the classes prop to provide a class name that would only be applied for the checked state, but in v4 Material-UI switched to using global class names for these states (more details here: https://material-ui.com/customization/components/#pseudo-classes) such as Mui-checked. This makes it easier to target these states via a single generated class (a big driver of this change was to make it easier to customize Material-UI components using styled-components).
I'm trying to import and use the Yellowtail font (from Google Fonts) in my React app in a Material-UI theme.
As far as i know all google fonts are on npm, I've installed it, with the
npm install typeface-yellowtail --save
command.
I have imported it in App.js, put it in the font-family part of the theme, passed the theme to the MuiThemeProvider, but it does not work. What did I miss?
This is what i have inside of App.js (header contains an AppBar with some grids and body contains only an h1 text for testing)
import React, { Component, Fragment } from 'react';
import Header from './Components/Layouts/Header';
import AppBody from './Components/Layouts/AppBody';
import Footer from './Components/Layouts/Footer';
import { MuiThemeProvider, createMuiTheme } from '#material-ui/core';
import 'typeface-yellowtail';
const theme = createMuiTheme({
typography: {
fontFamily:
'"Yellowtail", cursive',
},
});
class App extends Component {
render() {
return (
<MuiThemeProvider theme={theme}>
<Header />
<AppBody />
<Footer />
</MuiThemeProvider>
);
}
}
export default App;
Instead of installing via npm, you can just first load CSS file.
#import url('https://fonts.googleapis.com/css?family=Yellowtail&display=swap');
Import this CSS file
import './assets/css/yellowtail.css';
Now you don't need to use any #font-face. This can be used with font families like normal.
You are missing three things:
Import the npm package as something
Use the CssBaseline component
Add an override to the object provided to createMuiTheme()
See example:
import React, { Component, Fragment } from 'react';
import Header from './Components/Layouts/Header';
import AppBody from './Components/Layouts/AppBody';
import Footer from './Components/Layouts/Footer';
import { MuiThemeProvider, createMuiTheme, CssBaseline } from '#material-ui/core';
import yellowtail from 'typeface-yellowtail';
const theme = createMuiTheme({
typography: {
fontFamily:
'"Yellowtail", cursive',
},
overrides: {
MuiCssBaseline: {
'#global': {
'#font-face': [yellowtail],
},
},
},
});
class App extends Component {
render() {
return (
<MuiThemeProvider theme={theme}>
<CssBaseline />
<Header />
<AppBody />
<Footer />
</MuiThemeProvider>
);
}
}
export default App;
Example CodeSandbox (MUI v3): https://codesandbox.io/s/late-pond-gqql4?file=/index.js
Example CodeSandbox (MUI v4): https://codesandbox.io/s/pensive-monad-eqwlx?file=/index.js
Notes
MuiThemeProvider changed to ThemeProvider in the transition from Material-UI v3 to v4. If you are on v4, this is the only change needed - this example code otherwise works on both versions.
You must wrap text in Material-UI's Typography component for the font to be used.
There is a much easier way of doing this that doesn't require a .css file or installing any extra packages.
If your font is available over a CDN like Google Fonts then just imported into the root HTML file of your app:
<link
href="https://fonts.googleapis.com/css2?family=Yellowtail&display=swap"
rel="stylesheet"
/>
Then add one line in the Material-UI theme:
const theme = createTheme({
typography: { fontFamily: ["Yellowtail", "cursive"].join(",") }
});
Working codesandbox example with Material-UI v5.
Update: Since #ekkis mentioned I'm adding further details on how to include the Google Font. The following answer assumes you're using Material UI v4.10.1
Install the gatsby-plugin-web-font-loader to install Google font.
Edit gatsby-config.js to include the plugin and the Google font.
module.exports = {
plugins: [
{
resolve: "gatsby-plugin-web-font-loader",
options: {
google: {
families: ["Domine", "Work Sans", "Happy Monkey", "Merriweather", "Open Sans", "Lato", "Montserrat"]
}
}
},
]
}
To use the font, create a file called theme.js in src/components
import {
createMuiTheme,
responsiveFontSizes
} from "#material-ui/core/styles"
let theme = createMuiTheme({
typography: {
fontFamily: [
"Work Sans",
"serif"
].join(","),
fontSize: 18,
}
})
// To use responsive font sizes, include the following line
theme = responsiveFontSizes(theme)
export default theme
Now that you've the theme export, you can use it in your components.
Import theme on to your components. Let's say <Layout /> is your main component.
// src/components/layout.js
/**
* External
*/
import React from "react"
import PropTypes from "prop-types"
import {
ThemeProvider
} from "#material-ui/styles"
import { Typography } from "#material-ui/core"
/**
* Internal
*/
import theme from "./theme"
const Layout = ({ children }) => {
return (
<>
<ThemeProvider theme={theme}>
<Typography variant="body1">Hello World!</Typography>
</ThemeProvider>
</>
)
}
To use Google font in other components, just use
<Typography ...>Some Text</Typography>
As long as these components use as their parent, these components will continue to use the Google Font. Hope this helps.
Old Answer:
Place your text in the Typography component to reflect the Google Font you installed via npm
import { Typography } from "#material-ui/core"
Assume you have some text in <AppBody>
<AppBody>
Hello World!
</AppBody>
The above text should now be changed to
<AppBody>
<Typography variant="body1">Hello World!</Typography>
</AppBody>
Refer Material UI docs for the different variants.
I have define my font in main CSS file(index.css)
#font-face {
font-family: 'mikhak';
src: url(./fonts/mikhak.ttf) format("truetype")
}
and then in the App.tsx I added theme
const theme = createTheme({
typography: {
fontFamily: 'mikhak, Raleway, Arial',
}
});
ReactDOM.render(
<ThemeProvider theme={theme}>
<App />
</ThemeProvider>,
document.getElementById('root')
);
Note that it is for Typography components.
This worked for me:
Install your font as a package using #fontsource on npm, i.e:
npm i #fontsource/work-sans
Add to your _app.js your import, this makes your package (font) accessible globally
const workSans = require('#fontsource/work-sans');
In your theme modify your typography:
...
typography: {
fontFamily: 'Work Sans',
}
...
That's it!
I want to add to #georgeos answer that a small revision of the proposed solution worked for me:
export const theme = createTheme({
...
components: {
MuiCssBaseline: {
styleOverrides: {
'#global': {
'#font-face': [Inter, Nunito],
},
},
},
},
...
});
I also needed to add the following to the app.ts file (source):
function App(){
...
return (
<ThemeProvider theme={theme}>
<CssBaseline enableColorScheme /> <---
...
</ThemeProvider>);
...
}