<!-- 《CSS世界》 张鑫旭著 -->

替换元素

根据是否具有可替换内容,我们可以把元素分为替换元素和非替换元素。

<img>、<object>、<video>、<iframe>或表单元素<textarea>和<input>都是典型的替换元素。

替换元素除了内容可替换这一特性之外,还有以下一些特性:

(1)内容的外观不受页面上的CSS的影响。用专业的话讲就是样式表现在CSS作用域之外。例如:直接 input[type='checkbox'] {} 无法更改内间距、背景色等样式,需要用浏览器自身暴露的一些样式接口,例如::-ms-check {} 可以更改高版本IE浏览器下单复选框的内间距、背景色等样式

(2)有自己的尺寸。在WEB中,很多替换元素在没有明确尺寸设定的情况下,其默认的尺寸(不包括边框)是300像素 × 150像素,如<video>、<iframe>或者<canvas>等,也有少部分替换元素为0像素,如<img>图片,而表单元素的替换元素尺寸则和浏览器有关,没有明显的规律。

(3)在很多CSS属性上都有自己的一套表现规则。比较有代表性的是vertical-align属性,对于替换元素和非替换元素,vertical-align属性值的解释是不一样的。比方说vertical-align的默认值的baseline,很简单的属性值,基线之意,被定义为字符x的下边缘,在西方语言体系里近乎常识,几乎无人不知,但是到了替换元素那里就不适用了。为什么呢?因为替换元素的内容往往不可能含有字符x,于是替换元素的基线就被硬生生定义成了元素的下边缘。

替换元素的默认display值

替换元素都是内联水平元素,但是替换元素的display值却是不一样的,并且在不同浏览器的值也是不一样的,但是这并不会影响替换元素的尺寸计算规则,所以深究替换元素的display值是没有意义的。

<input type="button" value="按钮">
<button type="button">按钮</button>

<input>和<button>按钮的区别在于两种按钮默认的 white-space 值不一样,前者是 pre,后者是 normal,所表示出来的差异就是:当按钮文字足够多的时候,<input> 按钮不会自动换行,<button> 按钮会自动换行。

替换元素的尺寸计算规则

作者将替换元素的尺寸从内而外分为3类:固有尺寸、HTML尺寸和CSS尺寸。

(1)固有尺寸指的是替换内容原本的尺寸。例如:图片、视频作为一个独立文件存在时,都是有着自己的宽度和高度的。这个宽度和高度的大小就是这里的“固有尺寸”。对于表单替换元素,“固有尺寸”可以理解为“不加修饰的默认尺寸”。

(2)HTML 尺寸只能通过 HTML 原生属性改变,包括<img>的width和height属性、<input>的size属性,<textarea>的cols和rows属性等。

(3)CSS 尺寸特指可以通过 CSS 的width和height或者max-width/min-width和max-height/min-height设置的尺寸,对应盒尺寸中的content box。

这3层结构的计算规则如下:

  • CSS 尺寸 覆盖 HTML 尺寸, HTML 尺寸覆盖固有尺寸
  • 如果固有尺寸含有固有的宽高比例,同时仅设置了宽度或者仅设置了高度,则元素按照固有的宽高比例显示。
  • 如果三种尺寸都没有,则最终宽度表现为300像素,高度表现为150像素
  • <img>是这其中的意外,单看规则,一个没有替换内容也没有尺寸设定的裸露的<img>元素,应该是300像素 × 150像素,结果不仅不是这个尺寸,而且各个浏览器下的尺寸还不一样。IE浏览器下是28 × 30,Chrome浏览器下是0 × 0,Firefox浏览器下是0 × 22.。尺寸不一样还不打紧,因为我们都会设置尺寸,但是关键是表现型也不一样。先看下面的例子:

web开发的时候,为了提高加载性能以及节约带宽费用,首屏一下的图片就会通过滚屏加载的方式异步加载,然后这个即将异步加载的图片为了布局稳健、体验良好,往往会使用一张透明的图片占位,例如:<img src="transparent.png">

实际上这个透明的占位图片也是多余的资源,我们可以直接:<img>,然后配合CSS实现一样的效果:

img { visibility: hidden; }
img[src] { visibility: visible; }

这里的<img>直接没有src属性,因为src=""在很多浏览器下依然会有请求,而且请求的是当前页面数据。但图片的src属性缺省的时候,图片不会有任何请求,是最高效的实现方式。

但是这里存在一个问题,Firefox浏览器下,src缺省的<img>不是替换元素,而是一个普通的内联元素,所以使用的不是替换元素的尺寸规则,而是类似<span>的内联元素尺寸规则,宽高会无效。这时就要设置display: inline-block后再设置宽高了,既对Firefox浏览器有效,又不会影响其他浏览器的图片表现。

HTML 尺寸和 CSS 尺寸是怎么影响图片的尺寸的呢?

尺寸变化的本质不是改变固有尺寸,而是采用了填充作为适配 HTML 尺寸和 CSS 尺寸的方式。在 CSS3 新世界中,<img>和其他一些替换元素的替换内容的适配方式可以通过object-fit属性(IE全部不兼容)修改,例如:<img>默认声明是:object-fit: fill,如果我们设置object-fit: none,则我们图片的尺寸就完全不受控制(据笔者测试,是保持比例不变,不缩放,但是尺寸是受css属性width和height限制的);如果我们设置object-fit: contain,则图片会以保持比例,并尽可能利用 HTML 尺寸但又不会超出的方式显示。

《CSS世界》读书笔记(七)的更多相关文章

  1. java内存区域——深入理解JVM读书笔记

    本内容由<深入理解java虚拟机>的部分读书笔记整理而成,本读者计划连载. 通过如下图和文字介绍来了解几个运行时数据区的概念. 方法区:它是各个线程共享的区域,用于内存已被VM加载的类信息 ...

  2. MDX Step by Step 读书笔记(七) - Performing Aggregation 聚合函数之 Max, Min, Count , DistinctCount 以及其它 TopCount, Generate

    MDX 中最大值和最小值 MDX 中最大值和最小值函数的语法和之前看到的 Sum 以及 Aggregate 等聚合函数基本上是一样的: Max( {Set} [, Expression]) Min( ...

  3. 《深入理解java虚拟机》读书笔记七——第八章

    第八章 虚拟机字节码执行引擎 1.运行时栈帧结构 概述: 栈帧是用于支持虚拟机进行方法调用的和方法执行的数据结构,他是虚拟机运行时数据区中的虚拟机栈的栈元素,栈帧存储了方法的局部变量,操作数栈,动态连 ...

  4. 《深入理解Java虚拟机》读书笔记七

    第八章 虚拟机字节码执行引擎 1.运行时栈帧结构 概述: 栈帧是用于支持虚拟机进行方法调用的和方法执行的数据结构,他是虚拟机运行时数据区中的虚拟机栈的栈元素,栈帧存储了方法的局部变量,操作数栈,动态连 ...

  5. 深入理解linux网络技术内幕读书笔记(七)--组件初始化的内核基础架构

    Table of Contents 1 引导期间的内核选项 2 注册关键字 3 模块初始化代码 引导期间的内核选项 linux运行用户把内核配置选项传给引导记录,然后引导记录再把选项传给内核. 在引导 ...

  6. 《CLR.via.C#第三版》第二部分第13章节 接口 读书笔记(七)

    这章的书写感觉很普通,是些基础的认知知识. 其中一点的重要认知,泛型接口的好处(其实也是使用泛型的好处之一):编译时类型安全&处理值类型时减少装箱. 再说点书上没有的.本来这些知识我打算另外分 ...

  7. 【锋利的Jquery】读书笔记七

    第七章  jquery插件 管理cookie的插件--cookie jquery插件太多没什么好讲的,百度太多 说以下 cookie插件 <!DOCTYPE html> <html& ...

  8. 00-深入理解C#读书笔记说明

    带着问题去看书 尝试着,根据每一小节,先列出大纲.然后根据自己原先的认知和理解以及不理解,对每一个小的chapter,我会先自我提问,带着问题去阅读,然后把我的理解以及不理解记录下来,对于错误的地方做 ...

  9. MDX Step by Step 读书笔记(七) - Performing Aggregation 聚合函数之 Sum, Aggregate, Avg

    开篇介绍 SSAS 分析服务中记录了大量的聚合值,这些聚合值在 Cube 中实际上指的就是度量值.一个给定的度量值可能聚合了来自事实表中上千上万甚至百万条数据,因此在设计阶段我们所能看到的度量实际上就 ...

  10. Android驱动开发读书笔记七

    第七章 (一)创建设备文件 1.使用cdev_init函数初始化cdec 描述设备文件需要一个cdev结构体,代码如下: struct cdev{ struct kobject kobj; struc ...

随机推荐

  1. jmeter3.0下载及安装

    http://blog.csdn.net/shizhiailian/article/details/52443169 下载: https://archive.apache.org/dist/jmete ...

  2. linq2db sqlite应用

    使用linq2db sqlite 的时候,找不到增加,删除的操作,原来是要引入一个新的命名空间LinqTODB. 1 using LinqToDB; 插入: 1 User uNew = new Use ...

  3. Javascript中Promise对象的实现

    http://segmentfault.com/a/1190000000684654 http://www.infoq.com/cn/news/2011/09/js-promise/

  4. 用google map实现周边搜索功能

    项目要实现根据经纬度获取附近的建筑,由于项目在海外运营,谷歌地图首当其冲. 首先说明的是,该功能需要在服务端实现,也就是安卓的SDK不适用. api文档地址: https://developers.g ...

  5. [ICLR'17] DEEPCODER: LEARNING TO WRITE PROGRAMS

    DEEPCODER: LEARNING TO WRITE PROGRAMS Basic Information Authors: Matej Balog, Alexander L. Gaunt, Ma ...

  6. 四、Sql Server 基础培训《进度4-插入数据(实际操作)》

    知识点: 假设有订单表 CREATE TABLE Order ( ID int identity(1,1) not null primary key, --内码 BillNo varchar(100) ...

  7. Mysql命令行tab自动补全方法

    在mysql命令行有时为了方便想要按tbl键自动补全命令,以便节约时间. 具体方法如下: 第一步:修改my.cnf vi mysql/etc/my.cnf 将下图红框的代码注释,修改成如下代码: #d ...

  8. PHP异步请求之fsockopen()方法详解

    正常情况下,PHP执行的都是同步请求,代码自上而下依次执行,但有些场景如发送邮件.执行耗时任务等操作时就不适用于同步请求,只能使用异步处理请求. 场景要求: 客户端调用服务器a.php接口,需要执行一 ...

  9. Nginx配置跨域请求 CORS

    当出现403跨域错误的时候 No 'Access-Control-Allow-Origin' header is present on the requested resource,需要给Nginx服 ...

  10. nginx配置-为没有后缀的文件(实际上是有html文件)以html形式打开

    location ~ index.php@ { add_header content-type "text/html"; }