交互式的图片对比控件
想要实现的效果是两张图片堆叠摆放,然后可以通过交互调节两张图片的显示范围,来达到对比的效果。书中第一种方案是利用元素的resize
属性,在其中某一张图片包一层用来resize
的元素控制显示大小,最终达到目的。代码示例如下:
|
|
|
|
最后的效果并不太好,原生调节柄和自定义调节柄交叉在一起,包裹元素的width:50%
和max-width:100%
导致chrome下调节显示范围变成了50% - 100%,并不能任意调节了。
第二种方法利用了html原生的滑块控件,将滑块的值的利用js反映到图片的包裹元素上,这个比较常见易行。
自适应内部元素
我们在开发中可以很轻易做到让内部元素适应外部元素的大小,但是让外部元素适应内部元素的内容大小,尤其是内部元素有多个的情况,除了很不优雅的float
和inline-block
方案,书中给我们提供了min-content
这种方案。
min-content
这个关键字将解析为这个容器内部最大的不可断行元素的宽度(即最宽的单词、图片或具有固定宽度的盒元素)。
|
|
|
|
以上为不支持的浏览器添加了平稳退化,对于现代浏览器来说,后一条max-width
声明会覆盖前一条。如果figure
的尺寸是由内部因素决定时,第二条规则中的max-width: inherit
就不会生效了。
精确控制表格列宽
table
元素有一个table-layout
属性,它的默认值是 auto
,其行为模式被称作自动表格布局算法,也就是我们最为熟悉的表格布局行为。不过,它还接受另外一个值fixed
,这样的话表格就不会自动计算各自的列宽了。
根据兄弟元素的数量来设置样式
这一节感觉很有用,采用摘抄的方式记录如下:
在某些场景下,我们需要根据兄弟元素的总数来为它们设置样式。例如仅当列表项的总数为 4 时才对这些列表项设置样式。我们可以用li:nth-child(4)
来选中列表的第四个列表项,但这并不是我们想要的;我们需要在列表项的总数为 4 时选中每一个列表项。
对于只有一个列表项的特殊场景来说,解决方案显然就是:onlychild
,实际上,:only-child
等效于:first-child:last-child
,道理很简单:如果第一项同时也是最后一项,那从逻辑上来说它就是唯一的那一项。:last-child
其实也是一个快捷写法,相当于:nth-last-child(1)
。
这个 1 其实是一个参数,我们可以根据需要来修改这个值。你能猜到li:first-child:nth-last-child(4)
会命中哪些元素吗?如果从:onlychild
的例子举一反三,认定这个选择符会在列表项总数为 4 时命中所有列表项,那你可就太过乐观了。我们还没达到那个效果,但已经处在正确的方向上了。让我们把这两个伪类分开来想一想:我们在找一个同时匹配:first-child
和nth-last-child(4)
的元素。因此,这个元素需要是父元素的第一个子元素,同时还需要是从后往前数的第四个子元素。有哪个元素可以满足这个条件呢?
答案就是,一个正好有四个列表项的列表中的第一个列表项。(参见图7-9)这并不完全是我们想要的结果,但已经非常接近了。我们现在已经找到一种命中特定数量列表项中第一项的方法,接下来就可以用兄弟选择符(~)来命中它之后的所有兄弟元素:相当于在这个列表正好包含四个列表项时,命中它的每一项,而这正是我们一直想要达成的目标:
|
|
在实际的应用场景中,我们期望匹配元素的条件往往并不是列表项的具体数量,而是一个数量范围。:nth-child()
选择符在这方面非常好用,我们可以用它来命中一个范围,比如“选中第 4 项之后的所有项”这样的需求就完全不在话下。它的参数不仅可以是简单的数字,也可以是像 an+b 这样的表达式(比如:nth-child(2n+1)
)。这里的 n 表示一个变量,理论上的范围是 0 到 +∞(在实际情况下,由于页面中元素的数量本来就是有限的,超过某个特定数量的值实际上也没有元素可选了)。如果使用 n+b 这种形式的表达式(此时相当于 a 的取值为1),那么不论 n 如何取值,这个表达式都无法产生一个小于 b 的值。因此,n+b 这种形式的表达式可以选中从第 b 个开始的所有子元素。举例来说,:nth-child(n+4)
将会选中除了第一、二、三个子元素之外的所有子元素(参见图7-10)。
利用这个技巧,我们可以在列表项的总数是 4 或更多时选中所有列表项(参见图7-11)。在这种情况下,我们可以把表达式 n+4 传给:nth-lastchild()
:
|
|
同理,-n+b 这种形式的表达式可以选中开头的 b 个元素。因此,仅当列表中有 4 个或更少的列表项时(参见图7-12),要选中所有列表项可以这样写:
|
|
当然,我们还可以把这两种技巧组合起来使用,不过代码也会变得更加复杂。假设我们希望在列表包含 2 ~ 6 个列表项时命中所有的列表项,可以这样写:
|
|
是不是厉害了呢!但我转念又有一个问题,其实这个效果利用js动态添加样式可以轻轻松松做出,综合考虑学习和开发成本、性能等因素,我们用css来做这个效果,除了把样式单独交给css,还有没有其他意义了呢?(●’◡’●)