我正在构建一个购物车页面,并希望列出产品的图像,标题,价格和一个表单元素以将其从购物车中删除。
我尝试在要截断的元素上同时使用white-space: nowrap;
,overflow: hidden;
和text-overflow: ellipsis;
,但是我不知道如何正确显示它们,尤其是在img-container
和name-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。
答案 0 :(得分:1)
您需要进行一些更改才能获得所需的行为。首先,您需要了解自己正在处理Flexbox中的负空间情况。那是内容长度的总和大于可用父级的长度。
在这种情况下,flexbox将计算它们之间的差异,并尝试根据每个孩子的flex-shrink
因素,在允许flex-shrink
的孩子之间平均分配差异。
因此,您需要将.name-price-container
的{{1}}设置为flex-shrink
:
1
没有它,省略号就不会发生,因为内容(您的 .name-price-container {
flex: 1 1 auto;
}
)将始终根据需要增长,从而设置<a>
,因此width
的flex-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 ... of
。 Grid将使您可以更准确地定义列,在行的每个内容部分之间保持空间,并在网格区域内截断该内容。
这也将使您无需将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兼容的模块)。
我希望这会有所帮助!