我在布局具有非常严格的布局要求的电子商务页面时遇到了问题。我们希望在产品描述旁边显示产品图片,并在图片下方显示一些关于产品的可选额外信息。宽度受我们整个页面布局的限制,而高度可以是可变的。答案似乎是“你不能用纯 CSS 做到这一点”。
这是一个模拟:
标记的宽度为 372+12+178=562,边框留出 8px。图片和描述区域有2px的边框,总共有8px的水平像素,562+8=570。
我已经对图像的垂直居中进行了大部分排序,破坏设计的是可选的“额外信息”面板。该站点是由 PHP 生成的,<div>
如果数据可用于产品,PHP 可以选择性地包含该额外信息。如果它有助于解决设计问题,我很乐意始终包含“额外信息”元素并将其设置为不可见,如果它为空的话。
要求:
- 产品图像可以是任何纵横比。有的又瘦又高,有的又宽又短,有的方形。
- 产品图像应水平填充其区域,并按其纵横比自然垂直调整大小。
- 产品图像应在其区域(蓝色)中垂直居中。当额外信息不可见时,图像将在描述区域旁边垂直居中。当额外信息可见时,图像应在剩余空间中垂直居中。
- 额外信息可以是任意数量的文本,并与产品图像区域的底部对齐。所以,不能有固定的高度。
- 产品描述可以是任意数量的文本。
- “图像和额外信息”列应垂直匹配“描述”列的大小,反之亦然。
- 描述和额外信息框使用 CSS 渐变背景和边框。所有这些 div 都必须相应地调整自己的大小,我无法摆脱这里描述的“人造列” http://www.alistapart.com/articles/fauxcolumns/。
- 不想使用 Javascript 来对齐元素。是的,我确信我们都是 jQuery 大师,它是一个很棒的工具,但这种布局不应该是必需的。
到目前为止,我的设计使用纯 CSS 并且没有表格,使用表格单元格样式来居中图像,但是当使用不同大小的图像时,最小高度会中断。一个jsfiddle:http: //jsfiddle.net/GJVbX/
通过将产品描述文本内容增加三倍或添加“宽度:370 像素;高度:400 像素;”很容易破坏该小提琴。所以它不是一个很好的高度。
我设计的一个很好的例子:
但是,不难找到破坏它的图像大小:
请注意高大的产品图像如何使图像 div 垂直扩展并且描述列无法跟上。
我一直在 Freenode 上的#css IRC 频道上,并被告知使用纯 CSS 可以实现这一点,使用表格来完成此布局任务表明我不了解 CSS 布局,应该聘请专业人士,以实现垂直居中我应该使用“显示:表格单元格”。然而,尽管他们非常有帮助,但讨论过于复杂,无法在 IRC 上继续。我知道这<table>
会带来各种可怕的布局机制,这些机制只是为了准确的页面布局而被破坏,但是,我想不出更好的解决方案,主要是因为我要求保持列的高度相同。
希望有建设性的批评,替代解决方案,甚至只是确认我的困境:)
编辑- 这是上面给出的 jsfiddle 中的 HTML 和 CSS 内容,适合那些喜欢包含在 stackoverflow 问题中的内容的人。这是从实时站点中提取的,稍微清理一下缩进,带有虚拟产品图像(由实时站点中使用的缩略图脚本生成)和虚拟文本。
HTML:
<div class="productInfo">
<div class="productTopWrapper">
<div class="productImgWrapper"><div class="wraptocenter"><span></span><img src="http://nickfenwick.com/hood.jpg"></div></div><div class="extraInfoWrapper gradientBackground"><div class="extraInfoInner">Extra info goes here.</div>
</div>
<div class="productDescription gradientBackground"><div class="productDescriptionInner">
Product Description goes here.<br/>
Product Description goes here.<br/>
Product Description goes here.<br/>
Product Description goes here.<br/>
Product Description goes here.<br/>
Yet the gradient ends too soon because this div doesn't fill its space vertically!
</div>
</div>
</div>
</div>
CSS:
DIV.productInfo {
max-width: 570px;
font-family: Verdana,Geneva,'DejaVu Sans',sans-serif;
font-size: 12px; /* Just for this fiddle */
}
.productInfo .productTopWrapper {
overflow: hidden;
margin-bottom: 12px;
position: relative;
}
.productInfo .productImgWrapper {
width: 372px;
min-height: 353px;
float: left;
border: 2px solid #cbcbcb;
text-align: center;
}
/* BEGIN css wrap from http://www.brunildo.org/test/img_center.html */
.wraptocenter {
display: table-cell;
text-align: center;
vertical-align: middle;
width: 372px;
height: 309px;
}
.wraptocenter * {
vertical-align: middle;
}
/*\*//*/
.wraptocenter {
display: block;
}
.wraptocenter span {
display: inline-block;
height: 100%;
width: 1px;
}
/**/
*:first-child+html {} * html .wraptocenter span {
display: inline-block;
height: 100%;
}
/* END css wrap */
.productInfo .extraInfoWrapper {
position: absolute;
left: 0;
bottom: 0;
width: 376px;
}
.productInfo .extraInfoInner {
padding: 5px;
border: 2px solid #cbcbcb;
text-align: center;
}
.productInfo .gradientBackground {
background: #999; /* for non-css3 browsers */
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#d0d1d3', endColorstr='#fefefe'); /* for IE */
background: -webkit-gradient(linear, left top, left bottom, from(#d0d1d3), to(#fefefe)); /* for webkit browsers */
background: -moz-linear-gradient(top, #d0d1d3, #fefefe); /* for firefox 3.6+ */
background: -ms-repeating-linear-gradient(top, #d0d1d3, #fefefe);
background: repeating-linear-gradient(top, #d0d1d3, #fefefe);
}.productInfo .productDescription {
width: 178px;
min-height: 353px;
margin-left: 388px;
border: 2px solid #cbcbcb;
}
.productInfo .productDescriptionInner {
padding: 5px;
font-size: 1.2em;
line-height: 1.2em;
}