Gatsby: Improve gatsby-image behavior when used with styled-components

Created on 3 Sep 2018  路  3Comments  路  Source: gatsbyjs/gatsby

In order to facilitate using gatsby-image in conjunction with styled-components, styles passed to Img should be applied to gatsby-image's outer wrapper div rather than the inner one.

Currently, something like

import styled from 'styled-components'
import Img from 'gatsby-image'

export const Image = styled(Img)`
  grid-row: 1 / -1;
  border-radius: 50%;
`

applies the specified styles to the inner wrapper div, where the HTML produced by gatsby-image is as follows:

<div class="gatsby-image-outer-wrapper">
  <div class="gatsby-image-wrapper">
    <div></div>
    <!-- Placeholder (hidden after main image loads) -->
    <img style="...object-fit: cover; object-position: center center;">
    <!-- Main image -->
    <img style="...object-fit: cover; object-position: center center;">
  </div>
</div>

Since there is no parent selector in CSS, this makes it very difficult to apply styles to the outer wrapper div, as I would like to do in order to specify its position in a grid.

A related problem came up here.

If on the other hand, the styles were passed to the outer div, it would be very simple, to also style the inner div if necessary:

import styled from 'styled-components'
import Img from 'gatsby-image'

export const Image = styled(Img)`
  grid-row: 1 / -1;
  border-radius: 50%;
  > div {
    background: rebeccapurple;
  }
`
question or discussion

All 3 comments

A temporary fix for this issue until possible removal of the outer wrapper div by #7826 (see also #7797) is to insert

  .gatsby-image-outer-wrapper {
    display: contents;
  }

When using styled-components, this can simply be dropped into an injectGlobal (soon to be replaced by createGlobalStyle in v4) and then removed again should #7826 be merged.

This should be possible due to #7797 being merged. We no longer use nested wrappers (just the one wrapping div!), and styles applies e.g. something like

import React from 'react'
import styled from 'styled-components'
import Image from 'gatsby-image'

const StyledImage = styled(GatsbyImage)`
  grid-row: 1 / -1;
  border-radius: 50%;
`

should now work like you'd expect! Thanks for the issue, and please re-open/comment if you find something to the contrary!

new issue with less modules and gatsby-image-wrapper. while using grid would not fill the whole space. had to use to get the correct behavior ; )

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jp887 picture jp887  路  98Comments

jonathan-chin picture jonathan-chin  路  69Comments

Jivings picture Jivings  路  112Comments

OleksandrSachuk picture OleksandrSachuk  路  75Comments

TuckerWhitehouse picture TuckerWhitehouse  路  69Comments