使用文本溢出:带flexbox的省略号

时间:2019-01-26 01:35:31

标签: html css django twitter-bootstrap css3

我正在构建一个购物车页面,并希望列出产品的图像,标题,价格和一个表单元素以将其从购物车中删除。

我尝试在要截断的元素上同时使用white-space: nowrap;overflow: hidden;text-overflow: ellipsis;,但是我不知道如何正确显示它们,尤其是在img-containername-price-container使用flexbox。

这是我的Django模板:

<ul>
    {% for product in products %}
    <li class="row product">
        <div class="img-container">
            <a href="{% url 'gallery:product_page' %}?id={{ product.id }}">
                <img src="{{ product.image.url }}" alt="{{ product.name }}">
            </a>
        </div>
        <div class="name-price-container">
            <span>
                <a href="{% url 'gallery:product_page' %}?id={{ product.id }}">{{ product.name }} Loooooooooong Text</a>
            </span>
            <span>${{ product.price_per_unit }}</span>
        </div>
        <div class="btn-container">
            <form method="POST" action="{% url 'gallery:remove_cart' %}">
                {% csrf_token %}
                <input type="hidden" name="id" value="{{ product.id }}">
                <input type="submit" class="btn btn-light" value="Remove">
            </form>
        </div>
    </li>
    {% endfor %}
</ul>

...以及相关的CSS:

.product .img-container {
  background-color: #343a40;
  border: 1px solid #343a40;
  box-sizing: unset;
  height: 128px;
  width: 128px;
  flex: 0 0 auto;
}
.product .img-container img {
  display: block;
  max-height: 128px;
  max-width: 128px;
  width: auto;
  height: auto;
}
.name-price-container {
  margin: 0 1rem;
  display: flex;
  flex: 1 0 auto;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
}
.name-price-container a {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.btn-container {
  float: right;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.btn-container .btn {
  margin: 0;
}
@media all and (max-width: 768px) {
  body * {
    overflow: hidden;
  }
  .product .img-container {
    height: 64px;
    width: 64px;
  }
  .product .img-container img {
    max-width: 64px;
    max-height: 64px;
  }
}

...以及470px宽度的呈现: Image here

请注意,第一个和第三个结果正确呈现,但是如果文本比页面上的文本长,而不是被截断,则表单元素将换行。

感谢您的帮助。

编辑:这是根据安德烈(Andrei)的评论更新的jsfiddle

2 个答案:

答案 0 :(得分:1)

您需要进行一些更改才能获得所需的行为。首先,您需要了解自己正在处理Flexbox中的负空间情况。那是内容长度的总和大于可用父级的长度。
在这种情况下,flexbox将计算它们之间的差异,并尝试根据每个孩子的flex-shrink因素,在允许flex-shrink的孩子之间平均分配差异。

因此,您需要将.name-price-container的{​​{1}}设置为flex-shrink

1

没有它,省略号就不会发生,因为内容(您的 .name-price-container { flex: 1 1 auto; } )将始终根据需要增长,从而设置<a>,因此widthflex-basis(目前无法缩小)。因此,没有省略号。


您的第二个问题是事实.name-price-container元素,默认情况下<a>display。为了使省略号起作用,您需要一种限制其宽度的方法。最简单的方法是给它inline(因为现在缩小了父级)。另一种选择是将省略号效果移到display:block并赋予跨度span

最后,您要防止width: 100%缩小并删除其.btn-container。给它overflow并从其中删除flex-shrink: 0

顺便说一句,overflow: hidden 确实 您要避免的东西,因为它覆盖了每个元素的body * { overflow: hidden; }的默认值在您的页面中。如果您更改了很多元素,它们将不再能按预期工作。下拉菜单,工具提示,弹出窗口和模式,仅举几例。

这是您的工作示例:

overflow
@import url('https://fonts.googleapis.com/css?family=Open+Sans');
* {
  font-family: 'Open Sans', Helvetica, Arial, sans-serif;
}
body {
  background-color: #e6ebf0;
}
ul {
  padding-left: 0;
}
ul li {
  list-style: none;
}
ul li img {
  width: 100%;
}
.img-container {
  background-color: #343a40;
  border: 1px solid #343a40;
	display: flex;
	flex: 1 0 auto;
	flex-direction: column;
  justify-content: center;
  align-items: center;
}
form {
  display: inline;
}
.btn-light {
  background-color: white;
  border: 1px solid #ced4da;
}
.row {
  margin: 0;
}
.product {
  display: flex;
}
.product,
.total {
  margin-top: 0.5rem;
  padding: 1rem;
  background-color: white;
  border: 1px solid #ced4da;
  border-radius: 4px;
}
.product .img-container {
  background-color: #343a40;
  border: 1px solid #343a40;
  box-sizing: unset;
  height: 128px;
  width: 128px;
  flex: 0 0 auto;
}
.product .img-container img {
  display: block;
  max-height: 128px;
  max-width: 128px;
  width: auto;
  height: auto;
}
.name-price-container {
  margin: 0 1rem;
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
}
.name-price-container a {
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.name-price-container a,
.name-price-container a:hover {
  color: #212529;
}
.btn-container {
  height: 130px;
  line-height: 130px;
  min-width: 0;
  white-space: nowrap;
}
.btn-container .btn {
  margin: 0;
  display: inline-block;
}
@media all and (max-width: 768px) {
  .product .img-container {
    height: 64px;
    width: 64px;
  }
  .product .img-container img {
    max-width: 64px;
    max-height: 64px;
  }
  .btn-container {
    height: 66px;
    line-height: 66px;
    flex-shrink: 0;
  }
}

更新了fiddle here

答案 1 :(得分:0)

我知道您的问题专门提到了flexbox,但在这种情况下,我将使用for ... ofGrid将使您可以更准确地定义列,在行的每个内容部分之间保持空间,并在网格区域内截断该内容。

这也将使您无需将float和flexbox一起使用,这可能会带来意想不到的后果。由于网格可以在任何大小的行和列中保持内容的清晰定义,因此网格是您在此处执行操作的最合适的显示选项。

它可能看起来像这样:

display: grid

有关实际操作的示例,请参见this codepen

有一种方法可以处理您要使用flexbox进行的操作,但是维护起来并不容易。如果您花时间将其转换为网格,则将拥有更可靠的布局。如果您尝试使用此代码,则会发现

请注意,尽管您可能不需要支持IE11或更低版本,但<= IE11并不完全支持网格。如果您这样做,将有一些特殊的技巧可以通过使用.product { //each .product container will contain 1 row with 3 columns display: grid; grid-gap: 1rem; //this adds a gap between the sections of your row grid-template: "image info button" 128px / 128px auto 128px; //i assumed your button is 128px wide } .product .img-container { background-color: #343a40; border: 1px solid #343a40; box-sizing: unset; grid-area: image; //this places the .img-container div within the "image" grid area defined above in grid-template height: 128px; width: 128px; } .product .img-container img { display: block; max-height: 128px; max-width: 128px; width: auto; height: auto; } .name-price-container { display: flex; flex-direction: column; grid-area: info; //this places the .img-container div within the "info" grid area justify-content: center; min-width: 0; } .name-price-container span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .btn-container { display: flex; flex-direction: column; grid-area: button; //this places the .img-container div within the "button" grid area justify-content: center; } .btn-container .btn { margin: 0; } @media all and (max-width: 768px) { body * { overflow: hidden; } .product { grid-template: "image info button" 64px / 64px auto 128px; } .product .img-container { height: 64px; width: 64px; } .product .img-container img { max-width: 64px; max-height: 64px; } } 供应商前缀来实现网格布局。 Here是一篇很棒的文章,详细介绍了您可以使用的一些技巧(以及一个可以自动将CSS转换为与IE11兼容的模块)。

我希望这会有所帮助!