我正在尝试使用CSS网格进行布局,每行上都有交替的列。第一行的图像在左侧,文本在右侧,第二行的文本在左侧,图像在右侧,依此类推。
我尝试使用nth-of-type,但是随着父节点(框)在每个帖子中重复出现,我认为这将非常困难。
问题是我无法单独接触所有孩子,因为内容来自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} />}
/>
)
````
答案 0 :(得分:0)
使用样式组件,您可以将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
答案 1 :(得分:0)
知道了!
这对我有用:
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} />}
/>
)
谢谢!