CSS进阶 - 掌握HTML(5)和CSS(3)语言核心

238 阅读27分钟

1. HTML语义: 学会如何写出更优的html

超文本标记语言(英语:HyperText Markup Language,简称:HTML)是一种用于创建网页的标准标记语言。

1.1 常用的HTML标签汇总

1.1.1 HTML4
  • 基本文档:htmlheadbody...
  • 基本标签: h1-h6pbrhr...
  • 文本格式化:strongbemismallstrongdelsubsup...
  • 链接: alink
  • 图片: imgmaparea
  • 区块: divspan
  • 三大列表: ulliollidldtdd
  • 表格:tablecaptionthtrtdtheadtbodytfoot
  • 框架:iframe
  • 表单: forminputselectoptiontextareabuttonlabel
  • 实体: &lt&gt&copy&nbsp...
1.1.2 HTML5
  • 图形新元素:canvas
  • 新多媒体元素: audiovideosourceembedtrack
  • 新表单元素: deatalistkeygenoutput
  • 新的语义和结构元素: articleasidebdicommanddetailsdialogsummaryfigurefigcaptionfooterheadermarkmeternavprogressrubyrtrpsectiontimewbr

怎么知道我的标签用的对不对?

可以尝试去掉CSS,只将HTML代码显示在页面中,看看你的内容结构是否依然清晰、好看。

你还可以把代码上传到 W3C 标记验证服务 ,它会帮你验证你的代码是否有效或合理。

1.2 语义化含义和好处

语义化指对文本内容的结构化(内容语义化),选择合乎语义的标签(代码语义化),便于开发者阅读,维护和写出更优雅的代码的同时,让浏览器的爬虫和辅助技术更好的解析 (通俗理解: 用正确的标签做正确的事)

通过使用恰当语义的HTML标签,让页面具有良好的结构与含义,可以有效提高:

  • 可访问性:帮助辅助技术更好的阅读和转译你的网页,利于无障碍阅读;
  • 可检索性:有了良好的结构和语义,可以提高搜索引擎的有效爬取,提高网站流量;
  • 国际化:全球只有13%的人口是英语母语使用者,因此通用的语义化标签可以让各国开发者更容易弄懂你网页的结构;
  • 互用性:减少网页间的差异性,帮助其他开发者了解你网页的结构,方便后期开发和维护;

语义化的好处:

  • 利于SEO优化(也就是搜索引擎的抓取,搜索引擎的爬虫也依赖于标记来确定上下文和各个关键字的权重);
  • 在样式丢失的时候,还是可以比较好的呈现结构;
  • 更好的支持各种终端,例如无障碍阅读和有声小说等;
  • 利于团队开发和维护,W3C给我们定了一个标准,那么团队中都遵循这个标准,那么代码的差异就会缩小,在开发和维护的时候就可以提高效率;

1.3 学会如何写出更优的html

  • 尽可能少的使用无意义的标签,如 divspan
  • 语义不明显时,如既可以使用div也可以使用p时,尽量用p,因为p在默认情况下有上下间距,对兼容特殊终端有利
  • 不推荐使用 bfontucenter 等纯样式标签,推荐使用 CSS 控制样式
  • 需要强调的文本,可以使用 strongem 标签,strong 默认样式是加粗显示,em 默认样式是斜体显示
  • 使用表格时,标题用 caption,表头用 thead,主体部分用 tbody 包围,尾部用 tfoot 包围。表头和一般单元格要区分开,表头用 th,单元格用 td
  • 表单域要用 fieldset 标签包起来,并用 legend 标签说明表单的用途(可理解为表单标题)
1.3.1 结构搭建
  • 采用HTML5标准时开头应该加上<!DOCTYPE html>;
  • 应在head标签中引入CSS文件,这样浏览器就可以在输出HTML之前获取CSS信息;
  • body标签的末尾引入js文件,这样可以在页面显示之后再编译js文件,以加快页面读取速度,同时有助于js对页面中的元素进行操作
  • 对元素的操作应添加在js代码中,而不要在html中添加,后期难以维护;
1.3.2 代码校验

虽然现在浏览器的容错力越来越高,但这不能成为代码粗制滥造的借口。不管什么时候,正确的HTML代码都更易于debug、体积更小、运行更快、渲染时消耗资源更少,而错误的HTML代码只会使页面的最终设计难以实现想要的效果。特别是在使用模板来开发时,正确有效的HTML就更显得尤为重要,也许一个正常运行的模块会在其他环境中出现可怕的异常。

  • 在项目中加入校验过程:可以在代码编辑器中使用HTMLHint、SublimeLinter这类代码校验插件,也可以在build的时候使用HTMLHint with Grunt这类校验工具,还可以通过W3C HTML validator等网站来在线检测代码;
  • 尽量采用HTML5标准;
  • 确保正确的HTML层级:嵌套元素时确保元素首尾完整,在一个有大量内容的元素的结束标签后应添加注释,这样有助于后期debug,特别是在使用模板的时候;
  • 在所有不能自动结束的元素末尾添加结束标签;
  • li结束标签不是必须的,所以有些人认为可以不写li,这可以接受,但是ulol标签一定要加;
  • videoaudio元素必须要有结束标签;
1.3.3 良好的代码排版
  • 在项目中保持统一的HTML代码风格;
  • 使用代码编辑器来帮助你自动排版,比如在Sublime Text中可以使用自带的Reindent,也可以找一些自动排版插件来帮助你。同样也可以使用一些在线工具比如;CSS Beautifier 和 JS Beautifier;
  • 在HTML中用缩进来分层更易于阅读,如果代码编辑器没有自动缩进功能的话可以自行修改相应的设置。当你发现你的HTML层级过深的时候,那就表示你需要重构一下你的HTML了;
  • 用更直接易读的方式写HTML代码,注意标签的相互嵌套关系;
  • 元素要按常规放置,比如footer元素最好是放在HTML页面的底部,虽然理论上把它放在任何地方都可以正常运行;
  • 统一所有引号的使用规则,不要这里用双引号,那里又单引号;
  • 使用小写字母来写标签和属性,大写字母很不易读;
1.3.4 语义化设计
  • 标题使用h1(h2h3、...) ,列表使用ul或者ol
  • 在适当的地方使用HTML5的新元素,比如headerfooternavaside
  • 正文中的文本内容要用p标签,内容的结构化可以使用HTML5的新元素(或者div);
  • 修改文字样式时,emstrong要比ib更好些,因为前者语义更加明显;
  • form中要包含label元素,input要有typeplaceholder以及其他必要的属性,即使值为空都可以;
  • 尽量减少使用无意义标签,例如spandiv
  • 尽量不使用标签本身的css属性,例如bfonts等标签,如果需要这些样式,那么使用css样式来进行添加;
  • 在需要强调的部分,使用strongem,但是样式尽量使用css样式来描述;
  • 使用表格时,标题用 caption,表头用 thead,主体部分用 tbody 包围,尾部用 tfoot 包围。表头和一般单元格要区分开,表头用 th,单元格用 td
  • 列表搭建时,使用<ul>无序列表<ul><ol>有序列表<ol><dl>定义列表;
  • 表单域要用 fieldset 标签包起来,并用 legend 标签说明表单的用途(可理解为表单标题)
  • 每个input标签对应的说明文本都需要使用label标签,并且通过为input设置id属性,在lable标签中设置for = ld来让说明文本和相对应的input关联起来,或者直接在label中内嵌控件。
1.3.5 布局规范
  • p元素用来放文字,而不是用来布局。在浏览器自身的样式中默认pmargin和其他样式;
  • 想实现换行可以使用block元素或者css的display属性,尽量避免使用br来换行。文字内容中的换行可以用br,但通常也很少这样用;
  • 不要滥用div,w3c对div的描述是这样的:当没有其他元素可用时才能使用div,如果想让linkimg这类元素能够在结尾换行,可以在样式中添加display:block, 这样要比把他们放进div或者使用br来换行要好很多;
  • 必须知道哪些是块级元素,这样就可以避免把块级元素放到div里面,比如列表就不需要放到div里面;
  • table是用来放表格数据的,不是用来布局的;
  • 盒模型一定要掌握,必须知道什么时候该用padding,什么时候该用margin;是topleft
  • 使用margin的规则: 通常情况下,margin都是添加在元素的bottomright,有时也可以是top或者left。无论如何,尽量避免同时在bottomtop,或者rightleft添加margin,可以用last-of-type选择器来去掉最后一个子元素的margin
1.3.6 标签嵌套规范
  • 块元素可以包含内联元素或某些块元素,但内联元素却不能包含块元素,它只能包含其它的内联元素
  • 块级元素不能放在p里面
  • 有几个特殊的块级元素只能包含内嵌元素,不能再包含块级元素:h1h2h3h4h5h6pdt
  • ul,li / ol,li / dl,dt,dd拥有父子级关系的标签;ulol下都只能跟lidl下只能跟dtdd
  • a标签不能嵌套a标签
1.3.7 易访问性(网站代码优化)

要多为用户考虑,不同的设备条件、使用环境以及输入法等都会给你的HTML带来不同的体验:

  • 网页的titlekeywordsdescription一定要写,要精简全面。
  • 网页使用语义化代码。
  • a标签要设置title属性;外部链接还要设置rel属性– –rel=”nofollow”,nofollow值会使得网络爬虫不顺着链接爬出。
  • 所有的标题使用h1标签,样式可以使用css设置。
  • br标签只能用于文本换行。
  • table一定要使用caption设置表格题目。
  • strong用来设置重标,em设置斜体。
  • img标签一定要设置其alt属性。

2. HTML及扩展

2.1 DOCTYPE文档声明

  • 声明帮助浏览器正确地显示网页 ;
  • 定义这个文档的类型,浏览器会先识别这句话,会按照这个类型去解析这个文档;
  • HTML 也有多个不同的版本,只有完全明白页面中使用的确切 HTML 版本,浏览器才能完全正确地显示出 HTML 页面 ;
  • 一般高版本兼容低版本,所以在工作中我们默认写高版本就可以了(html5文档声明)
  • 文档声明不区分大小写;
  • 文档声明必须放在第一行(因为浏览器是从上到下解析的)
  • 必须写文档声明,如果不写就会发生怪异事件;
  • 文档声明不是一个标签,它只是一个声明;
HTML5
<!DOCTYPE html>

HTML 4.01
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

XHTML 1.0
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 


<p data-line="226" class="sync-line" style="margin:0;"></p>

2.2 meta元信息

meta标签提供关于HTML文档的元数据。元数据不会显示在页面上,但是对于机器是可读的。它可用于浏览器(如何显示内容或重新加载页面),搜索引擎(关键词),或其他 web 服务。

// 申明编码
<meta charset="UTF-8" />

// 页面关键词
<meta name="keywords" content="" />

//页面描述
<meta name="description" content=" " />

// 视口-移动设备
<meta name="viewport" content="width=device-width, initial-scale=1">

// 搜索引擎索引方式
all:文件将被检索,且页面上的链接可以被查询;
none:文件将不被检索,且页面上的链接不可以被查询;
index:文件将被检索;
follow:页面上的链接可以被查询;
noindex:文件将不被检索;
nofollow:页面上的链接不可以被查询。
<meta name="robots" content="index,follow" />

// 定义网页作者
<meta name="author" content="author name" /> 

// 优先使用IE最新版本和 Chrome
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
// 关于X-UA-Compatible
<meta http-equiv="X-UA-Compatible" content="IE=6" ><!-- 使用IE6 -->
<meta http-equiv="X-UA-Compatible" content="IE=7" ><!-- 使用IE7 -->
<meta http-equiv="X-UA-Compatible" content="IE=8" ><!-- 使用IE8 -->
// 页面重定向和刷新
<meta http-equiv="refresh" content="0;url=" />
// 禁止浏览器从本地计算机的缓存中访问页面内容:这样设定,访问者将无法脱机浏览
<meta http-equiv="Pragma" content="no-cache">
// 转码申明:用百度打开网页可能会对其进行转码(比如贴广告),避免转码可添加如下meta。
<meta http-equiv="Cache-Control" content="no-siteapp" />

// 启用 WebApp 全屏模式
<meta name="apple-mobile-web-app-capable" content="yes" />
// 隐藏状态栏/设置状态栏颜色:只有在开启WebApp全屏模式时才生效
// content的值为default | black | black-translucent 
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
// 添加到主屏后的标题
<meta name="apple-mobile-web-app-title" content="标题">
// 忽略数字自动识别为电话号码
<meta content="telephone=no" name="format-detection" />
// 忽略识别邮箱
<meta content="email=no" name="format-detection" />
// 添加智能 App 广告条 Smart App Banner
<meta name="apple-itunes-app" content="app-id=myAppStoreID, 
  affiliate-data=myAffiliateData, app-argument=myURL">

<p data-line="282" class="sync-line" style="margin:0;"></p>

<meta name="HandheldFriendly" content="true">

<p data-line="284" class="sync-line" style="margin:0;"></p>

<meta name="MobileOptimized"  content="320">

<p data-line="286" class="sync-line" style="margin:0;"></p>

<meta name="screen-orientation" content="portrait">

<p data-line="288" class="sync-line" style="margin:0;"></p>

<meta name="x5-orientation" content="portrait">

<p data-line="290" class="sync-line" style="margin:0;"></p>

<meta name="full-screen" content="yes">

<p data-line="292" class="sync-line" style="margin:0;"></p>

<meta name="x5-fullscreen" content="true">

<p data-line="294" class="sync-line" style="margin:0;"></p>

<meta name="browsermode" content="application">

<p data-line="296" class="sync-line" style="margin:0;"></p>

<meta name="x5-page-mode" content="app">

<p data-line="298" class="sync-line" style="margin:0;"></p>

<meta name="msapplication-tap-highlight" content="no">

// 浏览器内核控制 
<meta name="renderer" content="webkit|ie-comp|ie-stand">

<p data-line="302" class="sync-line" style="margin:0;"></p>

2.3 Entity

在编写HTML页面时,需要用到"<"、">"、"空格"等符号,直接输入这些符号时,会错误的把它们与标记混在一起,非常不利于编码。那么就需要把这些字符进行转义,以另一种方式抒写,以相同的形式展现。在HTML中,这些字符可称为HTML Entity,即HTML字符实体。一个HTML Entity都含有2种转义格式:Entity Name 和 Entity Number。

2.3.1 Entity Name
  • 格式: &entityName;
  • 说明:"&"开头,";"结尾,以语义的形式描述字符。如字符"<",英文名称为"less than",Entity Name为"<",取自"less than"2个单词的首字母。
2.3.2 Entity Number
  • 格式: &#entityNumber;
  • 说明:"&#"开头,";"结尾,以编号的形式描述字符。此编号可以为十进制或十六进制(以"&#x"开头)等数字格式。
2.3.3 作用

显示 HTML 保留字符,如 <、>、&、 " 等(联想到防御 XSS 攻击);表示难以用常规输入设备输入的字符,如 ©、®、± 等;表示给定的字符编码可能无法表达文档字符集的其他字符,如ASCII 编码想显示中文,使用水表示 “水”;

2.4 SVG矢量图形

2.4.1 什么是SVG
  • SVG 指可伸缩矢量图形 (Scalable Vector Graphics)
  • SVG 用来定义用于网络的基于矢量的图形
  • SVG 使用 XML 格式定义图形
  • SVG 图像在放大或改变尺寸的情况下其图形质量不会有所损失
  • SVG 是万维网联盟的标准
  • SVG 与诸如 DOM 和 XSL 之类的 W3C 标准是一个整体;
2.4.2 SVG的优势

与其他图像格式相比(比如 JPEG 和 GIF),使用 SVG 的优势在于:

  • SVG 图像可通过文本编辑器来创建和修改
  • SVG 图像可被搜索、索引、脚本化或压缩
  • SVG 是可伸缩的
  • SVG 图像可在任何的分辨率下被高质量地打印
  • SVG 可在图像质量不下降的情况下被放大
2.4.3 浏览器支持
  • Internet Explorer 9+
  • Firefox
  • Opera
  • Chrome
  • Safari
// 把 SVG 直接嵌入 HTML 页面
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="190">
  <polygon points="100,10 40,180 190,60 10,60 160,180"
  style="fill:lime;stroke:purple;stroke-width:5;fill-rule:evenodd;">
</svg>  
  
// 包含了 XML 声明。请注意 standalone 属性!该属性规定此 SVG 文件是否是“独立的”,
// 或含有对外部文件的引用。standalone="no" 意味着 SVG 文档会引用一个外部文件 - 在这里,是 DTD 文件
<?xml version="1.0" standalone="no"?>

// 引用了这个外部的 SVG DTD。该 DTD位于 “http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd”。
// 该DTD位于W3C,含有所有允许的 SVG 元素
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

// SVG 代码以 <svg> 元素开始,包括开启标签 <svg> 和关闭标签 </svg> 。这是根元素。
// width 和 height 属性可设置此 SVG 文档的宽度和高度。
// version 属性可定义所使用的 SVG 版本,xmlns 属性可定义 SVG 命名空间
<svg width="100%" height="100%" version="1.1"
xmlns="http://www.w3.org/2000/svg">

// SVG 的 <circle> 用来创建一个圆。cx 和 cy 属性定义圆中心的 x 和 y 坐标。如果忽略这两个属性,
// 那么圆点会被设置为 (0, 0)。r 属性定义圆的半径
// stroke 和 stroke-width 属性控制如何显示形状的轮廓。我们把圆的轮廓设置为 2px 宽,黑边框
// fill 属性设置形状内的颜色。我们把填充颜色设置为红色
<circle cx="100" cy="50" r="40" stroke="black"
stroke-width="2" fill="red"/>

</svg>


<p data-line="383" class="sync-line" style="margin:0;"></p>

3. CSS机制At-rule

大家可能在CSS中见到过字符@然后加一些关键字的用法,这种用法就称之为AT规则。

所谓“常规规则”指的是语法类似下面的规则:@[KEYWORD] (RULE)

  • @charset
  • @import
  • @namespace

所谓“嵌套规则”就是带有花括号{} , 语法类似下面的规则 @[KEYWORD] { /* 嵌套语句 */ }

  • @document
  • @font-face
  • @keyframes
  • @media
  • @page
  • @supports

3.1 @charset

定义字符集。⽤于提示CSS文件使用的字符编码方式,它如果被使用,必须出现在最前面。这个规则只在给出语法解析阶段前使用,并不影响页面上的展示效果;

@charset "utf-8";

<p data-line="416" class="sync-line" style="margin:0;"></p>

3.2 @import

导入其他CSS样式文件。除了@charset规则不会被引入,@import可以引⼊另⼀个文件的全部内容。

实际上线时候,不建议使用,多请求,阻塞加载之类。但本地开发可以使用,用做CSS模块化开发,然后使用一些(如grunt)工具进行压缩并合并。但是呢,相比less, sass等还是有不足,就是@import语句只能在CSS文件顶部,使得文件的前后关系控制,就不那么灵活。

@import 'index.css';
@import url('index.css');

<p data-line="425" class="sync-line" style="margin:0;"></p>

3.3 @document

CSS 4.0规范有相关说明。如果文档满足给定的一些条件,就可以应用我们指定的一些样式。比如说,这个CSS文件被子站A调用,和被子站C调用,我们可以通过域名匹配来执行不同的CSS样式。这样,我们可以有效避免冲突,或者防止外链之类

@document 
  /* 页面URL需要是 */
  url(http://www.zhangxinxu.com/),
  
  /* 页面URL的开头必须是... */
  url-prefix(www.zhangxinxu.com/wordpress/),
  
  /* 该域上的所有页面 */
  domain(zhangxinxu.com),

  /* 所有https协议页面 */
  regexp("https:.*")
{
  
  /* 开始样式 */
  body { font-family: Comic Sans; }

}

<p data-line="458" class="sync-line" style="margin:0;"></p>

3.4 @font-face

自定义字体用的。

@font-face {
  font-family: 'MyWebFont';
  src:  url('myfont.woff2') format('woff2'),
        url('myfont.woff') format('woff');
}

<p data-line="469" class="sync-line" style="margin:0;"></p>

3.5 @keyframes

用来声明CSS3 animation动画关键帧

@keyframes fadeIn {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

<p data-line="483" class="sync-line" style="margin:0;"></p>

3.6 @media

媒介查询

@media all and (min-width: 1280px) {
    /* 宽度大于1280干嘛干嘛嘞... */ 
}
@media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 2dppx) { 
    /* Retina屏幕干嘛干嘛嘞... */ 
}
@media print {
    /* 闪开闪开,我要打印啦! */ 
}
@media \0screen\,screen\9 {
    /* IE7,IE8干嘛干嘛嘞... */ 
}
@media screen\9 {
    /* IE7干嘛干嘛嘞... */ 
}

<p data-line="504" class="sync-line" style="margin:0;"></p>

3.7 @page

page⽤于分页媒体访问网页时的表现设置,页面是⼀种特殊的盒模型结构,除了页面本身,还可以设置它周围的盒,这个规则用在打印文档时候修改一些CSS属性。使用@page我们只能改变部分CSS属性,例如间距属性margin, 打印相关的orphans, widows, 以及page-break-*, 其他CSS属性会被忽略。

@page :first {
   margin: 1in;
}
上面CSS表示:first页面也要有:left, :right页面margin间距。zxx: 
//@page的伪类包括::blank, :first, :left, :right


<p data-line="515" class="sync-line" style="margin:0;"></p>

3.8 @supports

是否支持某CSS属性声明的AT规则,浏览器对其支持性越来越好了

/* 检查是否支持CSS声明 */ 
@supports (display: flex) {
  .module { display: flex; }
}

/* 检查多个条件 */ 
@supports (display: flex) and (-webkit-appearance: checkbox) {
  .module { display: flex; }
}

<p data-line="530" class="sync-line" style="margin:0;"></p>

4. CSS变量var的使用

在任何语言中,变量的有一点作用都是一样的,那就是可以降低维护成本,附带还有更高性能,文件更高压缩率的好处。

随着CSS预编译工具Sass/Less/Stylus的关注和逐渐流行,CSS工作组迅速跟进CSS变量的规范制定,并且,很多浏览器已经跟进,目前,在部分项目中已经可以直接使用了。 CSS 变量(CSS variable)又叫做"CSS 自定义属性"(CSS custom properties)。因为变量与自定义的 CSS 属性其实是一回事。

因为$foo被 Sass 用掉了,@foo被 Less 用掉了。为了不产生冲突,官方的 CSS 变量就改用两根连词线了。

4.1 CSS变量的语法和用法

  • CSS中原生的变量定义语法是:变量名前面要加两根连词线 --*
  • 变量使用语法是:var()函数用于读取变量 var(--*)
  • 其中 * 表示我们的变量名称
  • 变量名大小写敏感,--header-color--Header-Color是两个不同变量

4.2 CSS变量的命名

关于命名这个东西,各种语言都有些显示,例如CSS选择器不能是数字开头,JS中的变量是不能直接数值的,但是,在CSS变量中,这些限制通通没有,例如:

:root {
  --1: #369;
}
body {
  background-color: var(--1);
}

<p data-line="569" class="sync-line" style="margin:0;"></p>

但是,不能包含$,[,^,(,%等字符,普通字符局限在只要是“数字[0-9]”“字母[a-zA-Z]”“下划线_”和“短横线-”这些组合,但是可以是中文日文或者韩文,例如:

body {
  --深蓝: #369;
  background-color: var(--深蓝);
}

<p data-line="577" class="sync-line" style="margin:0;"></p>

无论是变量的定义和使用只能在声明块{}里面,例如,下面这样是无效的:

--深蓝: #369;
body {
  background-color: var(--深蓝);
}

<p data-line="585" class="sync-line" style="margin:0;"></p>

变量值只能用作属性值,不能用作属性名; 下面代码中,变量--side用作属性名,这是无效的。

.foo {
  --side: margin-top;
  /* 无效 */
  var(--side): 20px;
}


<p data-line="594" class="sync-line" style="margin:0;"></p>

4.3 全局/局部变量

  • :root伪类可以看做是一个全局作用域,在里面声明的变量,他下面的所有选择器都可以拿到;
// 全局变量
:root { --color: blue; }
.box{color: var(--color)}

// 局部变量
.box{
    --color: red;
    color: var(--color);
}

<p data-line="610" class="sync-line" style="margin:0;"></p>

4.4 CSS变量的默认参数

  • var()函数还可以使用第二个参数,表示变量的默认值。如果该变量不存在,就会使用这个默认值。
  • 第二个参数不处理内部的逗号或空格,都视作参数的一部分;
color: var(--foo, #7F583F);
var(--font-stack, "Roboto", "Helvetica");   var(--pad, 10px 15px 20px);

<p data-line="620" class="sync-line" style="margin:0;"></p>

4.5 CSS变量的拼接

  • 如果变量值是一个字符串,可以与其他字符串拼接;
  • 如果变量值是数值,不能与数值单位直接连用;
  • 如果变量值带有单位,就不能写成字符串;
// 字符串
--bar: 'hello';   
--foo: var(--bar)' world';

// 变量值是数值
foo { 
	--gap: 20; 
  margin-top: var(--gap)px;  /* 无效 */  
}

// 上面代码中,数值与单位直接写在一起,这是无效的。必须使用calc() 函数,将它们连接,
foo { 
	--gap: 20; 
  margin-top: calc(var(--gap) * 1px); 
}

// 变量值带有单位
.foo {
	--foo: '20px'; 
  font-size: var(--foo);  /* 无效 */ 
} 

.foo {
	--foo: 20px;
  font-size: var(--foo);  /* 有效 */ 
}

<p data-line="654" class="sync-line" style="margin:0;"></p>

4.6 CSS变量的作用域

同一个 CSS 变量,可以在多个选择器内声明。读取的时候,优先级最高的声明生效。这与 CSS 的"层叠"(cascade)规则是一致的;

<style>
  :root { --color: blue; }
  div { --color: green; }
  #alert { --color: red; }
  * { color: var(--color); }
</style>

<p>蓝色</p>
<div>绿色</div>
<div id="alert">红色</div>

<p data-line="670" class="sync-line" style="margin:0;"></p>

上面代码中,三个选择器都声明了--color变量。不同元素读取这个变量的时候,会采用优先级最高的规则,因此三段文字的颜色是不一样的。 这就是说,变量的作用域就是它所在的选择器的有效范围;

body {
  --foo: #7F583F;
}

.content {
  --bar: #F7EFD2;
}

<p data-line="681" class="sync-line" style="margin:0;"></p>

上面代码中,变量--foo的作用域是body选择器的生效范围,--bar的作用域是.content选择器的生效范围。 由于这个原因,全局的变量通常放在根元素:root里面,确保任何选择器都可以读取它们。

:root {
  --main-color: #06c;
}

<p data-line="689" class="sync-line" style="margin:0;"></p>

4.7 CSS变量的注意问题

  • 当存在多个同样名称的变量时候,变量的覆盖规则由CSS选择器的权重决定的,但并无!important这种用法。
  • 变量的取值采用就近原则。
  • 如果变量值是数值,不能与数值单位直接连用。必须使用calc()函数,将它们连接;
  • 如果变量值带有单位,就不能写成字符串。
  • CSS属性名是不可以使用变量的;
  • CSS变量是存在缺省值,只要定义正确,里面的值不对,结果以缺省值显示;
  • CSS变量默认尾部是有空格的;

4.8 CSS变量的响应式布局

CSS 是动态的,页面的任何变化,都会导致采用的规则变化。 利用这个特点,可以在响应式布局的media命令里面声明变量,使得不同的屏幕宽度有不同的变量值。

body {
  --primary: #7F583F;
  --secondary: #F7EFD2;
}

a {
  color: var(--primary);
  text-decoration-color: var(--secondary);
}

@media screen and (min-width: 768px) {
  body {
    --primary:  #F7EFD2;
    --secondary: #7F583F;
  }
}

<p data-line="722" class="sync-line" style="margin:0;"></p>

4.9 CSS变量的兼容性处理

对于不支持 CSS 变量的浏览器,可以采用下面的写法

// 用属性值得无效声明
a {
  color: #7F583F;
  color: var(--primary);
}

// 也可以使用@support命令进行检测
@supports ( (--a: 0)) {
  /* supported */
}
@supports ( not (--a: 0)) {
  /* not supported */
}

// JavaScript 检测浏览器是否支持 CSS变量
const isSupported =
    window.CSS &&
    window.CSS.supports &&
    window.CSS.supports('--a', 0);
 
if (isSupported) {
    /* supported */
} else {
    /* not supported */
}

// JavaScript 操作 CSS 变量的写法
window.onload = function() {
    // 设置值
    document.body.style.setProperty("--primary","pink");
    // 读取值
    let primary = document.body.style.getPropertyValue("--primary");
    console.log(primary);
    // 删除变量;返回删除的变量值
    let delPrimary = document.body.style.removeProperty("--primary");
    console.log(delPrimary);
}

<p data-line="765" class="sync-line" style="margin:0;"></p>

5. CSS高级属性绘制技巧

5.1 线性渐变:linear-gradient

5.2 径向渐变:radial-gradient

5.3 背景尺寸:background-size

5.4 背景原点:background-origin

5.5 背景裁剪:background-clip

5.6 边框圆角:border-radius

5.7 盒子阴影:box-shadow

5.8 文字阴影:text-shadow

5.9 滤镜特效:Filter

5.10 路径裁剪:clip-path

6. CSS高级常见技巧汇总

6.1 设置input的placeholder的字体样式

设置input占位符的样式:

input::-webkit-input-placeholder {    /* Chrome/Opera/Safari */
    color: red;
}
input::-moz-placeholder { /* Firefox 19+ */  
    color: red;
}
input:-ms-input-placeholder { /* IE 10+ */
    color: red;
}
input:-moz-placeholder { /* Firefox 18- */
    color: red;
}

<input type="text" placeholder="请设置用户名">

设置input聚焦时的样式:

input:focus {   
  background-color: red;
}

取消input的边框:

border: none;
outline: none;

6.2 单行和多行文本超出省略号

单行文本超出省略号:

width: 200px; 
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;

多行文本超出省略号:

display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
word-break: break-all;
overflow: hidden;

6.3 隐藏滚动条或更改滚动条样式

.scroll-container {
    width: 500px;
    height: 150px;
    border: 1px solid #ddd;
    padding: 15px;
    overflow: auto;
}

.scroll-container .row {
    margin: 0;
    line-height: 1.5;
}

.scroll-container::-webkit-scrollbar {
    width: 8px;
    background: white;
}

.scroll-container::-webkit-scrollbar-corner,
/* 滚动条角落 */
.scroll-container::-webkit-scrollbar-thumb,
.scroll-container::-webkit-scrollbar-track {
    border-radius: 4px;
}

.scroll-container::-webkit-scrollbar-corner,
.scroll-container::-webkit-scrollbar-track {
    /* 滚动条轨道 */
    background-color: rgba(180, 160, 120, 0.1);
    box-shadow: inset 0 0 1px rgba(180, 160, 120, 0.5);
}

.scroll-container::-webkit-scrollbar-thumb {
    /* 滚动条手柄 */
    background-color: #00adb5;
}
<p class="scroll-container">
        庭院深深,不知有多深?杨柳依依,飞扬起片片烟雾,一重重帘幕不知有多少层。豪华的车马停在贵族公子寻欢作乐的地方,她登楼向远处望去,却看不见那通向章台的大路。春已至暮,三月的雨伴随着狂风大作,再是重门将黄昏景色掩闭,也无法留住春意。泪眼汪汪问落花可知道我的心意,落花默默不语,纷乱的,零零落落一点一点飞到秋千外。庭院深深,不知有多深?杨柳依依,飞扬起片片烟雾,一重重帘幕不知有多少层。豪华的车马停在贵族公子寻欢作乐的地方,她登楼向远处望去,却看不见那通向章台的大路。春已至暮,三月的雨伴随着狂风大作,再是重门将黄昏景色掩闭,也无法留住春意。泪眼汪汪问落花可知道我的心意,落花默默不语,纷乱的,零零落落一点一点飞到秋千外。庭院深深,不知有多深?杨柳依依,飞扬起片片烟雾,一重重帘幕不知有多少层。豪华的车马停在贵族公子寻欢作乐的地方,她登楼向远处望去,却看不见那通向章台的大路。春已至暮,三月的雨伴随着狂风大作,再是重门将黄昏景色掩闭,也无法留住春意。泪眼汪汪问落花可知道我的心意,落花默默不语,纷乱的,零零落落一点一点飞到秋千外。庭院深深,不知有多深?杨柳依依,飞扬起片片烟雾,一重重帘幕不知有多少层。豪华的车马停在贵族公子寻欢作乐的地方,她登楼向远处望去,却看不见那通向章台的大路。春已至暮,三月的雨伴随着狂风大作,再是重门将黄昏景色掩闭,也无法留住春意。泪眼汪汪问落花可知道我的心意,落花默默不语,纷乱的,零零落落一点一点飞到秋千外。
</p>

6.4 纯CSS绘制三角形

正三角形:

.triangle {
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 0 25px 40px 25px;
  border-color: transparent transparent rgb(245, 129, 127) transparent;
}

倒三角形:

.triangle {
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 40px 25px 0 25px;
  border-color:  rgb(245, 129, 127) transparent transparent transparent;
}

6.5 虚线框绘制技巧

.dotted-line {
  width: 800px;
  margin: auto;
  padding: 20px;
  border: 1px dashed transparent;
  background: linear-gradient(white, white) padding-box, repeating-linear-gradient(-45deg, red 0, #ccc .25em, white 0, white .75em);
}

<p class="dotted-line">庭院深深,不知有多深?杨柳依依,飞扬起片片烟雾,一重重帘幕不知有多少层。豪华的车马停在贵族公子寻欢作乐的地方,她登楼向远处望去,却看不见那通向章台的大路。春已至暮,三月的雨伴随着狂风大作,再是重门将黄昏景色掩闭,也无法留住春意。泪眼汪汪问落花可知道我的心意,落花默默不语,纷乱的,零零落落一点一点飞到秋千外。庭院深深,不知有多深?杨柳依依,飞扬起片片烟雾,一重重帘幕不知有多少层。豪华的车马停在贵族公子寻欢作乐的地方,她登楼向远处望去,却看不见那通向章台的大路。春已至暮,三月的雨伴随着狂风大作,再是重门将黄昏景色掩闭,也无法留住春意。泪眼汪汪问落花可知道我的心意,落花默默不语,纷乱的,零零落落一点一点飞到秋千外。庭院深深,不知有多深?杨柳依依,飞扬起片片烟雾,一重重帘幕不知有多少层。豪华的车马停在贵族公子寻欢作乐的地方,她登楼向远处望去,却看不见那通向章台的大路。春已至暮,三月的雨伴随着狂风大作,再是重门将黄昏景色掩闭,也无法留住春意。泪眼汪汪问落花可知道我的心意,落花默默不语,纷乱的,零零落落一点一点飞到秋千外。庭院深深,不知有多深?杨柳依依,飞扬起片片烟雾,一重重帘幕不知有多少层。豪华的车马停在贵族公子寻欢作乐的地方,她登楼向远处望去,却看不见那通向章台的大路。春已至暮,三月的雨伴随着狂风大作,再是重门将黄昏景色掩闭,也无法留住春意。泪眼汪汪问落花可知道我的心意,落花默默不语,纷乱的,零零落落一点一点飞到秋千外。</p>

6.6 卡券效果制作

.coupon {
    width: 300px;
    height: 100px;
    line-height: 100px;
    margin:50px auto;
    text-align: center;
    position: relative;
    background: radial-gradient(circle at right bottom, transparent 10px, #ffffff 0) top right /50% 51px no-repeat,
        radial-gradient(circle at left bottom, transparent 10px, #ffffff 0) top left / 50% 51px no-repeat,
        radial-gradient(circle at right top, transparent 10px, #ffffff 0) bottom right / 50% 51px no-repeat,
        radial-gradient(circle at left top, transparent 10px, #ffffff 0) bottom left / 50% 51px no-repeat;
    filter: drop-shadow(2px 2px 2px rgba(0, 0, 0, .2));
}
.coupon span{
    display: inline-block;
    vertical-align: middle;
    margin-right:10px;
    color:red;
    font-size: 50px;
    font-weight: 400;
}

<p class="coupon">
    <span>200</span>优惠券
</p>

6.7 负边距使用技巧

规律:左为负时,是左移,右为负时,是左拉。上下与左右类似

*{
    margin:0;
    padding:0;
}
.wrap{
    /* 利用负值技巧进行整体移动 */
    margin-left:-6px;
}
.item{
    float:left;
    width: 20%;
    height: 300px;
    border-left:6px solid #fff;
    box-sizing: border-box;
}

<div class="wrap">
    <div class="item" style="background-color: red;"></div>
    <div class="item" style="background-color: green;"></div>
    <div class="item" style="background-color: yellow;"></div>
    <div class="item" style="background-color: pink;"></div>
    <div class="item" style="background-color: green;"></div>
</div>

6.8 定位同时设置方位情况

规律:绝对定位和固定定位时,同时设置 left 和 right 等同于隐式地设置宽度

span{
    border:1px solid red;
    position: absolute;
    left:0;
    right:0;
    
     /* 等同于设置  width:100%;display:block */
}

<span>1</span>

6.9 相邻兄弟选择器之常用场景

ul{
    width: 500px;
    margin:auto;
    list-style: none;
    padding:0;
    border:1px solid red;
    text-align: center;
}
li+li{
    border-top:1px solid red;
}

<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
</ul>

6.10 隐藏文本的常用两种方法

text-indent: -9999px; 或者 font-size: 0;

.logo {
    width: 190px;
    height: 80px;
    float: left;
    margin-top: 8px
}

.logo h1 {
    position: relative
}

.logo h1 .logo-bd {
    display: block;
    margin-left: 22px;
    padding-top: 58px;
    width: 142px;
    overflow: hidden;
    background: url(http://img.alicdn.com/tfs/TB1_uT8a5ERMeJjSspiXXbZLFXa-143-59.png) 0 0 no-repeat;
    text-indent: -9999px;
}

<div class="logo">
    <h1>
        <a href="#" role="img" class="logo-bd clearfix">淘宝网</a>
    </h1>
</div>

6.11 outline属性的妙用技巧

区别:outline不计算大小,border计算大小

* {
    padding: 0;
    margin: 0;
}

ul {
    list-style: none;
    width: 600px;
    margin: auto;
}

li {
    padding: 10px;
    border: 10px solid pink;
    outline-offset: -10px;
}
li+li{
    margin-top:-10px;
}
li:hover{
    /* border:10px solid gold; */
    outline:10px solid gold;
}

<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
</ul>

6.12 表格边框合并

table{
	 border-collapse: collapse;
}