从版本 10 开始,Next.js 带有内置Image
组件,该组件提供图像优化和响应式调整图像大小的功能。我非常喜欢它,我一直在我的网站上使用它来制作固定尺寸的图像。根据官方文档,除非是 for ,否则 width 和 height 是必需的道具layout=fill
。
Image
现在,即使我事先不知道宽度和高度,我也想使用组件。我有来自 CMS 的博客资源,其中图像的确切大小未知。在这种情况下,有什么办法可以使用Image
组件吗?
任何帮助,将不胜感激。
从版本 10 开始,Next.js 带有内置Image
组件,该组件提供图像优化和响应式调整图像大小的功能。我非常喜欢它,我一直在我的网站上使用它来制作固定尺寸的图像。根据官方文档,除非是 for ,否则 width 和 height 是必需的道具layout=fill
。
Image
现在,即使我事先不知道宽度和高度,我也想使用组件。我有来自 CMS 的博客资源,其中图像的确切大小未知。在这种情况下,有什么办法可以使用Image
组件吗?
任何帮助,将不胜感激。
是的,您可以将它与layout=fill
您提到的选项一起使用。
在这种情况下,您需要为图像设置“纵横比”
<div style={{ position: "relative", width: "100%", paddingBottom: "20%" }} >
<Image
alt="Image Alt"
src="/image.jpg"
layout="fill"
objectFit="contain" // Scale your image down to fit into the container
/>
</div>
您也可以使用objectFit="cover"
它,它会放大您的图像以填充所有容器。
这种方法的缺点是会附加到width
您指定的,它可以是相对的,例如“100%”或绝对的,例如“10rem”,但是没有办法根据大小设置像自动宽度和高度你的形象,或者至少还没有。
我也有同样的问题:我想在MUI的砖石中Image
使用next/image ...ImageList
无论如何,这是我用来获取图像大小并处理容器大小的技巧:
import React, { FC, useState } from 'react';
import styled from 'styled-components';
import Image from 'next/image';
interface Props {
src: string;
}
export const MasonryItem: FC<Props> = ({ src }) => {
const [paddingTop, setPaddingTop] = useState('0');
return (
<Container style={{ paddingTop }}>
<Image
src={src}
layout="fill"
objectFit="contain"
onLoad={({ target }) => {
const { naturalWidth, naturalHeight } = target as HTMLImageElement;
setPaddingTop(`calc(100% / (${naturalWidth} / ${naturalHeight})`);
}}
/>
</Container>
);
};
const Container = styled.div`
position: relative;
`;
这个想法:在加载时获取图像的大小,计算比率并使用它来使容器用 padding-top 填充所需的空间。这样,无论您的图像大小如何,容器都将适合它。
备注,我没有在容器上使用宽度或高度,因为我的项目不需要它,但也许您必须为您的项目设置两者之一。
由于我仍然从 React & NextJS & typescript 开始,也许解决方案可以更漂亮,如果有人有改进它的想法,我会很高兴阅读它!
如果要保留原始图像的比例,可以这样做:
<div
style={{
width: 150,
height: 75,
position: "relative",
}}>
<Image
src={"/images/logos/" + merger.companyLogoUrl}
alt={merger.company}
layout="fill"
objectFit="contain"
/>
图像将填充到容器允许的大小。因此,如果您知道图像的宽度大于长度,例如,您可以设置容器的宽度,然后将容器的高度设置为大于预测的图像高度。
因此,例如,如果您正在使用宽图像,您可以将容器宽度设置为 150 像素,那么只要容器高度大于图像高度,图像就会以原始比例的高度显示。
有时您希望拥有不同的图像尺寸,例如小、中和大。我们将一个 prop 传递给组件,并基于这个 prop,我们使用不同的样式。在这种情况下,layout="fill"
是得心应手的。
填充时,图像将宽度和高度拉伸到父元素的尺寸,前提是元素是相对的
const Card = (props) => {
const { imgUrl, size } = props;
const classMap = {
large: styles.lgItem,
medium: styles.mdItem,
small: styles.smItem,
};
return (
<div className={classMap[size]}>
<Image src={imgUrl} alt="image" layout="fill" />
</div>
);
};
您为每种情况编写 css 样式。重要的是你应该拥有position:relative
. 例如:
.smItem {
position: relative;
width: 300px;
min-width: 300px;
height: 170px;
min-height: 170px;
}
.mdItem {
position: relative;
width: 158px;
min-width: 158px;
height: 280px;
min-height: 280px;
}
.lgItem {
position: relative;
width: 218px;
min-width: 218px;
height: 434px;
min-height: 434px;
}
我写了一篇博文,详细介绍了如何获取远程图像的大小,同时还使用了 SSG。如何在 Next.js 中使用未知宽度和高度的图像组件
import Image from "next/image";
import probe from "probe-image-size";
export const getStaticProps = async () => {
const images = [
{ url: "https://i.imgur.com/uCxsmmg.png" },
{ url: "https://i.imgur.com/r4IgKkX.jpeg" },
{ url: "https://i.imgur.com/dAyge0Y.jpeg" }
];
const imagesWithSizes = await Promise.all(
images.map(async (image) => {
const imageWithSize = image;
imageWithSize.size = await probe(image.url);
return imageWithSize;
})
);
return {
props: {
images: imagesWithSizes
}
};
};
//...
export default function IndexPage({ images }) {
return (
<>
{images?.map((image) => (
<Image
key={image.url}
src={image.url}
width={image.size.width}
height={image.size.height}
/>
))}
</>
);
}
<Image src={thumbnail || ""}
alt="post-thumbnail"
layout="responsive"
objectFit="cover"
width={6}
height={4}
/>
宽度={6} 高度={4} 是比例
例如:正方形 => 宽度={1} 高度={1}