PCの場合はこんな感じ
スマホは
今回はmaterial-uiのv5を使用
以前と比べて表記などが多少変わっている
インストールしているパッケージは以下になる
記事一覧のソースコードは
import * as React from "react"
import { Link } from "gatsby"
import { GatsbyImage, getImage } from "gatsby-plugin-image"
import { styled } from "@mui/material/styles";
import { useTheme, useMediaQuery } from '@mui/material';
const BlogContainer = styled("article")(({ theme }) => ({
...theme.mixins.blogContainer,
}));
const BlogImage = styled("div")(({ theme }) => ({
...theme.mixins.blogImage,
}));
const BlogTitle = styled("div")(({ theme }) => ({
...theme.mixins.blogTitle,
}));
const Blogs = ({ posts }) => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down("xs"));
// theme.breakpoints.up(xs)
// theme.breakpoints.only(xs)
// theme.breakpoints.between(xs, sm)
return (
<ol style={{ listStyle: `none` }}>
{posts.map(post => {
const title = post.frontmatter.title || post.fields.slug
return (
<BlogContainer key={post.fields.slug}>
{
post.frontmatter.hero ?
<BlogImage>
<GatsbyImage style={{ objectFit: "fill" }} image={getImage(post.frontmatter.hero?.childImageSharp.gatsbyImageData)} alt={post.frontmatter.title} />
</BlogImage>
: ""
}
<BlogTitle>
<Link to={`${post.fields.slug}`} style={{ textDecoration: `none`, }}>
{title}
</Link>
</BlogTitle>
{
!post.frontmatter.hero || isMobile ? <small>{post.frontmatter.date}</small> : ''
}
<section>
<p
style={{ overflow: "hidden" }}
dangerouslySetInnerHTML={{
__html: post.frontmatter.description || post.excerpt,
}}
itemProp="description"
/>
</section>
</BlogContainer>
)
})}
</ol>
)
}
export default Blogs
src/component/mui-theme-provider.jsというファイルを作る
import { ThemeProvider, createTheme } from "@mui/material/styles"
import { CssBaseline } from "@mui/material"
import React from "react"
const MuiThemeProvider = ({ children }) => {
const theme = createTheme({
palette: {
mode: "light",
// primary: {
// main: '#fff',
// },
},
mixins: {
blogContainer: {
width: "100%",
minHeight: "250px",
marginBottom: "24px",
"@media (max-width:375px)": {
minHeight: "150px",
},
"@media (min-width: 376px) and (max-width:768px)": {
},
"@media (min-width: 769px)" : {
},
},
blogImage: {
float: "left",
maxWidth: "250px",
width: "30%",
margin: "24px",
marginLeft: 0,
borderRadius: 8,
"@media (max-width:375px)": {
float: "none",
width: "200px",
minHeight: "100px",
maxHeight: "150px",
marginLeft: "auto",
marginRight: "auto",
overflow: "hidden",
},
"@media (min-width: 376px) and (max-width:768px)": {
fontSize: "1.2em",
},
"@media (min-width: 769px)" : {
fontSize: "1.2em",
},
},
blogTitle: {
fontWeight: "bold",
"@media (max-width:375px)": {
fontSize: "1.0em",
marginBottom: "8px",
},
"@media (min-width: 376px) and (max-width:768px)": {
fontSize: "1.2em",
marginBottom: "16px",
},
"@media (min-width: 769px)" : {
fontSize: "1.5em",
marginBottom: "24px",
},
},
},
// レスポンシブのブレイクポイント
'breakpoints': {
'keys': [
'xs',
'sm',
'md',
'lg',
'xl',
],
'values': {
'xs': 376, // スマホ用
'sm': 768, // タブレット用
'md': 992, // PC用
'lg': 1400,
'xl': 1800,
},
},
})
return (
<ThemeProvider theme={theme}>
<CssBaseline />
{children}
</ThemeProvider>
)
}
export default MuiThemeProvider
createThemeのmixinsの中にサイズに合わせたcssの記述をしている。これを
import { styled } from "@mui/material/styles";
const BlogContainer = styled("article")(({ theme }) => ({
...theme.mixins.blogContainer,
}));
のように用いることができる
GatsbyのプロジェクトでThemeProviderを使うには
import React from "react"
import MuiThemeProvider from "./src/components/mui-theme-provider"
export const wrapRootElement = ({ element }) => {
return <MuiThemeProvider>{element}</MuiThemeProvider>
}
をgatsby-browser.jsに追加する必要がある。
このままgit pushしてhi1t0.comで確かめたところ、スタイルが反映されていなかった
調べてみたところgatsby-theme-material-ui
というプラグインがあったのでインストール
gatsby-config.jsに追記
module.exports = {
plugins: [
gatsby-theme-material-ui
],};
どうやらmixinsが効いてない
useMediaQueryの方は使えている
cssを書く場所を変更する
import * as React from "react"
import { Link } from "gatsby"
import { GatsbyImage, getImage } from "gatsby-plugin-image"
import { styled } from "@mui/material/styles";
import { useTheme, useMediaQuery } from '@mui/material';
const BlogContainer = styled("article")({
// ...theme.mixins.blogContainer,
width: "100%",
minHeight: "250px",
marginBottom: "24px",
"@media (max-width:375px)": {
minHeight: "150px",
},
"@media (min-width: 376px) and (max-width:768px)": {
},
"@media (min-width: 769px)" : {
},
});
const BlogImage = styled("div")({
float: "left",
maxWidth: "250px",
width: "30%",
margin: "24px",
marginLeft: 0,
borderRadius: 8,
"@media (max-width:375px)": {
float: "none",
minWidth: "320px",
minHeight: "100px",
maxHeight: "160px",
marginLeft: "auto",
marginRight: "auto",
overflow: "hidden",
},
"@media (min-width: 376px) and (max-width:768px)": {
},
"@media (min-width: 769px)" : {
},
});
const BlogTitle = styled("div")({
fontWeight: "bold",
"@media (max-width:375px)": {
fontSize: "1.0em",
marginBottom: "8px",
},
"@media (min-width: 376px) and (max-width:768px)": {
fontSize: "1.2em",
marginBottom: "16px",
},
"@media (min-width: 769px)" : {
fontSize: "1.5em",
marginBottom: "24px",
},
});
const Blogs = ({ posts }) => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down("xs"));
return (
<ol style={{ listStyle: `none` }}>
{posts.map(post => {
const title = post.frontmatter.title || post.fields.slug
return (
<BlogContainer key={post.fields.slug}>
{
post.frontmatter.hero ?
<BlogImage>
<GatsbyImage style={{borderRadius: 8}} image={getImage(post.frontmatter.hero?.childImageSharp.gatsbyImageData)} alt={post.frontmatter.title} />
</BlogImage>
: ""
}
<BlogTitle>
<Link to={`${post.fields.slug}`} style={{ textDecoration: `none`, }}>
{title}
</Link>
</BlogTitle>
{
!post.frontmatter.hero || isMobile ? <small>{post.frontmatter.date}</small> : ''
}
<section>
<p
style={{ overflow: "hidden" }}
dangerouslySetInnerHTML={{
__html: post.frontmatter.description || post.excerpt,
}}
itemProp="description"
/>
</section>
</BlogContainer>
)
})}
</ol>
)
}
export default Blogs
無事スタイルが反映された
参考: