MUI 组件中的媒体查询

我在 ReactJs项目中使用 MUI 组件,由于某些原因,我需要在一些组件中进行定制,使其根据屏幕宽度响应。

我已经添加了 media query,并将其作为样式属性传递给组件,但是没有工作,有什么想法吗?

我使用的代码是这样的:

const drawerWidth = {
width: '50%',
'@media(minWidth: 780px)' : {
width: '80%'
}
}


<Drawer
.....
containerStyle = {drawerStyle}
>
</Drawer>

代码只对 web 有效,对移动设备无效。甚至 CSS代码也没有应用,我已经在开发者控制台检查过了。我使用的是 MUI 版本 0.18.7

如果你能帮忙,我将不胜感激。

PS: 根据需要,我需要使用 CSS根据屏幕大小做一些更改。

139765 次浏览

In the style property on React you can only define properties that you can define in a normal DOM element (You can't include media queries for example)

The way you can include media queries for that component would be passing a class name to the Drawer Component

<Drawer containerClassName="someClass" />

And then in a CSS file you do something like this

@media(min-width: 780px){
.someClass {
width: 50%!important;
}
}

I've solved this problem by doing something like this:

const dropzoneStyles =
window.screen.availWidth < 780 ?
{ 'width': '150px', 'height': '150px', 'border': 'none', 'borderRadius': '50%' }
: { 'width': '200px', 'height': '200px', 'border': 'none', 'borderRadius': '50%' };

and then appending it as an attribute in the Material UI element:

<Dropzone style={dropzoneStyles} onDrop={this.handleDrop.bind(this)}>

So the key is to find out the window screen using window.screen.availWidth. And you would be doing this in the render() function. Hope that helps!

By using the breakpoints attribute of the theme, you can utilize the same breakpoints used for the Grid and Hidden components directly in your component.

API

theme.breakpoints.up(key) => media query

Arguments

key (String | Number): A breakpoint key (xs, sm, etc.) or a screen width number in pixels.

Returns media query: A media query string ready to be used with JSS.

Examples

const styles = theme => ({
root: {
backgroundColor: 'blue',
[theme.breakpoints.up('md')]: {
backgroundColor: 'red',
},
},
});

for more information check this out

So here is what you can do (quick hack). Material UI will complain about you doing an unnecessary calculation though.

const styles = {
drawerWidth: {
width: '50%',
['@media (min-width:780px)']: { // eslint-disable-line no-useless-computed-key
width: '80%'
}
}
}

You have a typo in the media query. You should use the following syntax and it will work as expected:

const drawerWidth = {
width: '50%',
'@media (min-width: 780px)' : {
width: '80%'
}
}

instead of

const drawerWidth = {
width: '50%',
'@media(minWidth: 780px)' : {
width: '80%'
}
}

Similiar answer to @Lipunov's, based on @nbkhope's comment

const styles = {
drawerWidth: {
width: '50%',
[theme.breakpoints.up(780)]: {
width: '80%'
}
}
}

Create a variable and then use that variable anywhere in the function

import React from 'react';
import { createMuiTheme, ThemeProvider, useTheme } from '@materialui/core/styles';
import useMediaQuery from '@material-ui/core/useMediaQuery';
    



function MyComponent() {
const theme = useTheme();
const matches = useMediaQuery(theme.breakpoints.up('sm')); // Variable for media query
return <span hidden={matches}>Hidden on screen size greater then sm </span>;
}


const theme = createMuiTheme();


export default function ThemeHelper() {
return (
<ThemeProvider theme={theme}>
<MyComponent />
</ThemeProvider>
);
}

In MUI v5, breakpoints can be declared in sx props by specifying an object where the keys are the breakpoint names and the values are the CSS values.

You can see MUI default breakpoints here. The breakpoint names and values can be overrided using createTheme():

const theme = createTheme({
breakpoints: {
values: {
xxs: 0, // small phone
xs: 300, // phone
sm: 600, // tablets
md: 900, // small laptop
lg: 1200, // desktop
xl: 1536 // large screens
}
}
});
return (
<ThemeProvider theme={theme}>
<Box
sx=\{\{
// specify one value that is applied in all breakpoints
color: 'white',
// specify multiple values applied in specific breakpoints
backgroundColor: {
xxs: "red",
xs: "orange",
sm: "yellow",
md: "green",
lg: "blue",
xl: "purple"
}
}}
>
Box 1
</Box>
</ThemeProvider>
);

In the example above, xs: "orange" means set the Box color to orange if the screen width is inside xs range [300, 600).

You can also set the breakpoints using an array consists of the values from the smallest to largest breakpoint:

return (
<ThemeProvider theme={theme}>
<Box
sx=\{\{
backgroundColor: [
"red",
"orange",
// unset, screen width inside this breakpoint uses the last non-null value
null,
"green",
"blue",
"purple"
]
}}
>
Box 2
</Box>
</ThemeProvider>
);

Edit 45847090/media-queries-in-material-ui-components

CSS media queries are the idiomatic approach to make your UI responsive. The theme provides five styles helpers to do so:

theme.breakpoints.up(key)
theme.breakpoints.down(key)
theme.breakpoints.only(key)
theme.breakpoints.not(key)
theme.breakpoints.between(start, end)

In the following stress test, you can update the theme color and the background-color property live:

const styles = (theme) => ({
root: {
padding: theme.spacing(1),
[theme.breakpoints.down('md')]: {
backgroundColor: theme.palette.secondary.main,
},
[theme.breakpoints.up('md')]: {
backgroundColor: theme.palette.primary.main,
},
[theme.breakpoints.up('lg')]: {
backgroundColor: green[500],
},
},
});
<Root>
<Typography>down(md): red</Typography>
<Typography>up(md): blue</Typography>
<Typography>up(lg): green</Typography>
</Root>

Know more

In my case I just needed the breakpoint on one component and I found the createTheme approach a little bit too much. I ended using useMediaQuery and useTheme.

I see that with useMEdiaQuery you can be quite granular

import { useTheme } from '@mui/material/styles';
import useMediaQuery from '@mui/material/useMediaQuery';


const Component = () => {
const theme = useTheme();
const matchesSM = useMediaQuery(theme.breakpoints.down('sm'));
const matchesMD = useMediaQuery(theme.breakpoints.only('md'));
const dynamicStyles = {
...matchesSM && {margin: '10px 0'},
...matchesMD && {margin: '20px 0'}
}


return (
<Grid item xs={12} md={4} sx=\{\{...dynamicStyles}}>
<div>Children</div>
</Grid>
)
}