Search code examples
cssreactjsgatsbyreact-bootstrap

Bootstrap Card ImgOverlay with gatsby-plugin-image not rezizing as expected


I have a card component id like to leverage the Bootstrap Card ImgOverlay for, but the image itself is coming gatsby-plugin-image as a GatsbyImage. Below is the component:

const BlogPostCard = (props: BlogPostCardProps) => {
    const imageData = getImage(props.imgData)
    return (
        <Card className={style.blogPostCard}>
            <Card.ImgOverlay>
                <Card.Body className={style.blogPostCardContent}>
                    <Card.Title as="h1">{props.title}</Card.Title>
                    <Card.Subtitle className={style.blogDate}>{props.date}</Card.Subtitle>
                    <Card.Text>{props.excerpt}</Card.Text>
                    <Card.Link as={Link} to={props.slug}>Read post.</Card.Link>
                </Card.Body>
            </Card.ImgOverlay>
            <Card.Img className={style.blogPostCardImg} as={GatsbyImage} image={imageData} alt="asdf"/>
        </Card>
    );
};

where the props.imgData is coming from the following graphql fragment:

node {
      frontmatter {
          ...
          image {
              childImageSharp {
                  gatsbyImageData(
                      placeholder: BLURRED
                      formats: [AUTO, WEBP]
                  )
               }
          ...
       }
}

Here the scss is as follows:

.blogPostCardContainer {
  .blogPostCard {
    height: 300px;
    .blogPostCardContent {
      h1 {
        color: $primary-font-color;
        text-decoration: underline;
      }

      p {
        color: $primary-font-color;
      }

      .blogDate {
        color: $secondary-font-color;
      }
    }

    .blogPostCardImg {
      object-fit: cover;
      picture {
        opacity: 0.3;
      }
    }
  }
  padding-bottom: 2vh;
}

Unfortunately, this is just rendering a card 300px high with the image at full width and no cropping to cover. What id really like is something equivalent to the example given in the object-fit docs: https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit

The card should be dynamic with the props.excerpt length (currently just 300px), and the image should scale and crop to fill the background. Where am I going wrong in my CSS?


Solution

  • This was eventually solved by adding some position values to various container elements to allow one to overflow the parent and the other to govern the parent's height:

    js

            <Card className={style.blogPostCard}>
                <Card.Img className={style.blogPostCardImg} as={GatsbyImage} image={imageData}/>
                <Card.ImgOverlay className={style.blogPostCardContent}>
                    <Card.Body>
                        <Card.Title as="h1">{props.title}</Card.Title>
                        <Card.Subtitle>{props.date}</Card.Subtitle>
                        <Card.Text>{props.excerpt}</Card.Text>
                    </Card.Body>
                </Card.ImgOverlay>
            </Card>
    

    css:

    .blogPostCardContainer {
      .blogPostCard {
        position: relative;
        overflow-y: hidden;
    
        .blogPostCardImg {
          position: absolute;
          object-fit: cover;
          height: 100%;
        }
    
        .blogPostCardContent {
          position: relative;
        }
    
      }
    }