Gatsby: [gatsby-image] Using `fluid` images on a flexbox layout when the images should have a max width.

Created on 25 Mar 2019  路  10Comments  路  Source: gatsbyjs/gatsby

Summary

fluid images seem to have no width or height on a flexbox display.

Relevant information


I've tried using fixed images as well, but these images need to shrink when the width of the display is smaller.

A demonstration can be seen here:
https://deploy-preview-10--optimistic-goodall-a71eb1.netlify.com/photographer right under the description, there is a flexbox display of images where all the images are too small to be seen.

The code for where I use gatsby-image is here: https://github.com/SammyIsra/SammyPortfoliov2/blob/1d26c04a049eed718b866baa51870523837e9e68/src/pages/photographer.js#L117

Environment (if relevant)

  System:
    OS: Windows 10
    CPU: (4) x64 Intel(R) Core(TM) i5-6300U CPU @ 2.40GHz
  Binaries:
    Yarn: 1.13.0 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 6.4.1 - ~\AppData\Roaming\npm\npm.CMD
  Browsers:
    Edge: 42.17134.1.0
  npmPackages:
    gatsby: 2.2.6 => 2.2.6
    gatsby-image: ^2.0.34 => 2.0.34
    gatsby-plugin-react-helmet: ^3.0.8 => 3.0.8
    gatsby-plugin-remote-images: 1.0.1 => 1.0.1
    gatsby-plugin-sharp: 2.0.30 => 2.0.30
    gatsby-plugin-styled-components: ^3.0.6 => 3.0.6
    gatsby-plugin-typography: ^2.2.8 => 2.2.8
    gatsby-source-filesystem: 2.0.23 => 2.0.23
    gatsby-transformer-remark: ^2.3.1 => 2.3.1
    gatsby-transformer-sharp: ^2.1.17 => 2.1.17

Also: Mozilla Firefox v65

File contents (if changed)

gatsby-config.js:

const path = require("path");

module.exports = {
  siteMetadata: {
    title: "Sammy is a...",
    description:
      "鈽勶笍Sammy's website and portfolio!\nFrom Development to Photography",
    tags: ["portfolio", "software developer", "developer", "photographer"]
  },
  plugins: [
    "gatsby-plugin-react-helmet",
    "gatsby-plugin-styled-components",
    {
      resolve: "gatsby-plugin-typography",
      options: {
        pathToConfigModule: path.join(__dirname, "src", "typography.js")
      }
    },
    {
      resolve: "gatsby-source-filesystem",
      options: {
        name: "posts",
        path: `${__dirname}/src/posts`
      }
    },
    "gatsby-transformer-remark",
    {
      resolve: "gatsby-plugin-remote-images",
      options: {
        nodeType: "flickrImage",
        imagePath: "url_l" // Use the 'large' sized image for the pictures in the photostream
      }
    },
    "gatsby-transformer-sharp",
    "gatsby-plugin-sharp"
  ]
};

package.json:
```{
"name": "gatsby-starter-hello-world",
"private": true,
"description": "A simplified bare-bones starter for Gatsby",
"version": "0.1.0",
"license": "MIT",
"scripts": {
"build": "gatsby build",
"develop": "gatsby develop",
"format": "prettier --write src/*/.{js,jsx}",
"start": "npm run develop",
"serve": "gatsby serve",
"test": "echo "Write tests! -> https://gatsby.dev/unit-testing"",
"deploy-demo": "gatsby build&&surge ./public/ --domain sammyis-gdemo.surge.sh"
},
"dependencies": {
"babel-plugin-styled-components": "^1.10.0",
"gatsby": "2.2.6",
"gatsby-image": "^2.0.34",
"gatsby-plugin-react-helmet": "^3.0.8",
"gatsby-plugin-remote-images": "1.0.1",
"gatsby-plugin-sharp": "2.0.30",
"gatsby-plugin-styled-components": "^3.0.6",
"gatsby-plugin-typography": "^2.2.8",
"gatsby-source-filesystem": "2.0.23",
"gatsby-transformer-remark": "^2.3.1",
"gatsby-transformer-sharp": "^2.1.17",
"graphql": "^14.1.1",
"node-fetch": "^2.3.0",
"react": "^16.8.4",
"react-dom": "^16.8.4",
"react-helmet": "^5.2.0",
"react-masonry-component": "6.2.1",
"react-typography": "^0.16.19",
"styled-components": "^4.1.3",
"typography": "^0.16.19",
"typography-theme-fairy-gates": "^0.16.19"
},
"devDependencies": {
"prettier": "^1.16.4"
},
"repository": {
"type": "git",
"url": "https://github.com/gatsbyjs/gatsby-starter-hello-world"
},
"bugs": {
"url": "https://github.com/gatsbyjs/gatsby/issues"
}
}

`gatsby-node.js`: 

const { createFilePath } = require("gatsby-source-filesystem");
const path = require("path");
const fetch = require("node-fetch");

const urlAllPhotos =
"https://us-central1-photo-flick-d764c.cloudfunctions.net/getFlickPhotos?sortBy=date&limitTo=40";

/**

  • Fetch data from my personal Flickr endpoint to get the pictures
    */
    exports.sourceNodes = function({ actions, createContentDigest }) {
    const { createNode } = actions;

return new Promise((resolve, reject) => {
//All photos
fetch(urlAllPhotos)
.then(resp => resp.json())
.then(photos => {
photos.forEach(element => {
createNode(processFlickrImageList(element, createContentDigest));
});
resolve();
})
.catch(reject);
});

function processFlickrImageList(flickrItem, digest) {
// console.log("Flickr:", flickrItem);
return {
...flickrItem,
address: https://www.flickr.com/photos/${flickrItem.owner}/${ flickrItem.id }/,
children: [],
parent: null,
internal: {
type: "flickrImage",
content: JSON.stringify(flickrItem),
contentDigest: digest(flickrItem)
}
};
}
};

exports.onCreateNode = function({ node, getNode, actions }) {
const { createNodeField } = actions;
if (node.internal.type === "MarkdownRemark") {
const slug = createFilePath({ node, getNode, basePath: "pages" });
createNodeField({
node,
name: "slug",
value: /posts${slug}
});
}
};

exports.createPages = function({ graphql, actions }) {
return new Promise((resolve, reject) => {
const { createPage } = actions;

graphql(`
  {
    allMarkdownRemark {
      edges {
        node {
          fields {
            slug
          }
        }
      }
    }
  }
`)
  .then(result => {
    result.data.allMarkdownRemark.edges.forEach(({ node }) =>
      createPage({
        path: node.fields.slug,
        component: path.resolve("./src/templates/blog-post.js"),
        context: {
          slug: node.fields.slug
        }
      })
    );
    resolve();
  })
  .catch(error => {
    console.error("Error on createPages", error);
    reject(error);
  });

});
};
`` gatsby-browser.js: N/A <!-- Please use a code block or just leave it as is if wasn't changed --> gatsby-ssr.js`: N/A

awaiting author response question or discussion

Most helpful comment

The solution that worked for me was wrapping each anchor tag in a div which is assigned a width of 100%: Then, flexbox is applied to the div instead of the anchor tag:

import Img from 'gatsby-image'

const ImgGallery = ({ data }) => (
  <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
    <div style={{ width: '100%' }}>
        <a href='#'>
            <Img fluid={data.fluidImageOne.childImageSharp.fluid} />
        </a>
    </div>
    <div style={{ width: '100%' }}>
        <a href='#'>
            <Img fluid={data.fluidImageTwo.childImageSharp.fluid} />
        </a>
    </div>
    <div style={{ width: '100%' }}>
        <a href='#'>
            <Img fluid={data.fluidImageThree.childImageSharp.fluid} />
        </a>
    </div>
  </div>
)

All 10 comments

does it work when switching fluid={sharpPhoto.childImageSharp.fixed} into fluid={sharpPhoto.childImageSharp.fluid} we use something called flex embed to make sure we keep ratio in tact

image

padding-bottom is nan because you're using fixed instead of fluid.

That does help in that the images seen in the page inspector no longer have a width or height of 0px, and the padding-bottom is no longer NaN:
image

However, the images still do not show, visible here:
https://deploy-preview-10--optimistic-goodall-a71eb1.netlify.com/photographer (same link as before)

Any solutions to this? I'm having the same problem.

Well, for one you're wrapping the images in an anchor tag element, and making them inline-block. I can't recall specifics but just using a block instead of inline-block appears to fix the issue. Presumably because width/height isn't defined for the inline-block(anchor tag), so if it's width is 0px, then 100% of that for any elements within(the gatsby image), that's correct?, alternatively specify a width value for the anchor element and it'll also work.

If you don't want to use a fixed value since you're using flex in the parent element as display, set a child to something like flex: 1; or flex-grow: 1 etc.

The solution that worked for me was wrapping each anchor tag in a div which is assigned a width of 100%: Then, flexbox is applied to the div instead of the anchor tag:

import Img from 'gatsby-image'

const ImgGallery = ({ data }) => (
  <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
    <div style={{ width: '100%' }}>
        <a href='#'>
            <Img fluid={data.fluidImageOne.childImageSharp.fluid} />
        </a>
    </div>
    <div style={{ width: '100%' }}>
        <a href='#'>
            <Img fluid={data.fluidImageTwo.childImageSharp.fluid} />
        </a>
    </div>
    <div style={{ width: '100%' }}>
        <a href='#'>
            <Img fluid={data.fluidImageThree.childImageSharp.fluid} />
        </a>
    </div>
  </div>
)

I looked properly at your code @SammyIsra sadly what you want isn't really feasible as you want it. Fluid will always keep it's ratio so you probably want to move into a masonry view. Or go for fixed and keep it centered.

I think that makes sense. In any case, I switched the style of what I was trying to do, thank you!

using fixed worked for my case, but I'm not sure WHY exactly :P

In case this helps, check if your CSS has any unscoped instances of position: relative.

Something like this will easily break gatsby-image:

* {
 position: relative;
}

Just in case someone's looking for a way to restrict the image size to max its original size (Not sure if it's the best approach, but it worked to me).
In the query, you might want to add the original img size like this:

query {
      logoImg: file(relativePath: { eq: "logo.png" }) {
        childImageSharp {
          fluid(maxWidth: 300) {
            ...GatsbyImageSharpFluid
          }
          original {
            width
          }
        }
      }
    }

And then you can just use it in the element wrapping the image to set its width

Was this page helpful?
0 / 5 - 0 ratings

Related issues

totsteps picture totsteps  路  3Comments

kalinchernev picture kalinchernev  路  3Comments

benstr picture benstr  路  3Comments

jimfilippou picture jimfilippou  路  3Comments

dustinhorton picture dustinhorton  路  3Comments