Chrome 60和Firefox 55(但不适用于iOS Safari 10.3;这很可能是另一个问题,为什么它在Safari中行为不端).
html,body { width: 100%; height: 100%; padding: 0; margin: 0; border: 0; background-color: lightgrey; } .container { Box-sizing: border-Box; width: 100%; display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: repeat(3,calc((60vh - 12px)/3)); /*grid-template-rows: 1fr 1fr 1fr;*/ /*grid-template-rows: auto auto auto;*/ height: 60vh; border: 3px solid yellow; padding: 3px; /*grid-gap: 20px;*/ /* <-- would also mess things up */ } .tile { } img { Box-sizing: border-Box; display: block; object-fit: contain; width: 100%; height: 100%; margin: 0; border: 0; padding: 3px; }
<!-- The image is 200 x 100 px: a green and a blue square next to each other. --> <div class="container"> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> </div>
重要的是图像的纵横比(2:1)
保存完好.我原以为:
grid-template-rows: 1fr 1fr 1fr;
要么:
grid-template-rows: auto auto auto;
使图像适合网格的行,但它们都不适合.
附:
grid-template-rows: repeat(3,calc((60vh - 12px)/3));
我得到了理想的行为.我怎么能避免自己算数学呢?换句话说,我应该怎么做grid-template-rows:1fr 1fr 1fr; (或类似的东西)有效吗?
在实际页面上很难计算出CSS中容器元素的高度.目标是用CSS网格布局解决它;没有JavaScript,没有背景图片黑客.
更新:我最初排除背景图片黑客有两个原因.
>我认为(由于一些误解)的背景图像
url必须在CSS文件中,但事实并非如此:我可以使用
内联样式并将其包含在HTML中.
>感觉很乱.在看到它变得多么复杂和混乱之后
嵌套的Flex容器嵌套在网格容器中只是为了使它在Safari上工作,我只是采用了背景图像黑客,因为它非常清晰,适用于所有经过测试的浏览器(Chrome,Firefox,Safari).
最后,它不是有助于解决我的问题的公认答案.
解决方法
Chrome和Firefox会对您的意图进行有根据的猜测.他们实施了旨在超越规范指导的算法,以改善用户体验.他们将这些修改称为“interventions”.
Safari不会这样做. Safari严格遵守spec语言,该语言指出元素上的百分比高度必须在父级上具有已定义的高度,否则将被忽略.
这里将更详细地解释这些浏览器差异:
> CSS Grid Row Height Safari Bug
> Chrome / Safari not filling 100% height of flex parent
然后,您必须考虑默认情况下,网格项不能小于其内容.如果您的行设置为1fr,但图像高于分配的空间,则行必须展开.您可以使用min-height:0 / min-width:0或使用除visible之外的任何值溢出来覆盖此行为.
此处更详细地解释了此行为:
> Prevent grid items from stretching in CSS Grid Layout
> Why doesn’t flex item shrink past content size?
尽管如此,一旦您考虑了上述指导,您可以使用网格和弹性属性的组合使您的布局在Safari中工作:
* { Box-sizing: border-Box; } body { display: flex; flex-direction: column; height: 100vh; margin: 0; background-color: lightgrey; } header,footer { flex: 0 0 100px; background-color: tomato; display: flex; align-items: center; justify-content: center; } .container { flex: 1; min-height: 0; display: grid; grid-template-columns: 1fr 1fr; grid-auto-rows: auto; padding: 3px; } .tile { display: flex; flex-direction: column; justify-content: center; min-height: 0; } img { max-width: 100%; max-height: 100%; object-fit: contain; padding: 3px; }
<header>HEADER</header> <!-- The image is 200 x 100 px: a green and a blue square next to each other. --> <div class="container"> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> </div> <footer>FOOTER</footer>