在 Gatsby 中使用带有动态内容的网格模板区域
Posted
技术标签:
【中文标题】在 Gatsby 中使用带有动态内容的网格模板区域【英文标题】:Using grid-template-areas with dynamic content in Gatsby 【发布时间】:2019-07-08 23:23:36 【问题描述】:我正在尝试使用 CSS 网格在每行上使用交替列进行布局。第一行左边是图片,右边是文字,第二行左边是文字,右边是图片,依此类推。
我尝试使用 nth-of-type,但是由于每个帖子的父节点(Box)重复,我认为这将非常困难。
问题是我无法单独联系所有孩子,因为内容来自 GraphQL,我只有一个节点要处理。
有人有建议来完成这个吗?
谢谢!
import React, Component from "react";
import Link, graphql, StaticQuery from 'gatsby'
import styled from 'styled-components'
import Img from 'gatsby-image'
const Wrapper = styled.div`
margin: 0 auto;
margin-bottom: 6rem;
overflow: visible;
`
const Title = styled.h5`
margin-bottom: 2rem;
text-align: center;
`
const Inner = styled.div`
display: grid;
grid-template-columns: 1fr;
grid-row-gap: 3rem;
@media (max-width: 1024px)
grid-template-columns: 1fr;
grid-row-gap: 80px;
padding: 1rem;
`
const Box = styled.div`
display: grid;
grid-template-columns: 1fr 1fr;
grid-column-gap: 6rem;
align-items: center;
grid-template-rows: auto;
grid-template-areas: "left right";
@media (max-width: 1024px)
grid-template-columns: 1fr;
grid-row-gap: 80px;
padding: 1rem;
`
const Content = styled.div`
text-decoration: none;
&:nth-of-type(even)
grid-area: right;
&:nth-of-type(odd)
grid-area: left;
`
const StyledLink = styled(Link)`
text-decoration: none;
color: inherit;
:nth-of-type(even)
grid-area: left;
:nth-of-type(odd)
grid-area: right;
`
const StyledImg = styled(Img)`
border-radius: 7px;
margin-bottom: 1rem;
opacity: 1;
-webkit-transition: .5s ease-in-out;
transition: .5s ease-in-out;
:hover
opacity: .7;
`
const PostTitle = styled.h6`
margin-bottom: 0.5rem;
`
const Date = styled.p`
font-size: 0.8rem;
display: block;
color: #777;
`
export class Gallery extends Component
render()
return (
<Wrapper>
<Title>
Works
</Title>
<Inner>
this.props.data.allMarkdownRemark.edges.map(( node ) => (
<Box key=node.id className='box'>
<StyledLink to=node.fields.slug>
<StyledImg fluid=node.frontmatter.image.childImageSharp.fluid />
</StyledLink>
<Content>
<StyledLink to=node.fields.slug>
<PostTitle>
node.frontmatter.title" "
</PostTitle>
</StyledLink>
<Date>
node.frontmatter.date
</Date>
<p>node.excerpt</p>
</Content>
</Box>
))
</Inner>
</Wrapper>
)
export default props => (
<StaticQuery
query=graphql`
query
allMarkdownRemark(sort: fields: [frontmatter___date], order: DESC )
totalCount
edges
node
id
frontmatter
title
date(formatString: "DD MMMM, YYYY")
image
childImageSharp
fluid(maxWidth: 800)
...GatsbyImageSharpFluid_noBase64
fields
slug
excerpt
`
render=data => <Gallery data=data ...props />
/>
)
````
【问题讨论】:
【参考方案1】:使用样式组件,您可以将 nth-of-type
提升到 Box
以定位其子项:
const Inner = styled.div`
display: grid;
grid-template-columns: 1fr;
grid-row-gap: 1rem;
`;
// declare Image & Content first, so we can use it in Box
const Image = styled.img`
display: block;
`;
const Content = styled.div`
display: block;
`;
const Box = styled.div`
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: auto;
grid-template-areas: "left right";
& > $Image,
&:nth-of-type(even) > $Content
grid-area: left;
& > $Content,
&:nth-of-type(even) > $Image
grid-area: right;
`;
这是一个最小的codesandbox
或者,您可以考虑只使用一个网格:
const Inner = styled.div`
display: grid;
grid-template-columns: repeat(2, 1fr);
`;
const Image = styled.img`
grid-column: 1;
&:nth-of-type(even)
grid-column: 2;
`;
const Content = styled.div`
grid-column: 2;
&:nth-of-type(even)
grid-column: 1;
`;
// use fragment (<>) so box is not rendered as a div
const Box = ( content ) => (
<>
<Image src="https://via.placeholder.com/100x100" />
<Content>`item $content`</Content>
</>
)
另一个codesanbox
【讨论】:
不幸的是,第一个解决方案不起作用,因为每个帖子都会生成一个新框,所以每次都保持不变。所以我认为代码必须来自上面(内部)。我将对我的代码进行一些更改以适应您的第二个建议(而且我对片段还不是很熟悉),但是您给了我一些可以使用的好主意。非常感谢! 嘿@Fadanabela,很高兴它有帮助。你看到代码框了吗? 是的,我做到了,它帮助我让它发挥作用。我刚刚发布了答案。感谢您的帮助! @Fadanabela 不客气,我不明白您为什么需要从内部组合中定位,但您设置组件的方式可能有所不同。希望你和盖茨比玩得开心! 是因为每发一个帖子,都会生成一个新的Box div,所以如果我有6个帖子,我就会有6个Box div,并且每一个网格代码都是从零开始的,所以模板区域打印好像它始终是第一行。内部 div 保持不变并且可以“计算”它的子级。我希望我能解释清楚。这是我第一次接触 Gatsby 和 GraphQL。谢谢! :)【参考方案2】:知道了!
这对我有用:
import React, Component from "react";
import Link, graphql, StaticQuery from 'gatsby'
import styled from 'styled-components'
import Img from 'gatsby-image'
const Wrapper = styled.div`
margin: 0 auto;
margin-bottom: 6rem;
overflow: visible;
`
const Title = styled.h5`
margin-bottom: 2rem;
text-align: center;
`
const Inner = styled.div`
display: grid;
grid-template-columns: 1fr;
grid-row-gap: 3rem;
@media (max-width: 1048px)
grid-template-columns: 1fr 1fr;
@media (max-width: 800px)
grid-template-columns: 1fr;
`
const Box = styled.div`
display: grid;
grid-template-columns: 1fr 1fr;
column-gap: 3rem;
align-items: center;
$Inner &:nth-child(even)
grid-template-areas:
"right left";
$Inner &:nth-child(odd)
grid-template-areas:
"left right";
`
const Thumb = styled(Link)`
text-decoration: none;
color: inherit;
grid-area: left;
`
const Content = styled.div`
text-decoration: none;
grid-area: right;
`
const StyledLink = styled(Link)`
text-decoration: none;
color: inherit;
`
const StyledImg = styled(Img)`
border-radius: 7px;
margin-bottom: 1rem;
opacity: 1;
-webkit-transition: .5s ease-in-out;
transition: .5s ease-in-out;
:hover
opacity: .7;
`
const PostTitle = styled.h6`
margin-bottom: 0.5rem;
`
const Date = styled.p`
font-size: 0.8rem;
display: block;
color: #777;
`
export class Gallery extends Component
render()
return (
<Wrapper>
<Title>
Works
</Title>
<Inner>
this.props.data.allMarkdownRemark.edges.map(( node ) => (
<Box key=node.id className='box' >
<Thumb to=node.fields.slug>
<StyledImg fluid=node.frontmatter.image.childImageSharp.fluid />
</Thumb>
<Content>
<StyledLink to=node.fields.slug>
<PostTitle>
node.frontmatter.title" "
</PostTitle>
</StyledLink>
<Date>
node.frontmatter.date
</Date>
<p>node.excerpt</p>
</Content>
</Box>
))
</Inner>
</Wrapper>
)
export default props => (
<StaticQuery
query=graphql`
query
allMarkdownRemark(sort: fields: [frontmatter___date], order: DESC )
totalCount
edges
node
id
frontmatter
title
date(formatString: "DD MMMM, YYYY")
image
childImageSharp
fluid(maxWidth: 800)
...GatsbyImageSharpFluid
base64
tracedSVG
aspectRatio
fields
slug
excerpt
`
render=data => <Gallery data=data ...props />
/>
)
谢谢!!
【讨论】:
以上是关于在 Gatsby 中使用带有动态内容的网格模板区域的主要内容,如果未能解决你的问题,请参考以下文章
Gatsby 的 GraphQL 查询 - 具有灵活内容模型的内容设置
正确地将第二个动态模板添加到 Gatsby/NetlifyCMS - 我哪里出错了?