【问题标题】:Using grid-template-areas with dynamic content in Gatsby在 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} />}
    />
)
````


【问题讨论】:

    标签: css reactjs graphql css-grid gatsby


    【解决方案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} />}
        />
    )
    
    

    谢谢!!

    【讨论】:

      猜你喜欢
      • 2018-04-25
      • 1970-01-01
      • 2021-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多