我希望网格中有一个单元格,其中包含不重要的信息,这些信息不能使任何其他单元格扩展到超出绝对要求的范围。它的高度不应超过其他细胞的高度,其宽度应为空的未占用区域。
让我们说每个项目我有一个缩略图,一个标题(单个不可绕行的行),信息(零行或多行),描述(可能很长,仅在有空的空间时显示)
我想出了这个:
.list {
display: flex;
flex-wrap: wrap;
font: 12px/14px Verdana;
}
.item {
display: grid;
grid-template-areas:
"thumb thumb thumb thumb"
"sl title desc sr "
"sl info desc sr ";
grid-template-columns:
auto auto 1fr auto;
grid-template-rows:
auto auto 1fr;
min-width: calc(var(--min-item-size) + 4px);
max-width: calc(var(--max-item-size) + 4px);
border: dotted 2px darkblue;
margin: 4px 2px auto 2px;
}
.item > * {
min-width: 0;
min-height: 0;
border: dotted 1px dodgerblue;
margin: 1px;
}
.thumb {
grid-area: thumb;
margin: auto;
height: 100px;
background: linear-gradient(lightskyblue, deepskyblue);
}
.title {
grid-area: title;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.info {
grid-area: info;
overflow: hidden;
text-overflow: ellipsis;
}
.desc {
grid-area: desc;
position: relative;
overflow: hidden;
}
.desc-text::after {
position: absolute; /*clean hack*/
left: 0;
top: 0;
right: 0;
bottom: 0;
content: var(--lorem-ipsum);
}
.desc-text.short::after {
content: var(--lorem-ipsum-short);
}
:root {
--lorem-ipsum: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
--lorem-ipsum-short: "Lorem";
--min-item-size: 100px;
--max-item-size: 150px;
}

<div class="list">
<div class="item">
<div class="thumb" style="width: 150px">1</div>
<div class="title">Short title</div>
<div class="info">Short info</div>
<div class="desc">
<div class="desc-text"></div>
</div>
</div>
<div class="item">
<div class="thumb" style="width: 150px">2</div>
<div class="title">Very long and detailed title</div>
<div class="info">Very long and detailed info</div>
<div class="desc">
<div class="desc-text"></div>
</div>
</div>
<div class="item">
<div class="thumb" style="width: 50px">3</div>
<div class="title">Short title</div>
<div class="info">Short info</div>
<div class="desc">
<div class="desc-text"></div>
</div>
</div>
<div class="item">
<div class="thumb" style="width: 50px">4</div>
<div class="title">Very long and detailed title</div>
<div class="info">Very long and detailed info</div>
<div class="desc">
<div class="desc-text"></div>
</div>
</div>
<div class="item" style="grid-template-columns: 22px auto 1fr 22px /*dirty hack*/">
<div class="thumb" style="width: 150px">5</div>
<div class="title">Short title</div>
<div class="info">Short info</div>
<div class="desc">
<div class="desc-text short"></div>
</div>
</div>
<div class="item">
<div class="thumb" style="width: 150px">6</div>
<div class="title">Very long and detailed title</div>
<div class="info">Very long and detailed info</div>
<div class="desc">
<div class="desc-text short"></div>
</div>
</div>
</div>
&#13;
我必须将描述放入相对定位的细胞内的绝对定位的容器中。这使得网格忽略了内容并且有点起作用,但是存在几个问题:
如果描述很短(参见第5项),我无法将信息块置于中心位置,因为1fr
用于描述,因此设置间距列(sl
和sr
)0
以外的任何其他内容都不起作用(样式属性形式的脏黑客不算数,它只是显示间距单元格的使用)。
它看起来不像纯CSS网格解决方案。我想知道是否有更多&#34; native&#34;指定细胞生长如何受内容影响的方法。
如果您想要&#34;干净利落的开始&#34;,您可以从CSS中删除position: absolute; /*clean hack*/
行,从HTML中删除style="grid-template-columns: 22px auto 1fr 22px /*dirty hack*/"
属性。一些定位CSS属性已经过时,但它们不再影响定位。如果你愿意,也可以删除它们。
清洁开始:
.list {
display: flex;
flex-wrap: wrap;
font: 12px/14px Verdana;
}
.item {
display: grid;
grid-template-areas:
"thumb thumb thumb thumb"
"sl title desc sr "
"sl info desc sr ";
grid-template-columns:
auto auto 1fr auto;
grid-template-rows:
auto auto 1fr;
min-width: calc(var(--min-item-size) + 4px);
max-width: calc(var(--max-item-size) + 4px);
border: dotted 2px darkblue;
margin: 4px 2px auto 2px;
}
.item > * {
min-width: 0;
min-height: 0;
border: dotted 1px dodgerblue;
margin: 1px;
}
.thumb {
grid-area: thumb;
margin: auto;
height: 100px;
background: linear-gradient(lightskyblue, deepskyblue);
}
.title {
grid-area: title;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.info {
grid-area: info;
overflow: hidden;
text-overflow: ellipsis;
}
.desc {
grid-area: desc;
overflow: hidden;
}
.desc-text::after {
content: var(--lorem-ipsum);
}
.desc-text.short::after {
content: var(--lorem-ipsum-short);
}
:root {
--lorem-ipsum: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
--lorem-ipsum-short: "Lorem";
--min-item-size: 100px;
--max-item-size: 150px;
}
&#13;
<div class="list">
<div class="item">
<div class="thumb" style="width: 150px">1</div>
<div class="title">Short title</div>
<div class="info">Short info</div>
<div class="desc">
<div class="desc-text"></div>
</div>
</div>
<div class="item">
<div class="thumb" style="width: 150px">2</div>
<div class="title">Very long and detailed title</div>
<div class="info">Very long and detailed info</div>
<div class="desc">
<div class="desc-text"></div>
</div>
</div>
<div class="item">
<div class="thumb" style="width: 50px">3</div>
<div class="title">Short title</div>
<div class="info">Short info</div>
<div class="desc">
<div class="desc-text"></div>
</div>
</div>
<div class="item">
<div class="thumb" style="width: 50px">4</div>
<div class="title">Very long and detailed title</div>
<div class="info">Very long and detailed info</div>
<div class="desc">
<div class="desc-text"></div>
</div>
</div>
<div class="item">
<div class="thumb" style="width: 150px">5</div>
<div class="title">Short title</div>
<div class="info">Short info</div>
<div class="desc">
<div class="desc-text short"></div>
</div>
</div>
<div class="item">
<div class="thumb" style="width: 150px">6</div>
<div class="title">Very long and detailed title</div>
<div class="info">Very long and detailed info</div>
<div class="desc">
<div class="desc-text short"></div>
</div>
</div>
</div>
&#13;
答案 0 :(得分:4)
这个问题有点难以理解,而且这个例子给出了回旋的事情。如果我没有直接回答你的问题,我很抱歉。
我认为您所要求的(根据您的示例及其要求)是:“您可以优先考虑哪些元素增长或缩小,而不管其内容如何?”
这个问题的答案是否定的,但这并不意味着你仍然只能使用CSS而无法达到你想要的效果。请参阅我的以下片段,了解我如何处理/解决问题。
请注意:我认为你通过尝试使用网格规则甚至弯曲来解决问题,因为我遇到了与尝试使用flex解决此问题时遇到的相同问题。
.list {
display: flex;
flex-wrap: wrap;
font: 12px/14px Verdana;
}
.item {
min-width: 100px;
max-width: 150px;
border: solid 1px black;
float: left;
margin: 10px;
}
.thumb {
margin: auto;
height: 100px;
background: linear-gradient(lightskyblue, deepskyblue);
}
.center {
float: left;
left: 50%;
transform: translateX(-50%);
position: relative;
max-width: 150px;
}
.meta-wrap {
float: left;
max-width: 100%;
}
.desc-wrap {
overflow: hidden;
/*
Make sure this doesn't grow out the rest of the item.
This can be a static height because if the info is long enough to grow the height
then the description wouldn't be seen anyway.
*/
max-height: 27px;
}
.title,
.info,
.text {
overflow: hidden;
text-overflow: ellipsis;
}
.title {
background: orange;
white-space: nowrap;
}
.info {
background: tomato;
}
.text {
background: aqua;
}
<div class="list">
<div class="item">
<div class="thumb" style="width: 150px">1</div>
<div class="center">
<div class="meta-wrap">
<div class="title">Short</div>
<div class="info">Short</div>
</div>
<div class="desc-wrap">
<div class="text">Lorem ipsum text and stuff goes here, cool!</div>
</div>
</div>
</div>
<div class="item">
<div class="thumb" style="width: 150px">2</div>
<div class="center">
<div class="meta-wrap">
<div class="title">Long title goes here that should cut off</div>
<div class="info">long description goes here</div>
</div>
<div class="desc-wrap">
<div class="text">Lorem ipsum text and stuff goes here, cool!</div>
</div>
</div>
</div>
<div class="item">
<div class="thumb" style="width: 50px">3</div>
<div class="center">
<div class="meta-wrap">
<div class="title">Short</div>
<div class="info">Short</div>
</div>
<div class="desc-wrap">
<div class="text">Lorem!</div>
</div>
</div>
</div>
<div class="item">
<div class="thumb" style="width: 50px">4</div>
<div class="center">
<div class="meta-wrap">
<div class="title">Long title goes here that should cut off</div>
<div class="info">long description goes here</div>
</div>
<div class="desc-wrap">
<div class="text">Lorem ipsum text and stuff goes here, cool!</div>
</div>
</div>
</div>
<div class="item">
<div class="thumb" style="width: 150px">5</div>
<div class="center">
<div class="meta-wrap">
<div class="title">Short</div>
<div class="info">Short</div>
</div>
<div class="desc-wrap">
<div class="text">Lorem!</div>
</div>
</div>
</div>
<div class="item">
<div class="thumb" style="width: 150px">6</div>
<div class="center">
<div class="meta-wrap">
<div class="title">Long title goes here that should cut off</div>
<div class="info">long description goes here</div>
</div>
<div class="desc-wrap">
<div class="text"></div>
</div>
</div>
</div>
</div>
答案 1 :(得分:4)
我认为我有一个很好的解决方案。
唯一的缺点是我需要在max-width
和.title
上设置.info
。
你的第一个问题是分配水平空间。您希望第二列为标题提供尽可能多的空间。但不超过所包含元素的自然宽度。因此,我们需要与内容相关的内容,以及 max-content 的最大宽度。
然后我们希望第三列( desc )取任何左边的宽度(如果有的话),也不要超过它可以填充的内容。这可以通过 min-max(0,max-content)
来实现最后,我们希望任何左侧空间都在第1和第4列, 1fr 。
这种安排有效,因为自由空间分为2轮,一轮用于minmax函数,第二轮用于 fr 元素。
此设置存在的问题是标题的 max-content 可能会溢出容器。我们无法在网格本身上解决(我认为)这个问题,我们需要在元素本身上设置最大宽度。
首先,你可以认为这里的minmax功能可以提供帮助。不,它不能。您可以看到解释here
另一个问题是处理 desc 的高度。由于它跨越2行,但两者都必须对内容有意义,我们在这里运气不好。
幸运的是,你已经有了一个嵌套结构。使容器溢出:隐藏并限制内部元素高度将起到作用。内部元素的内容没有足够的高度,但由于 overflow:none 而显示它们。容器适合网格的高度,并剪切溢出的内容
:root {
--lorem-ipsum: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
--lorem-ipsum-short: "Lorem";
--min-item-size: 100px;
--max-item-size: 150px;
--max-item-desc-height: 32px; /* added */
}
.list {
display: flex;
flex-wrap: wrap;
font: 12px/14px Verdana;
}
.item {
display: grid;
grid-template-areas:
"thumb thumb thumb thumb"
"sl title desc sr "
"sl info desc sr ";
grid-template-columns: 1fr max-content minmax(0px, max-content) 1fr; /* changed */
grid-template-rows: auto auto 1fr;
min-width: calc(var(--min-item-size) + 4px);
max-width: calc(var(--max-item-size) + 4px);
border: dotted 2px darkblue;
margin: 4px 2px auto 2px;
}
.item > * {
min-width: 0;
min-height: 0;
border: dotted 1px dodgerblue;
margin: 1px;
}
.thumb {
grid-area: thumb;
margin: auto;
height: 100px;
background: linear-gradient(lightskyblue, deepskyblue);
}
.title {
grid-area: title;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
max-width: var(--max-item-size); /* added */
}
.info {
grid-area: info;
overflow: hidden;
text-overflow: ellipsis;
max-width: var(--max-item-size); /* added */
}
.desc {
grid-area: desc;
overflow: hidden;
max-height: var(--max-item-desc-height); /* added */
}
.desc-text::after {
content: var(--lorem-ipsum);
}
.desc-text.short::after {
content: var(--lorem-ipsum-short);
}
&#13;
<div class="list">
<div class="item">
<div class="thumb" style="width: 150px">1</div>
<div class="title">Short title</div>
<div class="info">Short info</div>
<div class="desc">
<div class="desc-text"></div>
</div>
</div>
<div class="item">
<div class="thumb" style="width: 150px">2</div>
<div class="title">Very long and detailed title</div>
<div class="info">Very long and detailed info</div>
<div class="desc">
<div class="desc-text"></div>
</div>
</div>
<div class="item">
<div class="thumb" style="width: 50px">3</div>
<div class="title">Short title</div>
<div class="info">Short info</div>
<div class="desc">
<div class="desc-text"></div>
</div>
</div>
<div class="item">
<div class="thumb" style="width: 50px">4</div>
<div class="title">Very long and detailed title</div>
<div class="info">Very long and detailed info</div>
<div class="desc">
<div class="desc-text"></div>
</div>
</div>
<div class="item">
<div class="thumb" style="width: 150px">5</div>
<div class="title">Short title</div>
<div class="info">Short info</div>
<div class="desc">
<div class="desc-text short"></div>
</div>
</div>
<div class="item">
<div class="thumb" style="width: 150px">6</div>
<div class="title">Very long and detailed title</div>
<div class="info">Very long and detailed info</div>
<div class="desc">
<div class="desc-text short"></div>
</div>
</div>
</div>
&#13;