标题中的问题在this other question多年前就已经在某种程度上得到了解决,但那里的答案似乎并不是完整的故事,正如我将在这个问题中所展示的那样.

我有一个网格,有两列和两行.最上面的两个单元格有图像填充,最下面一行有一个单元格跨越两列,图像填充整个单元格.

在手机上的布局会有所不同,所以我需要使用图片元素.然而,出于本例的目的,每个<picture>中只有一个<img>.

现在,<picture>种元素是奇怪的.The specification没有说明它是如何运作的,the MDN article在这里没有增加任何相关的东西.也许还有其他相关的规格?这里讨论的奇怪之处在于<picture>个元素是如何与CSS样式规则交互的.

普遍的智慧(参见上面链接的另一个问题)似乎是,类应该应用于<img>元素,而不是<picture>元素.如果我们按照上面链接的规范中的注释中描述的方式处理它,这是有意义的:

picture元素本身不显示任何内容;它只提供其包含的img元素的上下文

这对我来说已经很好用了很多年,但现在我发现,当<picture>个元素作为一个css网格的直接子元素时,它似乎崩溃了.

正如您将在下面的示例中看到的,我必须将grid-column直接应用于<picture>元素才能应用它;如果设置在<img>元素上,则不会.另一方面,我必须将其他样式直接应用到<img>元素;如果将它们设置在<picture>元素上,它们将不会执行我希望它们执行的操作.

我当然可以这么做,但感觉很不舒服,因为这感觉像是脆弱的未经记录的行为.我想知道什么东西需要go 哪里的规则.

这种行为在 firefox 和Chrome上是一致的.

有没有人能说明一下相关的规格?你认为当前的行为是正确的(根据什么?)还是错误?它可能是稳定的还是不稳定的?

.grid {
    display: grid;
    gap: 2rem;
    aspect-ratio: 1 / 1;
    grid-template: 1fr 1fr / 1fr 1fr;
    background-color: #ccc;
}
.cell {
    background-color: #dfd;
}
.cell-3 {
    grid-column: span 2;
}
.fill {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
<h2>1. Grid with divs</h2>
<p>Simple case. Everything is as expected here.</p>
<div class="grid">
    <div class="cell cell-1">Cell 1</div>
    <div class="cell cell-2">Cell 2</div>
    <div class="cell cell-3">Cell 3</div>
</div>

<h2>2. Grid with pictures, all classes on img elements</h2>
<p>I can't find proper documentation but as far as I understand it, classes shouldn't be put on picture elements but rather on the img elements within them, since picture elements aren't displayed, just provide context for the nested img.</p>
<p>So in this example all classes are on the img elements.</p>
<p>The .fill class is getting applied and so the images fill their cells and imagery zooms to fill. But the .cell-3 class is doing nothing; it's meant to make the bottom kitten fill both columns. Dev tools complain that it won't do anything because it's not on grid item.</p>
<div class="grid">
    <picture><img src="https://placekitten.com/400/400" width="400" height="400" class="cell cell-1 fill"></picture>
    <picture><img src="https://placekitten.com/400/400" width="400" height="400" class="cell cell-2 fill"></picture>
    <picture><img src="https://placekitten.com/800/400" width="800" height="400" class="cell cell-3 fill"></picture>
</div>

<h2>3. Grid with pictures, all classes on picture elements</h2>
<p>In this example I've moved all the classes to the picture element rather than the img element.</p>
<p>This time, the correct cell size is applied to cell 3 via the .cell-3 class. The .fill class is not having the expected effect, however; the images don't fill their cells.</p>
<div class="grid">
    <picture class="cell cell-1 fill"><img src="https://placekitten.com/400/400" width="400" height="400"></picture>
    <picture class="cell cell-2 fill"><img src="https://placekitten.com/400/400" width="400" height="400"></picture>
    <picture class="cell cell-3 fill"><img src="https://placekitten.com/800/400" width="800" height="400"></picture>
</div>

<h2>4. Grid with pictures, grid classes on picture elements, size classes on img elements</h2>
<p>This shows the desired output. In this example I've put the .cell* classes on the picture element and the .fill class on the img element.</p>
<div class="grid">
    <picture class="cell cell-1"><img src="https://placekitten.com/400/400" width="400" height="400" class="fill"></picture>
    <picture class="cell cell-2"><img src="https://placekitten.com/400/400" width="400" height="400" class="fill"></picture>
    <picture class="cell cell-3"><img src="https://placekitten.com/800/400" width="800" height="400" class="fill"></picture>
</div>

Codepen link if you prefer.

推荐答案

默认情况下,图片元素为display:inline,因此其行为类似于span.就像span一样,如果它是display:grid元素的子元素,那么它生成的框就是一个网格项,并且是块化的.

获得所需效果的一种方法是将图片元素设置为display:contents.这样,它就不会生成一个盒子,img元素的盒子将成为grid-item,img元素的样式就像它是grid元素的子元素一样.

根据"图片元素本身不显示任何内容"的说法,如果图片元素是在display:contents之后发明的,那么它很有可能在默认情况下被定义为display:contents,但事实并非如此,向后兼容意味着它以后不能被更改.

.grid {
    display: grid;
    gap: 2rem;
    aspect-ratio: 1 / 1;
    grid-template: 1fr 1fr / 1fr 1fr;
    background-color: #ccc;
}
.cell {
    background-color: #dfd;
}
.cell-3 {
    grid-column: span 2;
}
.fill {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
picture {
  display: contents;
}
<h2>5. Grid with pictures, picture element is display:contents, grid classes on img elements, size classes on img elements</h2>
<p>This shows the desired output. In this example I've put the .cell* classes and the .fill class on the img element.</p>
<div class="grid">
    <picture><img src="https://placekitten.com/400/400" width="400" height="400" class="cell cell-1 fill"></picture>
    <picture><img src="https://placekitten.com/400/400" width="400" height="400" class="cell cell-2 fill"></picture>
    <picture><img src="https://placekitten.com/800/400" width="800" height="400" class="cell cell-3 fill"></picture>
</div>

Html相关问答推荐

为什么html复选框总是具有只读属性?

Angular 15 p-对话框不使用组件 Select 器呈现HTML

调整一组IMG的大小以适应容器DIV

摆动的html标签

使用bash从html表格中提取表格

为什么我不能覆盖 div 的样式?

如何从通过 find-each 方法(在 Rails 应用程序中)生成的列表创建下拉菜单?

是否可以制作响应式 CSS 剪辑路径?

如何使用javascript在jsx中重复插入特殊字符?

如何将内容放置在侧边栏旁边?

如何通过像图像一样的 元素来调整 SVG 图标的大小

绝对类在另一个绝对类之上

显示填充正方形的图形的简单页面的 HTML 代码

HTML 如何根据屏幕尺寸调整/裁剪视频背景?

CSS 中的 fingerprint scanner 动画

如何使用 CSS 和 HTML 将文本放入图像中?

如何使用 CSS 制作蜂窝状网格?

使用 bootstrap-icons 的未排序图标堆栈

我正在try 向我预先存在的导航栏添加响应式汉堡包导航,但由于某种原因它没有显示

无法使用 Reactjs 多次更新本地存储