mercredi 12 janvier 2022

CSS dynamic grid pattern

I'm currently working on the following grid using React, SCSS and the styled-components library:

enter image description here

I will eventually be fetching articles from a database so each card has to be dynamically generated. I'm struggling to make the long white cards (labeled (5) and (10) in the screenshot) dynamically sized.

My main problem is the 5th card needs to have a grid-row: 1 / span 2, but the 10th card needs a grid-row: 3 / span 2 (and the 15th will need grid-row: 5 / span 2 and so on , etc.), but I cannot hard-code it like that.

How can I automatically increase the grid-row-start for every 5th card?

Here is my React component:

    ...

    return (
                <Grid>
                    <Card>
                        <FlexBox>
                            <div>
                                <Image src="profilePicture.jpg" alt="Image"/>
                            </div>
                            <div>
                                <Name>Jonathan Walters</Name>
                                <Info>Member</Info>
                            </div>
                        </FlexBox>
                        <Title> (1) Lorem ipsum dolor sit amet, consectetur adipiscing elit.</Title>
                        <Content>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus ...</Content>
                    </Card>
                    
                    <Card> ... </Card>
                    <Card> ... </Card>
                    <Card> ... </Card>
                    <Card> ... </Card>
                    <Card> ... </Card>
                    <Card> ... </Card>
                    <Card> ... </Card>
                    <Card> ... </Card>
                    <Card> ... </Card>
                </Grid>
        )
    }

(I will eventually be iterating on an array with the map method and return one card component for each element in the array).

Here is my styled.jsx file :

    const colors = {
        grey: 'rgb(72, 85, 106)',
        purple: 'rgb(117, 65, 200)',
        coal: 'rgb(25, 33, 46)',
    }

    export const Grid = styled.div`
        display: grid;
        gap: 1.5rem;
        grid-template-columns: repeat(4, 1fr);
    `

    export const Card = styled.div`
        &:nth-child(5n) {
            grid-column-start: 4;
            grid-row: 1 / span 2;
        }
        &:nth-child(5n+1) {
            background-color: ${colors.purple};
            color: white;
            grid-column: span 2;
        }
        &:nth-child(5n+2) {
            background-color: ${colors.grey};
            color: white;
        }
        &:nth-child(5n+3) {
            background-color: white;
            color: black;
        }
        &:nth-child(5n+4) {
            background-color: ${colors.coal};
            color: white;
            grid-column: span 2;
        }
        &:nth-child(5n+5) {
            background-color: white;
            color: black;
        }
        &:nth-child(10n) {
            grid-column-start: 4;
            grid-row: 3 / span 2;
        }
    `

    export const FlexBox = styled.div`
        display: flex;
        gap: 1rem;
        `

    export const Image = styled.img`
        border-radius: 50%;
        width: 1.75rem;
    `

    export const Name = styled.h2`
        font-size: 1rem;
    `

    export const Info = styled.p`
        font-size: 0.8rem;
    `

    export const Title = styled.p`
        font-size: 1.2rem;
    `

    export const Content = styled.p`
        font-size: 0.8rem;
    `

Aucun commentaire:

Enregistrer un commentaire