使用盒子模型在其父 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 中工作的解决方案,因为这需要在 androidios 设备上工作。我认为我们遇到了 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 中包含项目的主要内容,如果未能解决你的问题,请参考以下文章

盒子模型漫谈

初学css盒子模型,对于盒子的使用不是很明白,请问这样的盒子布局怎么写?

css,关于盒子模型

盒子模型(Box Model)

盒子模型

HTML5+CSS——11盒子模型-边框、内边距、外边距