Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gatsby-plugin-image class styles break user created styles & CSS frameworks like Tailwind CSS #34457

Closed
2 tasks done
sgarcia-dev opened this issue Jan 12, 2022 · 10 comments
Closed
2 tasks done
Labels
topic: media Related to gatsby-plugin-image, or general image/media processing topics type: bug An issue or pull request relating to a bug in Gatsby

Comments

@sgarcia-dev
Copy link

sgarcia-dev commented Jan 12, 2022

Preliminary Checks

Description

The current implementation of gatsby-plugin-image injects it's CSS classes in a <style> element that is placed last in the DOM tree, after user created styles loaded via gatsby-browser.js. Making it impossible to override any of its default styles with a normal class unless using a higher specificity selector (ID/inline). Notably, this breaks class driven CSS frameworks like TailwindCSS unless prefixing utility classes with !important.

For example, assuming the following simple code sample: (css loaded via gatsby-browser.js)

<StaticImage
  alt="Clifford, a reddish-brown pitbull, posing on a couch and looking stoically at the camera"
  className="absolute l-0 t-0 test-class-dont-override "
  src="../images/dog.jpeg"
/>
@tailwind base;
@tailwind components;
@tailwind utilities;

.test-class-dont-override {
  display: 'block';
}

When building the project, the output image container has the styles of both TailwindCSS's absolute class, and a custom user created class overriden by gatsby-plugin-image's styles because they are placed lower in the DOM.
Screenshot_2022 01 12_03 15 AM

Evidence of the problem is made clear when browsing the output rendered HTML by Gatsby's build in the Chrome Inspector:

<style>
.absolute {
    position: absolute
}

.test-class-dont-override {
    display: "block"
}
</style>
<meta name="generator" content="Gatsby 4.4.0"/>
<style>
.gatsby-image-wrapper {
    position: relative;
    overflow: hidden
}

.gatsby-image-wrapper picture.object-fit-polyfill {
    position: static!important
}

.gatsby-image-wrapper img {
    bottom: 0;
    height: 100%;
    left: 0;
    margin: 0;
    max-width: none;
    padding: 0;
    position: absolute;
    right: 0;
    top: 0;
    width: 100%;
    object-fit: cover
}

.gatsby-image-wrapper [data-main-image] {
    opacity: 0;
    transform: translateZ(0);
    transition: opacity .25s linear;
    will-change: opacity
}

.gatsby-image-wrapper-constrained {
    display: inline-block;
    vertical-align: top
}
</style>
<noscript>
<style>
    .gatsby-image-wrapper noscript [data-main-image] {
        opacity: 1!important
    }

    .gatsby-image-wrapper [data-placeholder-image] {
        opacity: 0!important
    }
</style>
</noscript>

A solution here would be ensuring that the gatsby-plugin-image CSS is always loaded FIRST in the DOM tree, allowing user created classes of equal specificity to win against it.

It appears other people have faced this issue as well. #33960 stumbled upon this issue, and there is a Stack Overflow thread of people facing the issue and looking for work arounds like !important to all tailwind classes or using inline styles to beat the styles by gatsby-plugin-image:
https://stackoverflow.com/questions/66763196/gatsby-image-plugin-staticimage-cannot-override-the-default-wrapper-style-gats

Reproduction Link

https://github.com/sgarcia-dev/my-first-gatsby-siteww

Steps to Reproduce

Using linked project:

  1. npm install
  2. npm run develop
  3. add any user created or tailwind classes that override properties declared by gatsby-plugin-image to src/pages/index.js:12
  4. build the project
  5. note user created styles are overriden
    ...

Expected Result

User created styles or CSS framework classes should not be overriden by gatsby-image-plugin by default

Actual Result

User created styles or CSS framework classes are being overriden by gatsby-image-plugin by default, forcing users to find weird workarounds for this issue.

Environment

System:
    OS: macOS 11.6
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 14.15.5 - ~/.nvm/versions/node/v14.15.5/bin/node
    Yarn: 1.22.10 - ~/.nvm/versions/node/v14.15.5/bin/yarn
    npm: 6.14.11 - ~/.nvm/versions/node/v14.15.5/bin/npm
  Languages:
    Python: 2.7.16 - /usr/bin/python
  Browsers:
    Chrome: 96.0.4664.55
    Safari: 15.0
  npmGlobalPackages:
    gatsby-cli: 4.4.0

Config Flags

No response

@sgarcia-dev sgarcia-dev added the type: bug An issue or pull request relating to a bug in Gatsby label Jan 12, 2022
@gatsbot gatsbot bot added the status: triage needed Issue or pull request that need to be triaged and assigned to a reviewer label Jan 12, 2022
@sandren
Copy link

sandren commented Jan 18, 2022

I'm experiencing this issue as well. I just wanted to add that the behavior of the issue is different for development and production. Successful workarounds for gatsby dev still break in gatsby build.

@LekoArts LekoArts added topic: media Related to gatsby-plugin-image, or general image/media processing topics and removed status: triage needed Issue or pull request that need to be triaged and assigned to a reviewer labels Jan 31, 2022
@LekoArts
Copy link
Contributor

Hi!

This is not something we'll fix as the styles for the image component are there for a reason (best performance, best lighthouse scores) and thus we don't want people to easily overwrite them. You should create a wrapper to do your layouting or directly use the gatsbyImageData API to serve the correct images.

@docforcedev
Copy link

Hi!

This is not something we'll fix as the styles for the image component are there for a reason (best performance, best lighthouse scores) and thus we don't want people to easily overwrite them. You should create a wrapper to do your layouting or directly use the gatsbyImageData API to serve the correct images.

I don't understand what you're saying. Can you help me understand?

<StaticImage
      src="../../assets/images/myimage.png"
      as="div"
      className="hidden md:inline-block md:col-span-2 lg:col-span-6"
      imgClassName="w-full h-auto"
      objectFit="contain"
    />

This won't work since the wrapper always has display: inline-block and will always win the battle.

<div data-gatsby-image-wrapper="" class="gatsby-image-wrapper gatsby-image-wrapper-constrained hidden md:inline-block md:col-span-2 lg:col-span-6">

In this case hidden and gatsby-image-wrapper-constrained try to battle it out, but gatsby-image-wrapper-constrained wins in the end.

How would you suggest fixing this? It isn't clear to me. Also it's confusing because it works on local dev instance but fails on prod builds. The behavior seems strange to me.

@docforcedev
Copy link

I fixed by adding a wrapper class with virtually the same properties which hid the gatsby image.

@FelDev
Copy link

FelDev commented Mar 7, 2022

Hi!

This is not something we'll fix as the styles for the image component are there for a reason (best performance, best lighthouse scores) and thus we don't want people to easily overwrite them. You should create a wrapper to do your layouting or directly use the gatsbyImageData API to serve the correct images.

I understand the motivation to make these styles hard to overwrite, but the ideal behavior is definitely to have the same results while running gatsby develop and gatsby build.

@IvanVishnevskiy
Copy link

I personally have an issue where gatsby images basically live their own life in prod builds but work absolutely fine in dev. Switching to img tag helps, but it's not optimal...

@samuel99
Copy link

This is such an annoying "feature". Everything looks good in dev, then you merge the PR and CI builds it to test environment, bam, everything looks like crap. How can the display property affect the Lighthouse score? There should at least be a way to opt out of this behaviour without having to use !important.

@babgyy
Copy link

babgyy commented Jan 4, 2023

Bump, to have such differences between dev & prod environments is very annoying and dangerous

@abouroubi
Copy link

Hi!

This is not something we'll fix as the styles for the image component are there for a reason (best performance, best lighthouse scores) and thus we don't want people to easily overwrite them. You should create a wrapper to do your layouting or directly use the gatsbyImageData API to serve the correct images.

This "We know better than you" mentality is what drove me of create-react-app, but if it's the same in the gatsby community, we have no other choice than to chose another framework.

@AlastairTaft
Copy link

AlastairTaft commented Feb 15, 2023

This is quite frustrating. There should be exactly the same result between dev and build. Issues are one thing but an attitude of not willing to fix really helps drive me, and I'm sure others, away from Gatsby. Please, hopefully reconsider.

mattrigg9 added a commit to mattrigg9/portfolio that referenced this issue Nov 30, 2023
Some tailwind classes must be marked with important to override
gatsby-image-wrapper

Issue: gatsbyjs/gatsby#34457
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: media Related to gatsby-plugin-image, or general image/media processing topics type: bug An issue or pull request relating to a bug in Gatsby
Projects
None yet
Development

No branches or pull requests

10 participants