流式CSS布局在Firefox和IE11中出现问题

5
我想将一个图像容器放在文本框旁边,使图像始终与文本的高度匹配。
<-         50%        ->  <-         50%        ->         
+----------------------+  +----------------------+
| Lorem ipsum dolor si |  | some                 |
| t amet, consectetuer |  | image                |
| adipiscingelit. Aene |  |                      |
| an commodoligula ege |  |                      |
| t dolor.             |  |                      |
+----------------------+  +----------------------+

vs

+------------+  +------------+
| Lorem ipsu |  | some       |
| m dolor si |  | image      |
| t amet, co |  |            |
| nsectetuer |  |            |    Reduce
| adipiscing |  |            |<-- browser
| elit. Aene |  |            |    width
| an commodo |  |            |
| ligula ege |  |            |
| t dolor.   |  |            |
+------------+  +------------+

为了实现这一点,我将两个容器都包装在一个 div 中,并将图像显示为 background-image:
<div class="outerTable">
    <div>Lorem ipsum dolor sit amet, consectetuer</div>
    <div class="image">
        <div></div>
    </div>
</div>

以下为相应的样式:

.outerTable {
    width: 100%;
    display: table;
}
.outerTable > div {
    display: table-cell;
    border: 10px solid transparent;
    background-clip: padding-box;
    position: relative;
    background-color: #fff;
    padding: 2%;
    width: 50%;
}
.image {
    background-color: #fff;
}
.image > div {
    background-image: url(http://lorempixel.com/500/300/abstract/4);
    background-size: cover;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    padding: 6%;
    background-clip: content-box;
    background-position: 0 0;
}

这里有一个可运行的示例:http://jsfiddle.net/KxFUL/

在Chrome、Safari和Opera中,这个示例可以正常工作。但是在FireFox中,图片会覆盖整个页面,在IE11中则完全不显示…

我是否漏掉了什么,理解错误?有什么想法?还有其他的解决方案吗?


出于我的好奇心 - 你为什么想让一张图片的高度是宽度的五倍? - Mave
实际布局看起来更像这样:http://jsfiddle.net/hY9aH/1/ 我只是想有一个简单的例子来讨论... - AvL
5个回答

1
这是如果你愿意可以做的事情。 移除设置背景图像的
标签。我知道你想将其与带有边框的图像联系起来,但你可以通过设置内阴影的 CSS 实现这一点。

http://jsfiddle.net/cornelas/KxFUL/4/

.outerTable > div {
  display: table-cell;
  border: 10px solid transparent;
  background-clip: padding-box;
  position: relative;
  background-size: cover;
  background-color: #fff;
  padding: 2%;
  width: 50%;
}
.image {
  background-color: #fff;
  background-image: url(http://lorempixel.com/500/300/abstract/4);
}

这是将边框添加回去的代码。
.image {
   background-color: #fff;
   background-image: url(http://lorempixel.com/500/300/abstract/4);
   -webkit-box-shadow:0 0 0 13px #FFFFFF inset;
   box-shadow:inset 0px 0px 0px 13px #ffffff;
 }

更新 fiddle http://jsfiddle.net/cornelas/KxFUL/6/


这绝对是一个开始!我会尝试一下……明天…… - AvL

1
我的解决方案有点冗长,但只是通过改变CSS来实现你想要的效果。首先我尝试使用padding而不是透明边框,我设置的第一个padding是在.outer-table上。当然,该表格是100%宽度,因此您需要添加Paul Irish建议的box-sizing修复。然后,我在.col-66上设置了右侧padding以创建均匀间距(margin不能用于display:table-cell)。最后,我将背景图像设置为.image,而不是在其中的空容器上,这意味着无需绝对定位。新的CSS如下:
/* apply a natural box layout model to all elements */
*, *:before, *:after {
    -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box;
}

body {
    background-image: url(http://bradjasper.com/subtle-patterns-bookmarklet/patterns/concrete_wall.png);
    background-repeat: repeat repeat;
}
.outerTable {
    width: 100%;
    display: table;
    padding: 10px;
}
.outerTable > div {
    display: table-cell;
}
.col-33 {
    width: 33.333%
}
.col-66 {
    width: 66.666%;
    padding-right: 20px;
}
.content {
    padding: 3.4%;
    background-clip: padding-box;
    margin-bottom: 20px;
    background-color: #fff;
}
.content:last-child {
    margin-bottom: 0;
}
.image {
    background-image: url(http://lorempixel.com/500/300/abstract/4);
    background-size: cover;
    border: 10px white solid;
    background-position: 0 0;
}

并用小提琴来结束它。


哇,这在所有主要浏览器上都可以工作,并且没有像 Cams 方案那样裁剪图像的缺点!但是我们是否需要在 .content 中使用 background-clip: padding-box; - AvL
糟糕!如果.content中没有足够的内容怎么办:http://jsfiddle.net/lucadou/hY9aH/5/ ??? - AvL
我只能想到这个非常不好的解决方法:http://jsfiddle.net/lucadou/hY9aH/6/ 但由于我使用媒体查询,所以可能可以使用它... - AvL
不,你不需要 background-clip - 很好的发现。我没有去除所有不必要的规则,我只是添加了修复。不确定我是否理解第二个问题?在你的 fiddle 中,你错过了 .outerTable 上的 display: table。如果你在我给出的 fiddle 中使用较少的文本,它看起来还不错?http://jsfiddle.net/lucadou/hY9aH/6/ - davidpauljunior
你说得对,我漏掉了 display: Table - http://jsfiddle.net/lucadou/hY9aH/9/ 谢谢! - AvL
显示剩余2条评论

0

表格单元格元素并不是真正意义上的 position: relative;,我相信如果您尝试在实际的表格单元格 <td> 上设置它是行不通的,虽然我可能错了。

因为您正在使用 CSS 表格,大多数现代浏览器都允许您在其上设置它,但 Firefox 似乎坚持认为表格单元格不允许它。

您可以通过几种方式解决这个问题,但这将取决于您还有什么其他事情要做。

例如,您可以在表格单元格元素内部的内容周围包装一个额外的 <div>,然后将其设置为 position: relative;。这样做的缺点是您需要给它一个固定的高度,如果您需要高度随内容流动,则无法工作。

您也可以使用 javascript/jQuery 来完成。

这篇文章对此进行了很好的概述,所以我不会详细解释过程,因为他做得更好:

http://css-tricks.com/absolutely-position-element-within-a-table-cell/

请注意,他正在使用它在实际的表格元素上,所以你需要做一些更改。本质上,它与我上面列出的额外div相同的过程,只是用JS动态设置高度。你可以将其改编为在窗口调整大小时更改高度以使其响应等等...
最后,(就我的建议而言,我相信这里还有更多选项未列出)- 我首选的建议是,您可以使用display:inline-block;来构建您的两列布局,而不是display:table-cell;。这种方式将避免整个陷阱,并且还将减少您需要获得效果的HTML元素数量。
这是一个很好的阅读材料:

http://designshack.net/articles/css/whats-the-deal-with-display-inline-block/


我真的想避免使用JavaScript解决方案 - 但感谢您提供有关“inline-block”的信息!我会去看一下... - AvL
float 也可以使用,但它不能保持一切整洁,并且可能会与其他样式产生问题。但根据您的用例,这可能是一个有效的选项。 - Blake Mann

0
问题在于您为 .image div 设置了 display:table-cell,然后在其中放置了一个绝对定位的元素。table-cell 无法包含绝对定位的元素,因为其中的元素不是从其父元素(虽然其父元素是相对定位的)获取坐标进行定位,而是从表格(或 display:table)获取。

是的,我知道 - 但也许有其他解决方案适用于我的布局? - AvL
至少在Chrome/Mac中,我无法在您的解决方案中看到图像... - AvL

0

在表格单元格中,您无法使用绝对定位与表格单元格相关联(不要问我为什么,我没有发明这个愚蠢的CSS规范)。无论如何,.image应该具有position:relative才能使position:absolute正常工作。

我猜Chrome很好地忽略了标准,或者类似于那样的东西。


1
在这种情况下,.outerTable > div 等于 .image -> position: relative - AvL

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接