问题描述
我想要达到的目标
我正在使用 gatsby 并想设计一个图片库。单击其中一张图像将打开一个模态,它:(1) 以最大可能的尺寸显示图像,以便它仍然适合屏幕和 (2 ) 在屏幕中居中。
我的代码
/* imagemodal.js */
import React from 'react'
import * as ImagemodalStyles from './imagemodal.module.css'
import { Modal } from 'react-bootstrap'
import Img from 'gatsby-image'
import { useStaticQuery,graphql } from 'gatsby'
export default function Imagemodal() {
const data = useStaticQuery(graphql`
query {
file(relativePath: { eq: "images/mytestimage.jpg" }) {
childImageSharp {
fluid(maxWidth: 1200) {
...GatsbyImageSharpFluid
}
}
}
}
`)
return (
<div>
<Modal
show={true}
centered
className={ImagemodalStyles.imageModal}
dialogClassName={ImagemodalStyles.imageModalDialog}
onHide={(e) => console.log(e)}
>
<Modal.Header closeButton />
<Modal.Body className={ImagemodalStyles.imageModalBody}>
<h1>TestInhalt</h1>
<Img fluid={data.file.childImageSharp.fluid} />
</Modal.Body>
</Modal>
</div>
)
}
/* imagemodal.module.scss */
.imageModalDialog {
display: inline-block;
width: auto;
}
.imageModal {
text-align: center;
}
.imageModalBody img {
max-height: calc(100vh - 225px);
}
问题
图像未按屏幕尺寸缩放。图像要么太大 - 所以它流过 vieport - 要么太小。其次,模态大小没有正确响应图像大小和/或未居中。
我尝试了什么
- 我对 CSS 使用了这个建议:How to limit the height of the modal?
- 我还尝试了许多其他 CSS 参数组合。但我找不到可行的解决方案。
- 我尝试使用样式标签直接格式化 gatsby-image。
- 我也尝试过 react-modal,但遇到了类似的问题。
有没有人有一个很好的解决方案来在响应模式中以全屏尺寸显示 gatsby 图像?对我来说,可以使用 bootstrap-modal 或 react-modal - 或任何其他合适的解决方案。
编辑
最后我找到了一个解决方法。我使用 react-image-lightBox 并将 gatsby-image 中的 Image-Source 作为灯箱的输入。我的组件通过 props.imageData 从 props 中的 graphQL 查询获取数据。 这对我来说非常有效:
import LightBox from 'react-image-lightBox';
...
export default function Imagegallery(props) {
...
const allImages = props.imageData.edges
const [indexImagetoShow,setIndexImagetoShow] = useState()
...
return(
<LightBox
mainSrc={allImages[indexImagetoShow].node.childrenImageSharp[0].fluid.src}
...
/>
特别感谢@FerranBuireu 为我指明了正确的方向
解决方法
假设功能按预期工作,看起来是 CSS 规则问题,而不是 React/Gatsby 问题。以下规则:
.imageModalBody img {
max-height: calc(100vh - 225px);
}
它永远不会被正确应用,因为 gatsby-image
创建了嵌套 <div>
、<picture>
和 <img>
的 HTML 结构的输出,因此您的规则将受到继承的影响和 HTML 结构的相对性。换句话说,由于结果 HTML 结构,您没有使用该规则指向图像本身。
您应该指向 <Img>
,它确实是一个包装器,而不是一个 <img>
。
return (
<div>
<Modal show={true} onHide={handleClose} centered className={ImagemodalStyles.imageModal} dialogClassName={ImagemodalStyles.imageModalDialog}>
<Modal.Header closeButton />
<Modal.Body>
<Img className={ImagemodalStyles.imageModalBody} fluid={props.data.file.childImageSharp.fluid} />
</Modal.Body>
</Modal>
</div>
)
上面的代码段将添加(找出不同之处,没有 img
):
.imageModalBody {
max-height: calc(100vh - 225px);
}
对于包装器,它可能会也可能不会解决问题,但至少会正确应用规则。没有 CodeSandbox 就很难知道出了什么问题,但您可以使用此解决方法正确应用样式。
请始终记住,在使用 gatsby-image
时,<img>
在生成的 HTML 结构中意义重大,因此您的样式应该应用于它的外部包装器。