极致CSS(5)-替换元素与伪元素(伪类)

660 阅读5分钟

网页中常用的元素, 首先是div, 基本上单独使用它就可以完成整个页面, 有些时候对于简短的文本可能会用到span, 不过我更喜欢用简短的i和em. 其他元素多数是有一些特定的功能和含义, 其中使用最多的估计就是img. 对于在网页中加入图片, 一般就是img标签和CSS的背景图片background-image两种方式. 使用伪元素的content也可以引入图片, 但是不好控制样式, 所以很难实际应用. 一般来说, 重要的内容图片使用img标签, 其他都可以使用背景图片. 这样页面结构比较简单清晰, 结构和样式分离, 也不用在HTML里处理图片链接.

img被称为替换元素, 也就是说它的显示样式很大程度上是由链接的图片本身控制的, 图片有原始的宽高尺寸, 如果不在代码里进行设置, 图片就将按原始尺寸显示, 也就是替换元素的width和height默认值为auto. 如果设置了其中一个值, 另一个将会按照图片的原始宽高比缩放. 如果两个都设置, 就按照设置的值显示, 如果设置的宽高和图片的原始宽高比不一致, 图片就会拉伸变形.

以前对于图片除了设置宽高也没法作更多控制, 不过现在CSS中加入了object-fit, object-position等属性, 可以像调整背景图片一样调整图片的渲染方式. 如果不需要考虑旧浏览器, 又有合适的场景可以尝试一下, 一般是可以减少多包裹的一层div标签.

img的src属性是图片引用的链接地址. 也可以使用base64或者svg编码. 格式方面多数浏览器都支持jpg和png, gif, 现代的格式webp等压缩比更高, 但是需要较新的浏览器才能支持.

替换元素的display属性默认是inline或inline-block, 也就是会和文本在同行显示. 此时由于vertical-align属性默认值是baseline, 图片底部会和文字的baseline对齐, 导致底部留有空隙, 此时可以调整vertical-align属性为top, bottom, 或middle. 如果不需要和文字同行, 也可以直接设置display属性为block, 消除空隙. 因为即使没有文字, 由于line-height默认值normal和行框占位空字符的存在, 也会在图片下方留下空隙.

多数元素可以加伪元素, 主要是before和after元素, first-line和first-letter只有在元素为dispaly: block(或'inline-block', 'table-cell' 或者 'table-caption')时才能生效, 而且使用场景也有限, 只能在碰巧需要为首行首字符设置样式时减少一个标签和选择器. 实际使用时, 装饰性和附加的内容都可以用before/after元素生成. 不用添加标签, 简化页面结构, 但是伪元素生成的内容无法选中, 所以重要的内容要注意. 通常在HTML中只包含页面的主体结构, 边角细节的装饰说明都可以用伪元素在CSS中完成, 这样页面结构清晰, 便于修改维护, 也方便js操作页面.

伪元素首先要有content属性, 否则不会显示, content可以是文本, 也可以用attr引用元素的属性, 还可以用url引用图片, 不过因为不好控制样式, 多数时候是用content: ''构造一个没有内容的伪元素, 然后在用CSS添加背景图片装饰. 默认伪元素也是display: inline, 所以设置尺寸的话要先改成block或inline-block.

和伪元素有点类似的是伪类, 其实最早只有伪类, 用单:写法, 后来认为伪元素应该区分一下, 用::写法, 但是一般浏览器都会兼容两种写法. 伪类用的比较多的是nth-of-type, 当不添加类名时使用数字在页面中选择元素. first-child, last-child, only-child, nth-child等对页面结构要求较高, 必须是满足条件的子元素, 所以用起来也比较受局限. 另外一个功能性的伪类是hover, 用于模拟简单交互, 类似功能的focus是全页唯一的, active不能保持效果, 只有hover在PC端和移动端都有良好效果. 不过还是由于只能作用于同一元素, 要通过操作改变其他元素的样式还是要借助js. empty用于选择空元素, 可以用于模拟placeholder, checked选择选中的选项, 可以不用js实现tab切换, not可以对选择条件取反.

替换元素和伪元素的相关之处在于, 他们都属于生成内容. 网页的基础是文字和容器, 其实也都是按照规则生成的, 但是对于这些基础内容, 已经建立了一套规范, 而生成内容基本上都有自己的规范. 比如像iframe, video这些元素, 在没有设置样式的时候, 浏览器会给一个默认宽高300*150, 而且iframe也无法通过内部内容自动设置高度, 不过现在iframe也用的不多了.