Material UI 有一组很好的内置媒体查询:https://material-ui.com/customization/breakpoints/#css-media-queries
Material UI 还允许我们将 Styled-Components 与 Material UI 一起使用:https://material-ui.com/guides/interoperability/#styled-components
我想知道如何将两者结合在一起。也就是说,如何使用 Styled Components 和 Material-UI 的内置断点进行媒体查询?
谢谢。
更新:
这是我正在尝试做的一个例子:
import React, { useState } from 'react'
import styled from 'styled-components'
import {
AppBar as MuiAppBar,
Drawer as MuiDrawer,
Toolbar,
} from '@material-ui/core'
const drawerWidth = 240
const AdminLayout = ({ children }) => {
return (
<BaseLayout>
<AppBar position="static">
<Toolbar>
TOOLBAR
</Toolbar>
</AppBar>
<Drawer>
DRAWER
</Drawer>
{children}
</BaseLayout>
)
}
AdminLayout.propTypes = {
children: PropTypes.node.isRequired,
}
export default AdminLayout
// ------- STYLES -------
const AppBar = styled(MuiAppBar)`
/* Implement appBar styles from useStyles */
`
const Drawer = styled(MuiDrawer)`
/* Implement drawer styles from useStyles */
`
// STYLES THAT I WANT TO CONVERT TO STYLED-COMPONENTS
const useStyles = makeStyles(theme => ({
root: {
display: 'flex',
},
drawer: {
[theme.breakpoints.up('sm')]: {
width: drawerWidth,
flexShrink: 0,
},
},
appBar: {
[theme.breakpoints.up('sm')]: {
width: `calc(100% - ${drawerWidth}px)`,
marginLeft: drawerWidth,
},
},
toolbar: theme.mixins.toolbar,
}))
下面的示例展示了利用 Material-UI 主题断点和样式组件的一种方法。这会将 Material-UI 主题传递给样式组件
ThemeProvider
,以便使其可以作为样式中的道具使用。该示例还将 StylesProvider
与 injectFirst
属性一起使用,以便 Material-UI 样式将出现在 <head>
的开头而不是末尾,以便样式化组件样式出现在 Material-UI 样式之后因此,当特异性相同时获胜。
import React from "react";
import styled, { ThemeProvider as SCThemeProvider } from "styled-components";
import { useTheme, StylesProvider } from "@material-ui/core/styles";
import MuiAppBar from "@material-ui/core/AppBar";
const AppBar = styled(MuiAppBar)`
background-color: red;
${props => props.theme.breakpoints.up("sm")} {
background-color: orange;
}
${props => props.theme.breakpoints.up("md")} {
background-color: yellow;
color: black;
}
${props => props.theme.breakpoints.up("lg")} {
background-color: green;
color: white;
}
`;
export default function App() {
const muiTheme = useTheme();
return (
<StylesProvider injectFirst>
<SCThemeProvider theme={muiTheme}>
<AppBar>Sample AppBar</AppBar>
</SCThemeProvider>
</StylesProvider>
);
}
相关文档:
如果您对样式组件使用“样式对象”方法(即“JavaScript”),那么这就是实现相同结果的方法。这是建立在 Ryan Cogswell 之前提到的之上的。
如果从另一个 CSS-in-JS 系统(例如 Material-UI 的内置 JSS)切换,有些人可能会更喜欢这个。此外,“样式对象”方法只需要您引入
props
一次,而不是在任何行上使用 props
变量。有选择是件好事。 😇
const AppBar = styled(MuiAppBar)((props) => ({
backgroundColor: red;
[props.theme.breakpoints.up("sm")]: {
backgroundColor: orange,
},
[props.theme.breakpoints.up("md")]: {
backgroundColor: yellow,
color: black,
},
[props.theme.breakpoints.up("lg")]: {
backgroundColor: green,
color: white,
},
}));
由于我们只需要使用 JavaScript 方法访问一次 props,并且我们只在此样式区域中使用主题,因此我们可以从传入的
theme
中解构 props
,从而减少一点代码。
const AppBar = styled(MuiAppBar)(({ theme }) => ({
backgroundColor: red;
[theme.breakpoints.up("sm")]: {
backgroundColor: orange,
},
[theme.breakpoints.up("md")]: {
backgroundColor: yellow,
color: black,
},
[theme.breakpoints.up("lg")]: {
backgroundColor: green,
color: white,
},
}));
注意:如果您使用 TypeScript 并已设置样式组件主题以匹配 Material-UI 主题,则类型安全在 CSS 或 JavaScript 方法中仍然按预期工作。
提供断点作为默认主题的一部分。
它们是常量,不会改变,因此您可以在组件或样式主题中使用它们:
import React from 'react';
import styled from 'styled-components';
import { makeStyles } from '@material-ui/core/styles';
const useStyles = makeStyles(theme => {
console.log('md', theme.breakpoints.up('md'));
return {};
});
const BP = {
MD: `@media (min-width:960px) `,
};
const Container = styled.div`
background-color: green;
${({ bp }) => bp} {
background-color: red;
}
`;
export default function StyledComponentsButton() {
useStyles();
return <Container bp={BP.MD}>Example</Container>;
}
语法可能看起来很奇怪,但尝试这段代码可以解释一切
const StyledDiv = styled.div`
${({theme}) => {
console.log(theme.breakpoints.up('lg'));
return "";
}}
`;
// you will see in your console
// @media (min-width:1280px)
一旦你明白
theme.breakpoints.up('lg')
与@media (min-width:1280px)
相同,一切就变得显而易见了。每次你输入 theme.breakpoints.up(key)
时,它都会被 @media...
字符串替换。
我完全同意答案https://stackoverflow.com/a/64047876/7262646
我从Mui系统获取官方文档这里,它是由里面的material-ui导入的。
我将在此处粘贴一些示例
const StatWrapper = styled('div')(
({ theme }) => `
background-color: ${theme.palette.background.paper};
box-shadow: ${theme.shadows[1]};
border-radius: ${theme.shape.borderRadius}px;
padding: ${theme.spacing(2)};
min-width: 300px;
`,
);
const StatHeader = styled('div')(
({ theme }) => `
color: ${theme.palette.text.secondary};
`,
);
const StyledTrend = styled(TrendingUpIcon)(
({ theme }) => `
color: ${theme.palette.success.dark};
font-size: 16px;
vertical-alignment: sub;
`,
);
const StatValue = styled('div')(
({ theme }) => `
color: ${theme.palette.text.primary};
font-size: 34px;
font-weight: ${theme.typography.fontWeightMedium};
`,
);
const StatDiff = styled('div')(
({ theme }) => `
color: ${theme.palette.success.dark};
display: inline;
font-weight: ${theme.typography.fontWeightMedium};
margin-left: ${theme.spacing(0.5)};
margin-right: ${theme.spacing(0.5)};
`,
);
const StatPrevious = styled('div')(
({ theme }) => `
color: ${theme.palette.text.secondary};
display: inline;
font-size: 12px;
`,
);
return (
<StatWrapper>
<StatHeader>Sessions</StatHeader>
<StatValue>98.3 K</StatValue>
<StyledTrend />
<StatDiff>18.77%</StatDiff>
<StatPrevious>vs last week</StatPrevious>
</StatWrapper>
);
const StyledDrawer = styled(Drawer)(
({ theme }) => `
.MuiDrawer-paper {
${theme.breakpoints.up('sm')} {
width: 370px;
}
${theme.breakpoints.down('sm')} {
width: 100vw;
}
}
`)