使用盒子模型在其父 div 中包含项目
Posted
技术标签:
【中文标题】使用盒子模型在其父 div 中包含项目【英文标题】:Using box model to contain items within its parent div 【发布时间】:2013-04-19 06:33:37 【问题描述】:使用以下 html 和 CSS3 规则,我试图确保遵守以下标准:
除了第 1 项之外,我的所有标准都有效 孩子们超过了他们父母的宽度。问题:如何让孩子留在父母身边?
-
li 项不能超过其父级宽度,即 400px
img、标签和货币内容必须在它们的范围内垂直居中
货币不应换行,应始终完整显示
货币应始终显示在尽可能靠近
标签跨度。
标签文本应被限制在 2 行处,并在超过 2 行的地方显示省略号。
注意:只需要在 Chrome 和 Safari 基于 webkit 的浏览器中工作。
应该是这样的:
但是,现在看起来是这样的:
有什么想法吗?
********************* JS Fiddle example *********************** *
<ul>
<li>
<span class="img"></span>
<span class="label">Acclaim</span>
<span class="currency">(USD 50)</span>
</li>
<li>
<span class="img"></span>
<span class="label">Acclaim 1 11 111 1111 11111</span>
<span class="currency">(USD 50)</span>
</li>
<li>
<span class="img"></span>
<span class="label">Acclaim 1 11 111 1111 11111 2 22222 2222 22222 3 33 333 3333 33333 4 44 444 4444 44444 5 55 555 5555 55555 6 66 666 6666 66666</span>
<span class="currency">(USD 50)</span>
</li>
</ul>
ul
width: 400px;
background-color: yellow;
padding: 0;
margin: 0;
li
display: -webkit-box;
padding-right: 50px;
.label
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-box-pack: center;
-webkit-line-clamp: 2;
text-overflow: ellipsis;
overflow: hidden;
white-space: normal;
word-wrap: break-word;
line-height: 1.3em;
margin-right: 0.2em;
background-color: pink;
.currency
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-box-pack: center;
white-space: nowrap;
background-color: lightgreen;
.img
display: block;
width: 40px;
height: 40px;
margin-right: 0.1em;
background-image:url('data:image/png;base64,iVBOR...);
【问题讨论】:
这是我使用 flex 模型的另一个小提琴,但仅限于 Chrome。它仍然不适用于 Safari? jsfiddle.net/tUqvG - 然而,它有点混合了 flex 和 box 模型,因为我无法让省略号和 line-clamp 与 flex 模型一起使用。 Flexbox 没有替代盒子模型。这只是布局的另一种选择。 你不会让 line-clamp 在 Safari 中使用 box 模型或 flex 模型,因为文本溢出:省略号不适用于多行文本,你的只是 Chrome 上的幸运解决方案. :) 见quirksmode.org/css/user-interface/textoverflow.html 您可能会使用 :after 选择器和 content: '...' 来伪造文本溢出:省略号,但无论如何它都不会太好。 @DavidStorey 将此声明删除为不正确。 【参考方案1】:我已经解决了这个问题,可以在没有 javascript 的情况下工作。但是,它仅适用于更现代的浏览器,包括 Chrome 和 Opera。它在 Safari 中不起作用。一旦更新到最新规范,它将在 Firefox 中运行。我可能可以让它在 IE10 中工作,但我必须进一步研究。省略号仅适用于 Chrome/Safari,因为它是特定于供应商的。
演示在http://jsfiddle.net/uLm92/1/
首先,我们要将 li 设置为 flexbox 容器并将其设置为 400px,因此 flex 项目将尝试适应该大小(稍后会详细介绍):
li
/* make all items inside li as flex items */
display: -webkit-flex;
display: flex;
height: 40px;
max-width: 400px;
现在子项目是弹性项目,让标签适合的关键是将图像和价格设置为不弹性。对于价格,我们知道它希望总是 40xp 宽,所以我设置了以下内容:
.img
width: 40px;
height: 40px;
-webkit-flex-basis: 40px;
flex-basis: 40px;
-webkit-flex-shrink: 0;
flex-shrink: 0;
这表示 id 为 40px 的首选且永远不会变小。
然后我们还想告诉价格永远不要缩小,并且还要让匿名框(内容)居中:
.currency
/* make anonymous box vertically centred */
display: -webkit-flex;
display: flex;
-webkit-align-items: center;
align-items: center;
/* make sure it never shrinks */
-webkit-flex-shrink: 0;
flex-shrink: 0;
最后,我们还想让标签文本居中。由于您需要省略号技巧,因此我使用了 WebKit 的旧 Flexbox 语法。不使用旧的 flexbox,line-clamp 属性不起作用:
.标签
/* need to use old flexbox for line-clamp to work
it is a *horrible hack* */
display: -webkit-box;
display: flex;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow : hidden;
text-overflow: ellipsis;
-webkit-box-pack: center;
align-items: center;
由于其他两项永远不会缩小,因此 .label 元素是唯一可以缩小的元素,因此如果没有剩余空间,它会缩小尺寸。
【讨论】:
您好,再次感谢您的努力。但是,如原始问题所述(“注意:仅需要在基于 Chrome 和 Safari webkit 的浏览器中工作”)我需要一个在 Chrome 和 Safari 中工作的解决方案,因为这需要在 android 和 ios 设备上工作。我认为我们遇到了 CSS 限制。 Flexbox 能够做你想做的事,但遗憾的是 Safari 不能。它的 Flexbox 实现还不够好。它不支持在不增长元素的情况下缩小元素。您可以添加更多后备以使其主要在 Safari 中工作,但您无法正确缩小内容。这不是 CSS 限制;这是 Safari 的限制。【参考方案2】:如果价格没有变高,以下方法将起作用:
http://jsfiddle.net/WDjZ3/4/
我只是将 margin-right 转换为像素,以便知道标签以外的内容占用的空间,然后为其余部分添加 max-width:
.label
margin-right: 3px;
max-width: 294px;
如果价格或图像是可变宽度的,您将需要 js 读取它们的宽度,从 400px 中删除并将该值添加到 max-width。
这是一个使用 JavaScript 动态设置最大宽度的示例:http://jsfiddle.net/WDjZ3/7/
我没有检查所有尺寸,所以应该添加它以使其完全准确,否则边距会使价格不再合适。
我基本上检查了其他元素的宽度:
function getWidth(el)
return parseInt(window.getComputedStyle(el,null).getPropertyValue("width"));
然后我从 400px 中删除了这个宽度,并设置了 maxWidth:
for (var i=0; i<imgs.length; i++)
var width = 400 - (getWidth(imgs[i]) + getWidth(currencies[i])) + "px";
labels[i].style.maxWidth = width;
【讨论】:
嗨 - 谢谢你的回答 - 我很感激你投入的时间。由于价格总是可以更大或更小,因此您提出的纯 CSS 解决方案是不够的。我正在寻找使用盒子模型(或弹性模型)的解决方案,请参阅帖子标题。我真的在寻找一种仅在 CSS 中执行此操作的方法。如您所见,我最初编写的 CSS 几乎实现了这一点。再次感谢。以上是关于使用盒子模型在其父 div 中包含项目的主要内容,如果未能解决你的问题,请参考以下文章