css揭秘 7 结构与布局
36 自适应内部元素
众所周知,如果不给元素指定一个具体的 height,它就会自动适应其
内容的高度。假如我们希望 width 也具有类似的行为,该怎么做呢?
<p>Some text [...]</p>
<figure>
<img src="adamcatlace.jpg" />
<figcaption>
The great Sir Adam Catlace was named after
Countess Ada Lovelace, the first programmer.
</figcaption>
</figure>
<p>More text [...].</p>
我们希望figure的宽度和图片一样保持自适应,。把图1变成图2的效果
图1
图2
你可能会想到的方法:
- 让figure元素浮动
- 对figure应用display:inline-block
- 给figure设置一个固定的宽度
很可惜这些方法都差强人意,有没有一种合适的 CSS 技巧可以解决这个问题?我们是不是应该放弃这条路,改用脚本来动态地为每个 figure 设置宽度?
解决方法
CSS 内部与外部尺寸模型(第三版)(http://w3.org/TR/css3-sizing)是
一个相对较新的规范,它为 width 和 height 属性定义了一些新的关键字。
其中min-content,将解析为这个容器内部最大的不可断行元素的宽度(即最宽的单词、图片或具有固定宽度的盒元素),这正是我们所希望的。
figure {
width: min-content;
margin: auto;
}
给旧版的浏览器提供一个平稳的回退样式
figure {
max-width: 300px;
max-width: min-content;
margin: auto;
}
figure > img { max-width: inherit; }
37 精确控制表格列宽
尽管多年以前我们就不再使用表格来完成页面布局了,但表格在现代网
站中仍然有其不可替代的位置。尽管有时候它们看起
来很方便,但对于不固定的内容来说,它们的布局其实是很难预测的。这是
因为列宽根据其内容进行调整,即使我们显式地指定了 width,也只能起到
类似提示的作用。
解决方案
解决方案来自于 CSS 2.1 中一个鲜为人知的属性,叫作 table-layout。
它的默认值是 auto,其行为模式被称作自动表格布局算法,也就是我们最为熟悉的表格布局行为(就像图 7-5 那样)。不过,它还接受另外一个值fixed,这个值的行为要明显可控一些。
table {
table-layout: fixed;
width: 100%;
}
例如:
.users {
table-layout: fixed;
width: 100%;
white-space: nowrap;
}
.users td {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* Column widths are based on these cells */
.row-ID {
width: 10%;
}
.row-name {
width: 40%;
}
.row-job {
width: 30%;
}
.row-email {
width: 20%;
}
<table class="users" border="1">
<thead>
<tr>
<th class="row-1 row-ID">ID</th>
<th class="row-2 row-name">Name</th>
<th class="row-3 row-job">Job</th>
<th class="row-4 row-email">Email</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>0001</td>
<td>Johnny Five</td>
<td>Robotin'</td>
<td>need@input.com</td>
</tr>
<tr>
<td>0002</td>
<td>Super Superlonglastnamesmith</td>
<td>Doin' stuff</td>
<td>doing@stuff.com</td>
</tr>
</tbody>
</table>
38 根据兄弟元素的数量来设置样式
在某些场景下,我们需要根据兄弟元素的总数来为它们设置样式。最常
见的场景就是,当一个列表不断延长时,通过隐藏控件或压缩控件等方式来
节省屏幕空间,以此提升用户体验。
解决方案
思路:
:only-child
等 效 于 :first-child:last-child
, 道理很简单:如果第一项同时也是最后一项,那从逻辑上来说它就是唯一的那一项。
你能猜到li:first-child:nth-last-child(4)
会命中哪些元素吗?
一个正好有四个列表项的列表中的第一个列表项
- 选中有4个li的列表的第一项
.my-ul li:first-child:nth-last-child(4) {
background: #fce7f8;
}
- 选中有4个li的列表的所有项
.my-ul1 li:first-child:nth-last-child(4),
.my-ul1 li:first-child:nth-last-child(4) ~ li {
background: #fce7f8;
}
- 当列表至少包含四项时,命中所有列表项
.my-ul2 li:first-child:nth-last-child(n + 4),
.my-ul2 li:first-child:nth-last-child(n + 4) ~ li {
background: #fce7f8;
}
- 当列表最多包含四项时,命中所有列表项
.my-ul3 li:first-child:nth-last-child(-n + 4),
.my-ul3 li:first-child:nth-last-child(-n + 4) ~ li {
background: #fce7f8;
}
- 当列表包含2~6项时,命中所有列表项
.my-ul4 li:first-child:nth-last-child(n + 2):nth-last-child(-n + 6),
.my-ul4 li:first-child:nth-last-child(n + 2):nth-last-child(-n + 6) ~ li {
background: #fce7f8;
}