Использование grid-template-area с динамическим контентом в Gatsby - PullRequest
0 голосов
/ 14 февраля 2019

Я пытаюсь использовать 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} />}
    />
)
````


Ответы [ 2 ]

0 голосов
/ 15 февраля 2019

Понял!

Вот что у меня сработало:

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} />}
    />
)

Спасибо !!

0 голосов
/ 15 февраля 2019

С помощью style-компонентов вы можете поднять 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;
  }
`;

Вот минимальное коды и поле


В качестве альтернативы, вы можете рассмотреть возможность использования только одной сетки:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...