【学习笔记】CSS 基础

初识 CSS

  • CSS 全称为 cascading style sheet 层叠样式表,它的主要做用是为 HTML 标签添加各类各样的样式和修饰效果

HTML 页面引入 CSS 的方式

  • 行间样式:直接写在 HTML 标签里的 style 属性
  • 页面级 CSS:在 head 标签里面添加一个 style 标签
<style type=”text/css”></style>
复制代码
  • 外联 CSS 文件:在外建立一个 .css 后缀的文件,在 head 标签里面加上个 link 标签
    • link 标签里的 href 属性上写上 CSS 文件地址,最好用相对地址的形式link 加载不会阻塞 HTML 的加载,HTML 和 css 属于异步加载
    • 注意:link 标签引入和 style 标签修改样式之间并无什么优先级,谁写在前面谁就先执行,写在后面的 CSS 样式会覆盖掉前面的 CSS 样式。有时link 写在上面可是 link 还没加载进来因此先运行了后面的 style,这种问题多是网速致使的并非两者自己拥有优先级的问题
      <link rel="stylesheet" href="">
      复制代码
  • import 方式引入(已经弃用):在 head 标签里面写个 style 标签,在第一行写上 @import url(); url 里写 CSS 文件的地址,可加引号也可不加引号,这种引入方式有几种缺点致使它如今被废弃使用
    • 必须写在第一行,如有多个则一块儿写在最前面
    • IE6 的环境下只能使用最多 31 次,这个数字听说是阿里的开发人员一点一点测试出来的(待考究)
    • 程序读到 import 时会忽略掉 import,等 HTML 里的全部内容包括图片在内的全部资源全都加载完后才加载 import 的 CSS 文件,即 import 引入的 CSS 文件和 HTML 的加载是同步进行的
  • link 和 import 的区别
    • link 是 XHTML 标签,除了加载 CSS 外还可定义 RSS 等其余事务;@import 属于 CSS 范畴,只能加载 CSS
    • link 引用 CSS 时在页面载入时同时加载;@import 须要页面网页彻底载入之后加载
    • link 是 XHTML 标签,无兼容问题;@import 是在 CSS2.1 提出的,低版本的浏览器不支持
    • link 支持使用 JS 控制 DOM 去改变样式;而 @import 不支持
    • link 的样式权重高于 @import 的权重

CSS 选择器

  • CSS 选择器的做用是让咱们能找到想要修改样式的元素,而后为其修改样式php

  • id 选择器
    该 id 是惟一标识,一个元素只能有一个 id,一个 id 也只能给一个元素。而后在 CSS 文件中,经过 #id {} 的方式选择到添加 id 的那个元素css

  • class 类选择器
    在元素的属性中写上 class 属性,该属性是为这个元素添加一个类名,每个元素可有多个类名,同一个类名也可赋给不少个元素,在 CSS 文件中,经过 .class {} 的方式来选择出添加了类名的元素html

  • 标签选择器
    div {},只要是 div 的标签就会被选择出来css3

  • 通配符选择器
    * {},全部的标签都会被选择出来加上样式,body 标签页包含在内web

  • 父子选择器(派生选择器)chrome

    • 如 div p {},给 div 下的 p 加样式 这时的 p 的权重值是加和的结果,id 和 class 也是可使用父子选择器
    • 在实际开发中因要注意浏览器寻找元素时的耗能,通常父子选择器不超过 4 层,如:div p strong em span,解读顺序是从选择器的右边到左边读取路径链越短效率越高,层级通常最好不超过四层,这是为何呢?
      • 如果从左往右寻找,每找到一个父级标签都要把它下面全部标签都遍历一遍,看看有没有下一个标签,上面那个选择器示例中浏览器会先找到 div 标签,而后把 div 下面全部的子元素都遍历一遍后找到 strong 这个标签,而后再把 strong 标签下的全部元素遍历一遍找到 em 这个标签,以此类推,十分消耗性能且速度很是慢
      • 若从右往左,那浏览器只须要先找到 span 标签,而后从 span 这个节点向上寻找,只要找到 em 就能够中止寻找,以此类推,没必要遍历全部节点且需遍历的点很是的少,这样的好处显而易见,速度很是快并且不耗性能
  • 直接子元素选择器
    如 div > strong浏览器

    // 正确
      <div>
      <strong></strong>
      </div>
    
      // 错误
      <div> <em> <strong></strong> </em> </div>
    复制代码
  • 并列选择器
    可以使用相似 div.select {} 来选择,这种方式是只有 div 和 .select 同时做用在一个标签上时才会被选出来,书写时标签名放在前面,其余的放在后面markdown

    <div class=”select”></div>
    复制代码
  • 分组选择器
    如 div, p, em, strong {} 这样的写法,能够把这些标签都选择出来加上一样的样式,中间是用逗号链接的app

  • 伪类选择器异步

    • 用于当已有元素处于某个状态时为其添加对应的样式,这个状态是根据用户行为而动态变化的,如当用户悬停在指定的元素时,能够经过 :hover 来描述这个元素的状态
    • 虽然它和普通的 CSS 类类似,能够为已有的元素添加样式,但它只有处于 DOM 树没法描述的状态下才能为元素添加样式,因此将其称为伪类
    • 常见的伪类
      • :link,设置 a 标签在未被访问前的 CSS 样式
      • :visited,设置 a 标签在其连接地址已被访问过的 CSS 样式
      • :hover,设置元素在其鼠标悬停时的 CSS 样式
      • :active,设置元素在被用户激活(在鼠标点击与释放间发生的事件)时的 CSS 样式

伪类.png

  • 伪元素选择器
    • 用于建立一些不在文档树中的元素并为其添加样式,如可经过 :before 来在一个元素前增长一些文本并为这些文本添加样式
    • 虽然用户可看到这些文本,可是这些文本实际上不在文档树中(某些伪类或伪元素仍然处于试验阶段,在使用前建议先在 Can I Use 等网站查一查其浏览器兼容性,处于试验阶段的伪类或伪元素会在标题中标注)

伪元素.png

  • 属性选择器
    属性选择器搭配较自由,既可根据属性来选也可根据属性值来选,还可根据部分属性值来选,具体规则以下

属性选择器.png

注意
一、通常不给标签加 id,而是经过添加 class 类名来选择的,由于 id 表明惟一标示,通常用 id 来作标记,后台的 php 会根据提取出来 id 换成他们的标记,所以可能会致使选择器选择不出来想要的标签
二、写类名时必定要注意语义化,要符合语义化标准,要用英文单词去命名,而不是用看不懂的abc之类的类名

选择器的权重及优先级

  • 权重值
    • !important:无穷大,在数学中【无穷大+1】依然是无穷大,但在 CSS 选择器的权重值里【无穷大+1 > 无穷大】
    • 行间(内联)样式:1000
    • id:100
    • class、属性、伪类:10
    • 标签、伪元素:1
    • 通配符:0
  • 优先级
    • 元素声明的样式权重高于浏览器的默认样式
    • 浏览器默认样式的权重高于继承父级元素的样式
    • !important > 内联 > ID 选择器 > 类选择器(属性、伪类) > 标签选择器(伪元素) > 通配符

选择器的执行效率

  • 选择器的执行效率(由高到低):id(#myid) > 类(.myclassname) > 标签(div, h1, p) > 相邻(h1 + p) > 子元素(ul > li) > 后代(li a) > 通配符(*) > 属性(a[rel="external"]) > 伪类(a: hover, li: nth-child)
  • CSS 选择器对性能的影响源于浏览器匹配选择器和文档元素所消耗的时间,因此优化选择器的原则是应尽可能避免使用消耗更多匹配时间的选择器

单位

  • 绝对单位,如:px、in、pt、cm、mm
    • px:pixels(像素)的缩写,用于屏幕显示器上。传统上一个像素对应屏幕上的一个点,而对于高清屏则更多。任何现代显示屏都是由成千上万的像素组成,所以可使用像素来定义长度。CSS 将光栅图像如照片等的显示方式定义为默认每一个图像大小为 1px,一个 “600x400” 解析度的照片的长宽分别为 “600px” 和 “400px”,因此照片自己像素并不会与显示装置像素(可能很是小)一致,而是与单位 px 一致,如此就能够将图像完整的与网页其余元素排列起来
  • 相对单位,如:%、em、rem、vw、vh、vmin、vmax
    • %:子元素的百分比相对的数值是父级里对应属性的值,如父级的高度是 100px,子级的 50% 就是 50px
    • em:须有个参照值,该参照值不是固定的,而是不一样属性有不一样的参照值
      • font-size:em 的计算方式是相对于父元素的字体大小,1em 等于父元素设置的字体大小,若父元素没有设置字体大小则继续往上查找,若都没有设置大小则使用浏览器默认的字体大小
      • 其余属性(border、width、height、padding、margin、line-height):em 的计算方式是参照该元素的字体大小,1em 等于该元素设置的字体大小,同理若该元素没有设置则一直向上查找,若都没有设置则使用浏览器默认的字体大小
    • rem:rem 的参照物是固定的,相对根元素 html 的 font-size 来计算,rem 的 r 就是 root,CSS3新加属性,有些浏览器不兼容,哪怕在移动端安卓 4.3 如下也是不兼容,不过长远来讲这也是必备的
    • vw/vh/vmin/vmax
      • 基于视窗大小(浏览器用来显示内容的区域大小)来计算的
      • 网页中不少时候须要用到满屏或屏幕大小的一半等,尤为是移动端,屏幕大小各式各样,这四个就很适合
      • vw:基于视窗的宽度计算,1vw 等于视窗宽度的百分之一
      • vh:基于视窗的高度计算,1vh 等于视窗高度的百分之一
      • vmin:基于 vw 和 vh 中的最小值来计算,1vmin 等于最小值的百分之一
      • vmin:基于 vw 和 vh 中的最小值来计算,1vmin 等于最小值的百分之一

chrome 浏览器的最小字体是 12px,就算设置为 10px 也会渲染成 12px

盒模型

概念

  • 当对一个文档进行布局(layout)时,浏览器的渲染引擎会根据标准之一的 CSS 基础框盒模型(CSS basic box model),将每一个元素都描述为一个个矩形的盒子(box),这些盒子经过一个模型来描述其占用空间,CSS 决定这些盒子的大小、位置以及属性(例如颜色、背 景、边框尺寸...)
  • 一个盒子由 4 个部分组成:外边距(margin)、边框(border)、内边距(padding)、内容区(content)
    • content 不是由属性构成,由咱们写的内容和 width、height 属性构成
    • margin 它设置是这个元素距离外面靠近它的元素或浏览器边框的距离,这是一个复合属性:margin-top、margin-right、margin-bottom、margin-left 组成,也可分开写设置每一个属性的属性值,该复合值有 4 种写法
      • 4个值:按照上、右、下、左的顺序
      • 3个值:按照上、左右、下的顺序
      • 2个值:按照上下、左右的顺序
      • 1个值:四个方向是同个值
    • padding 也是复合属性(参考 margin)

注意:body 元素有个默认的 8px 的 margin,同时还发现标签默认也有一些 margin。由于这些样式可能对布局形成影响,通常须要去掉这些默认样式:在开发中通常使用 *{} 通配符选择器来初始化样式,由于通配符的优先级最低,后面若想要加样式,随便一个样式设定都会高于通配符选择器,但若没有设置的话浏览器就会将默认样式为设置的初始化样式

盒模型.png

盒子计算

  • CSS 的盒子模型有两种:标准的 W3C 盒子模型模型、怪异(IE)盒子模型
  • 标准的 W3C 盒子模型模型
    • 在 W3C 标准下定义元素的 width 值即为盒模型中的 content 的宽度值,height 值即为盒模型中的 content 的高度值,所以标准盒模型下:
      width = content 的宽度
      height = content 的高度
      盒子实际占位宽度 = width(内容宽度) + margin-left + border-left + padding-left + padding-right + border-right + margin-right
      盒子实际占位高度 = height(内容高度) + margin-top + border-top + padding-top + padding-bottom + border-bottom + margin-bottom
      复制代码

标准盒子模型.png

  • 怪异盒子模型
    • 而 IE 怪异盒模型(IE8 如下),width 的宽度并非 content 的宽度,而是 border-left + padding-left + content 的宽度值 + padding-right + border-right,height 同理
      width = border-left + padding-left + content 的宽度值 + padding-right + border-right
      height = border-left + padding-left + content 的宽度值 + padding-right + border-right
      盒子实际占位宽度 = margin-left + content + margin-right
      盒子实际占位高度 = margin-top + content + margin-top
      复制代码

怪异盒子模型.png

盒模型的转换方式

  • 现代浏览器默认使用 W3C 的标准盒模型,但有时可能须要怪异盒模型,则可以使用 W3C 在 CSS3 中加入的 box- sizing
box-sizing: content-box // 标准盒模型,默认值
box-sizing: border-box // 怪异盒模型
复制代码

注意:
一、只有 firefox 浏览器支持 padding-box 属性值
二、IE 浏览器在 getComputedStyle 获得 width/height 是按照标准模式计算的,而不论 box-sizing 的取值

格式化上下文

  • 默认状况下盒子按照元素在 HTML 中的前后位置从左至右自上而下一个接着一个排列摆放
  • 不一样的盒子使用的是不一样的格式化上下文(formatting context)来布局,每一个格式化上下文都拥有一套不一样的渲染规则,它决定了其子元素将如何定以及和其余元素的关系和相互做用

BFC

  • 块级格式化上下文(Block Format Context)
  • 在 W3C 规范中对 BFC 的定义
    • 浮动元素、绝对定位元素、非块级盒子的块级容器(如 inline-block、table-cells 和 table-captions)、overflow 值不为 visiable 的块级盒子,都会为他们的内容建立新的 BFC(块级格式上下文)
    • 在 BFC 中,盒子从顶端开始垂直地一个接一个地排列,两个盒子之间的垂直的间隙是由他们的 margin 值决定,两个相邻的块级盒子的垂直 margin 会产生合并
    • 在 BFC 中每一个盒子的左外边缘 margin-left 会触碰到容器的左边缘border-left,相反则触碰到右边缘
  • MDN 对 BFC 的定义:块格式化上下文(Block Formatting Context,BFC)是 Web 页面可视化 CSS 渲染的一部分,是布局过程当中生成块级盒子的区域,也是浮动元素与其余元素的交互限定区域
  • 简而言之,BFC 是一块独立的渲染区域,让处于 BFC 内部的元素与外部的元素互相隔离,该区域内全部元素的布局不会影响到区域外元素的布局。它决定了其子元素 将如何定位以及和其余元素的关系和相互做用,这个渲染区域只对块级元素起做用
  • BFC 渲染规则
    • 块级盒会在垂直方向一个接一个地放置,每一个盒子水平占满整个容器空间
    • 块级盒的垂直方向距离由上下 margin 决定,同属于一个 BFC 中的两个或两个以上块级盒相接的 margin 会发生重叠,都为正值则取最值、一正一负则取相加后的值、都为负则取绝对值大的那个,不一样 BFC 垂直方向 margin 不合并
    • 计算 BFC 的高度时浮动元素也参与计算
  • 触发 BFC
    • 根元素(html 元素)或包含根元素的元素
    • 浮动元素(float 的属性不为 none)
    • 绝对定位元素(position 为 absolute 或 fixed)
    • overflow 值不为 visible 的块元素(hidden、auto、scroll)
    • 行内块元素(元素的 display 为 inline-block)
    • 表格单元格(元素的 display为 table-cell,HTML 表格单元格默认为该值)
    • 表格标题(元素的 display 为 table-caption,HTML 表格标题默认为该值)
    • 弹性盒子元素(display 为 flex 或 inline-flex)
    • 网格元素(display 为 grid 或 inline-grid)
    • display 值为 flow-root 的元素
    • contain 值为 layout、content或 strict 的元素

块格式化上下文

  • BFC 的做用
    • margin 合并现象
      如两个 div,分别给它们加上 margin-bottom 和 margin-top 为 10 px 的样式,这两个 div 上下之间的距离并非相加的 20px,而是只有 10px!

      <div class=”top”>top</div>
      <div class=”bottom”>bottom</div>
      复制代码

      解决:给每一个 div 分别加上一个父级包裹层,而后给父级包裹层都加上 overflow:hidden; 经过父级 div 来触发 BFC 就能够解决 margin 合并的问题

      <div class=”wrapper”>
          <div class=”top”>top</div>
      </div>
      <div class=”wrapper”> <div class=”bottom”>bottom</div> </div>
      复制代码
    • margin 塌陷现象
      当给如示例中的结构的两个 div 分别设置 margin-top 时,这个 bug 就会出现了

      <div class=”wrapper”>
       <div class=”content”></div>
      </div>
      .wrapper {
         width: 100px;
         height: 100px;
         margin-top: 100px;
         margin-left: 100px;
         background-color:yellow;
      }
      .content {
         width: 50px;
         height: 50px;
         margin-top: 50px;
         margin-left: 50px;
         background-color: red;
      }
      复制代码

      这段代码的原意是想要一个 100100 大小的父级 div,里面有一个 5050 大小的子级 div,让这个 div 在父级 div 的右下角,同时父 div 距离浏览器的边框有 100px 的距离

      margin塌陷_1.png
      实际的结果是子级 div 的 margin-top 的效果并非距离父级 div 50px,而是子级的 div 距离浏览器边框的距离是 50px,因为自己父级 div 有一个 margin-top 的值,因此就致使了子级的 margin-top 的效果并无显现出来,再改变一会儿级 div 的 margin-top 的值为 200px,子级 div 不只没有距离父级 div 有一段距离,反而带动了父级 div 一块儿向下移动了!这就是 margin 塌陷现象 margin塌陷_2.png

      解决:
      一、利用 border 来触发 BFC 的效果:margin 塌陷问题很容易让人联想到子 div 之因此没有相对父级移动是由于看不到父级的边界,只能看到浏览器的边界,给父级加一个子级能看到的边界这个问题是否是就解决了?因此在父级 div.wrapper 里添加个属性:border-top: 1px solid red; 果真 content 和 wrapper 解除了绑定,子级 div 能看到父级的边界,可是这样就会改变父级 div 的样式,不符合开发要求,所以这种方法虽然能够解决问题可是是彻底没法使用的
      二、利用 overflow 来触发 BFC 的效果:如今在父级 div.wrapper 里面加一条属性:overflow: hidden; 这条属性的意思是溢出隐藏,在外观没有改变的同时,子 div 和父 div 解除了绑定,能正常移动了!通常采用这种方式来解决 margin 塌陷的问题。

      注意:虽然这种的方式能够采用,但也不是没有缺点。一旦用 JS 代码改变了子级 div 的位置,就会有可能致使子级一部份内容由于溢出被隐藏的风险

    • 两栏布局,防止文字环绕等
      以下代码

      <div class='div1'></div>
      <div class='div2'></div>
      .div1 {
          float:left;
          height:400px;
          width:200px;
          border:2px solid red;
      }
      .div2 {
        height:400px;
        border:5px solid green;
      }
      复制代码

      两栏布局_1.png

      触发 BFC

      .div1 {
          float:left;
          height:400px;
          width:200px;
          border:2px solid red;
      }
      .div2 {
          height:400px;
          border:5px solid green;
          display:flex;
      }
      复制代码

      两栏布局_2.png

  • BFC 与 hasLayout
    • *zomm: 1 的属性,这是 IEhack ,由于 IE6-7 并不支持 W3C 的 BFC ,而是使用私有属性 hasLayout 。
    • 从表现上来讲 hasLayout 跟 BFC 很类似,只是 hasLayout 自身存在不少问题,致使了 IE6-7 中一系列的 bug
    • 触发 hasLayout 的条件与触发 BFC 有些类似,推荐为元素设置 IE 特有的 CSS 属性 zoom: 1 触发 hasLayout
    • zoom 用于设置或检索元素的缩放比例,值为“1”即便用元素的实际尺寸,使用 zoom: 1 既能够触发 hasLayout 又不会对元素形成其余影响,相对来讲会更为方便
    • 须要注意既然 hasLayout 有着跟 BFC 类似的功能,那在实际开发中就要为须要触发 BFC 的元素同时触发 hasLayout ,这样 BFC 和 hasLayout 具备的一些特殊性质能够在现代浏览器和 IE 中同时产生,避免一个元素在不一样浏览器间的表现由于 BFC 或 hasLayout 出现差别
    • 事实上在实际开发中不少莫名其妙的问题其实都是所以而产生的。固然一样地,若是一个元素没有触发 BFC 也要尽可能保证它没有触发 hasLayout

image.png

深刻理解BFC

IFC

  • 行内格式化上下文中(Inline Formatting Context)
  • 相对于块格式化上下文,盒子一个接一个地水平排列,起点是包含块的顶部,视觉上它将内容与其它行内级元素排列为一行,直到该行被占满而后换行
  • 水平方向上的 margin、border 和 padding 在盒子之间获得保留
  • 盒子在垂直方向上能够以不一样的方式对齐:顶部或底部对齐,或根据其中文字的基线对齐
  • 行内级盒分为行内盒(inline boxes)和原子行内级盒(atomic inline-level boxes),前者由非置换元素且 display 值为 inline 的元素生成;后者由行内级置换元素或 display 值为 inline-block、inline-table、inline-flex、inline-grid 的元素生成,典型的可替换元素有 <img>、 <object>、 <video> 和 表单元素,如 <textarea>、 <input>
    • 对于非替换元素,如 a,span 等标签能够设置水平方向上的 margin 可是没法设置垂直方向的 margin,至于 border 和 padding,垂直方向能够设置可是当 border-top 和 padding-top 到达页面顶部后就再也不增长了
    • 对于替换元素如 input、img 等标签,能够正常使用 margin、border、padding 的
  • IFC 渲染规则
    • IFC 中的行内级盒将会按照以下规则进行渲染(规则有点多,大概主要点就是行盒,折行机制,水平对齐方式,垂直高度及垂直对齐方式)
    • 盒子一个接一个水平摆放,当容器宽度不够时就会换行
    • 在水平方向上这些盒的外边距、边框、内边距所占用的空间都会被计算,但行内盒的垂直的 border、padding、margin 都不会撑开行盒的高度
    • 在垂直方向上,这些盒可能会以不一样形式来对齐,可经过 vertical-align 来设置,默认对齐为 baseline
    • 每一行将生成一个行盒(line box),包括该行全部的盒子,行盒的宽度是由包含块和存在的浮动来决定
    • 行盒通常左右边都贴紧其包含块,可是会由于浮动盒(float 元素)的存在而发生变化。浮动盒会位于包含块边缘与行盒边缘之间,这样行盒的可用宽度就小于包含块的宽度
    • 当全部盒的总宽度小于行盒的宽度,那么行盒中的水平方向排版由 text-align 属性来决定
    • 当一个行内盒超过行盒的宽度时,它会被分割成多个盒,这些盒被分布在多个行盒里。若一个行内盒不能被分割(好比只包含单个字符,或 word-breaking 机制被禁用,或该行内框受 white-space 属性值为 nowrap 或 pre 的影响),那么这个行内盒将溢出这个行盒
    • 当一个行内盒发生分割时,分割处的 margins、borders、 padding 不会有任何视觉效果(或其余任何分裂,只要是有多个行盒)
    • 行盒的高度由内部元素中实际高度最高的元素计算出来。每一个行盒的高度因为内容不同,因此高度也可能不同
    • 在一个行盒中,当包含的内部容器的高度小于行盒的高度时,内部容器的垂直位置可由本身的 vertical-align 属性来肯定

注:在 IFC 的环境中是不能存在块级元素的,若是将块级元素插入到 IFC 中,那么此 IFC 将会被破坏掉变成 BFC,而块级元素前的元素或文本和块级元素后的元素或文本将会各自自动产生一个匿名块盒其包围

定位

  • CSS 中元素的层次模型主要是由 position 属性来决定的
  • position 的意思是定位,一样该属性的做用就是给元素施加定位
  • static:默认属性,当没有设置 position 属性时元素默认的定位就是 static 定位,元素出如今正常的流中,此时 top, right, bottom, left 和 z-index 属性无效
  • relative:相对定位,此时的『相对』是相对于其在正常文档流的位置进行定位
    • 当 position 改为 relative 后 left、top、right、bottom 进行的定位就会变成相对于自身的位置进行移动
    • relative 的参照物是元素自身
    • **当仅仅给元素设置 position:relative 并没设置 left、right、top、bottom 属性时,元素的定位是没有发生任何改变的,由于这个特性,通常在开发中 relative 都是用做设置参照物的,一个 absolute 元素要相对于某个元素进行移动就给那个元素设置 relative **
  • absolute:绝对定位
    • 绝对定位,它会使元素脱离原本的位置再进行定位,它会使元素像立交桥同样出现空间上的分层,当元素脱离原来的位置后其余的元素就会“看不到”这个元素,同时 absolute 也能够触发 BFC
    • absolute 的参照物是距离它最近的有定位(除了 static)的父级,当每一个父级都没有定位时元素会相对于浏览器边框进行定位
    • 当使用绝对定位后可使用 left、right、top、bottom 这四个属性分别设置当前元素距离左边、右边、上边和下边的距离,通常都是两两一对出现,其中 left 和 top 是一对,right 和 bottom 是一对
  • fixed:绝对定位
    • fixed 定位是相对于视口的定位,网页上下左右两边不随着滚轮滚动而改变位置的广告栏,通常就是用 fixed
  • 粘性定位,特性近似于relative和fixed的合体,其在实际应用中的近似效果就是IOS通信录滚动的时候的 『顶屁股』

    codepen.io/xiaomuzhu/p…

z-index

  • z-index 属性用于指定已定位元素在垂直于页面方向的排列顺序,其属性值有 2种:auto(默认值)和整数
    • z-index 属性只对定位元素元素生效,即 position 属性不为 static 的元素
    • 除了默认值 auto, z-index 能够设置为任意整数,正数、0、负数
  • 通常状况下,z-index 值进行比较有下面 2 条规则
    • 数值大的在上面,auto 数值上至关于 0
    • 数值相同的在 HTML 结构中排后面的在上面
  • z-index 默认值 auto 数值上等于 0,z-index: 0; 和默认的 z-index:auto; 是有区别的
    • 设置了 z-index 属性为整数值包括 0 的元素,自身会建立一个层叠上下文,而建立一个层叠上下文后其子元素的层叠顺序就相对于父元素计算,不会与外部元素比较
  • 在进行 z-index 比较时要留意其祖先元素有没有创建独立的层叠上下文,z-index 只有在同个层叠上下文中比较才有意义
  • 咱们能够把视图上的元素认为是一摞书的层叠,而人眼是俯视的视⻆,设置 z-index 的位置就如同设置某一本书在这摞书中的位置
    顶部: 最接近观察者 
    ...
    3210 层 默认层 
    -1 层
    -2 层
    -3 层 
    ...
    底层: 距离观察者最远
    复制代码

层叠上下文和层叠顺序

层叠上下文

  • 层叠上下文 stacking context 是 HTML 中一个三维的概念,在 CSS2.1 规范中每一个盒模型的位置是三维的,分别是平面画布上的 X 轴、Y 轴以及表示层叠的 Z 轴。通常状况下元素在页面上沿 X 轴、Y 轴平铺,察觉不到它们在 Z 轴上的层叠关系,而一旦元素发生堆叠,这时就能发现某个元素可能覆盖了另个元素或被另个元素覆盖,HTML 元素依据其自身属性按照优先级顺序占用层叠上下文的空间
  • 若一个元素含有层叠上下文(即它是层叠上下文元素),能够理解为这个元素在 Z 轴(表示的是用户相对于面向(电脑屏幕的)视窗或网⻚的这条看不见的垂直线)上就“高人一等”,最终表现就是它离屏幕观察者更近
  • 特性
    • 层叠上下文的层叠水平要比普通元素高
    • 层叠上下文能够阻断元素的混合模式
    • 层叠上下文能够嵌套,内部层叠上下文及其全部子元素均受制于外部的层叠上下文
    • 每一个层叠上下文和兄弟元素独立,即当进行层叠变化或渲染时只须要考虑后代元素
    • 每一个层叠上下文是自成体系的,当元素发生层叠时整个元素被认为是在父层叠上下文的层叠顺序中
  • 如何产生?
    • HTML 中的根元素 自己就具备层叠上下文,称为“根层叠上下文”
    • 普通元素设置 position 属性为非 static 值并设置 z-index 属性为具体数值(非 auto),产生层叠上下文
    • 一个 z-index 值不为 auto 的 flex 项目 (flex item),即:父元素 display: flex|inline-flex
    • opacity 属性值小于 1 的元素(参考 the specification for opacity)
    • transform 属性值不为 none 的元素,
    • mix-blend-mode 属性值不为 normal 的元素
    • filter 值不为 none 的元素
    • perspective 值不为 none 的元素
    • isolation 属性被设置为 isolate 的元素
    • 在 will-change 中指定了任意 CSS 属性,即使没有直接指定这些属性的,关于 will-change 能够参见该文章:使用CSS3 will-change提升页面滚动、动画等渲染性能
    • -webkit-overflow-scrolling 属性被设置 "touch"的元素

层叠水平/等级(stacking level)

  • 在同个层叠上下文中元素在 Z 轴上的显示顺序,普通元素的层叠水平优先由层叠上下文决定,所以层叠水平的比较只有在当前层叠上下文元素中才有意义
  • 在其余普通元素中它描述定义的是这些普通元素在 Z 轴上的上下顺序

层叠顺序

  • 层叠顺序 stacking order 表示元素发生层叠时按照特定顺序规则在 Z 轴上垂直显示,所以前面所说的层叠上下文和层叠等级是一种概念,而层叠顺序是一种规则
  • 在不考虑 CSS3 的状况下当元素发生层叠时,层叠顺讯遵循下面的规则,这里值得注意的是
    • 层叠上下文 background/border 指的是层叠上下文元素的背景和边框,每一个层叠顺序规则适用于一个完整的层叠上下文元素
    • 原图没有呈现 inline-block 的层叠顺序,实际上 inline-block 和 inline 水平元素是同等 level 级别
    • z-index: 0 实际上和 z-index: auto 单纯从层叠水平上看是能够当作是同样的,实际上二者在层叠上下文领域有着根本性的差别
  • 为何内联元素的层叠顺序要比浮动元素和块状元素都高?
    • border/background 等通常为装饰属性,浮动和块状元素通常用做布局,而内联元素通常都是页面内容,网页中最重要的固然是内容,所以必定要让内容的层叠顺序至关高,当发生层叠时重要的文字、图片内容能够优先暴露在屏幕上

层叠顺序.png

总结

  • 首先先看要比较的两个元素是否处于同一个层叠上下文中
  • 若是是谁的层叠等级大,谁在上面
  • 若是两个元素不在同一层叠上下文中,请先比较他们所处的层叠上下文的层叠等级
  • 当两个元素层叠等级相同、层叠顺序相同时,在 DOM 结构中后面的元素层叠等级在前面元素之上

层叠上下文-张鑫旭

浮动

  • float 属性可以让元素像站队同样浮动起来,它会让原本占满整行的元素只按照内容和设置大小来在父级里面进行站队排列,当这一行剩余的空间不足以再放下个元素时元素就会自动换行,到下一行去进行浮动排列;当容器不够大时虽然内容会超出容器范围,可是超出以后仍然是按照相同队形来进行站队

  • 浮动起来的元素会像 absolute 的元素脱离文档流,但不会脱离文字流,这是什么意思呢?

    • 脱离文档流的意思就是正常元素看不到它,不脱离文字流的意思则是 display 属性是 inline 或 inline-block 的元素仍是能够看到它的,文字自己是 inline 属性的
    • float 属性会自动将这个元素的 display 改为 inline-block ,即不论给 display 加上什么值,只要有 float 属性,那这个元素就是 inline-block 属性
  • float 属性只有两个值:left、right,默认状态是 none

  • float 属性的做用

    • 对元素进行布局
    • 像 absolute 同样,让元素浮动起来,产生本身独有的浮动流
  • 浮动流有两个效果

    • 脱离标准的文档流但不会脱离文字流 ,正常元素看不到它,但有文字属性 inline 或文字自己能够看到它
    • 在内部会把该元素变换成 inline-block 属性的元素
  • 使用 float 属性

    • 通常是使用网状布局时使用,当不知道容器里面会盛放多少个子元素,但这些子元素又是按照同样格式进行排列,设置浮动来进行流式布局
      浮动_1.png
    • 实现像报纸那样文字包围在图片四周的效果 浮动_2.png
  • 浮动元素会引发的问题

    • 父元素的高度没法被撑开,影响与父元素同级的元素
    • 与浮动元素同级的非浮动元素会跟随其后
    • 若非第一个元素浮动,则该元素以前的元素也须要浮动,不然会影响页面显示的结构
  • 清除浮动

  • 清除浮动主要是为了解决因为浮动元素脱离文档流致使的元素重叠、父元素高度坍塌的问题,而这两问题分别对应了须要清除浮动的两种状况:清除前面兄弟元素浮动闭合子元素浮动(解决父元素高度坍塌)

  • 清除前面兄弟元素浮动

    • 只需在不想受到浮动元素影响的元素上使用 clear: both 便可
    • 在 CSS2 之前 clear 的原理为自动增长元素的上外边距(margin-top)值,使之最后落在浮动元素的下面
    • 在 CSS2.1 中引入了一个清除区域(clearance):在元素外边距之上增长额外间距,使之最后落在浮动元素的下面,因此若须要设置浮动元素与 clear 元素的间距,得设置浮动元素的 margin-bottom,而不是 clear 元素的 margin-top
  • 闭合子元素浮动

父元素高度坍塌问题:在计算页面排版时,若没设置父元素的高度,那么该父元素的高度是由他的子元素高度撑开的,但若子元素是设置了浮动,脱离文档流,那父元素计算高度时就会忽略该子元素,甚至当全部子元素都是浮动时就会出现父元素高度为 0 的状况

  • 解决办法

    • 在父级里内容区最后加个 p(div等)标签,给该 p 标签增长清除浮动的样式
      1)实际上并非父级清除了浮动流,而是被 p 标签撑开了,p.clear 能看到上面浮动的元素,wrapper 能看到不浮动的 p 标签,所以把 p 标签包裹进去了
      2)虽然该办法比较直观,但不是很优雅,由于增长了一个无用的空白标签,比较冗余且不方便后期维护(通常不太建议使用该办法)
      <div class=”wrapper”>
        <div class=”content”>1</div>
        <div class=”content”>2</div>
        <div class=”content”>3</div>
        <div class=”content”>4</div>
        <p class=”clear”></p>
      </div>
      .clear {
          clear: both;
      }
      复制代码
  • 添加伪元素

    • 为父级元素添加一个 after 伪元素,让这个伪元素专门实现清除浮动的功能
      .wrapper::after {
          content: "";
          clear: both;
          display: block; // 能清除浮动的元素,必须是块级元素
      }
      复制代码

      一、伪元素是一种不能单独存在的元素,它必需要依附于其余正式元素标签上使用,单独写是没有任何意义的,伪元素最经常使用的有两个 afterbefore,当不想改变 html 结构又想要增添一些东西时,伪元素 after、before 就很是实用
      二、注意写伪元素,即便内容是空的也要加上 content 这个属性: content: " "
      三、既然是伪元素那天然也属于元素,可改变伪元素的 display 为 block,从而可改变宽高等块级元素才有的样式

  • 触发 BFC 的方式来清除浮动(触发方式请见本文相关 BFC 部份内容)

  • 注意

    • IE6 / IE7 并无伪元素这种东西,但其独有 hasLayout,只要触发了 hasLayout 就和触发 BFC 有差很少的做用,可以触发这个东西的属性有不少,其中最无害的属于 zoom 属性,只要写上这个属性 IE6 / IE7 也可清除浮动
    • 不过其余浏览器并不需 zoom 属性,该属性只是为了 IE6 / IE7 准备的,因此须要一点点 CSS hack,在 zoom 前加一个符号,**zoom: 1; 该符号只有 IE6 / IE7 可以识别,其余的浏览器都不识别,属性前面加上’_‘后就只有 IE6 能够识别 _zoom: 1;
      .wrapper {
          zoom: 1; //视口同比例放大仍是缩小,1 就是不变
      }
      复制代码

CSS3

简介

CSS3 是 CSS2 的升级版本,3 只是版本号,它在 CSS2.1 的基础上增长了不少强大的新功能,目前主流浏览器 chrome、safari、firefox、opera、甚至 360 都已经支持了 CSS3 大部分功能,IE10 之后也开始全面支持 CSS3

CSS3 前缀

  • 在编写 CSS3 样式时不一样的浏览器可能须要不一样的前缀,它表示该 CSS 属性或规则还没有成为 W3C 标准的一部分,是浏览器的私有属性,虽然目前较新版本的浏览器都是不须要前缀的,但为了更好的向前兼容前缀仍是少不了的,标准写法如表顺序,再在后面添加无前缀的
    前缀 浏览器
    -webkit chrome/safari
    -moz firefox
    -ms IE
    -o opera

CSS3 功能

  • 提供了更增强大且精准的选择器,提供多种背景填充方案,可实现渐变颜色,可改变元素的形状、角度等,能够加阴影效果,报纸布局,弹性盒子,ie6 混杂模式的盒模型,新的计量单位,动画效果等等...
  • 但 CSS3 的兼容性问题一样也显得格外重要,并非全部 CSS3 属性都经过了 W3C 标准,须要全面的兼容性查阅手册

详细可阅读 CSS3 教程

扩展

有哪些方式(CSS)能够隐藏⻚面元素?

  • display: none,自身及全部的子元素都完全隐藏,好像不存在,既不占据空间也不可交互
  • visibility: hidden,元素的大小不变,仍占据空间,可理解为透明,但不可交互。但子元素设置为visibility:visible,则该子元素依然可见
  • overflow: none,规定了当内容元素溢出父容器时隐藏元素溢出的部分,使用滚动条来显示或直接显示超出部分,占据空间且不可交互
  • z-index: -9999:原理是将层级放到底部,这样就被其余层级元素覆盖,看起来隐藏了
  • opacity: 0:本质上是将元素的透明度将为 0,看起来隐藏了,但依然占据空间且可交互
  • transform: scale(0, 0):平面变换,将元素缩放为0,占据空间但不可交互
  • 还有一些靠绝对定位把元素移到可视区域外或用 clip-path 进行裁剪的操做等

水平间距问题

  • 在写页面时的导航时,通常须要将 display 属性设置为 inline-block,此时会致使在两个导航元素间出现大约 8px 左右的空白间隙

    <div class="nav">
      <div class="nav-item"><a>导航</a></div>
      <div class="nav-item"><a>导航</a></div>
      <div class="nav-item"><a>导航</a></div>
    </div>
    .nav {
      background: 999;
    }
    .nav-item {
      display: inline-block;
      width: 100px;
      background: #ddd;
    }
    复制代码
  • 缘由是由于编写代码时输入空格、换行都会产生空白符,而浏览器是不会忽略空白符的且对于多个连续的空白符浏览器会自动将其合并成一个,故产生了所谓的间隙

    空白间隙.png

  • 解决方案

    • 代码不换行。因为换行空格致使产生换行符,所以可将上述例子中的列表 item 写成一行,这样空白符便消失,间隙就不复存在。但考虑到代码可读及维护性,通常不建议连成一行的写法
      <div class="nav">
         <div class="nav-item">导航</div><div class="nav-item">导航</div><div class="nav-item">导航</div>
      </div>
      复制代码
    • 设置 font-size
      一、首先要理解空白符归根结底是个字符,所以可经过设置 font-size 属性来控制产生的间隙的大小,若将 font-size 设置为 0,文字字符是无法显示的,一样这个空白字符也没了,间隙也就没了
      二、经过设置父元素的 font-size 为 0 来去掉这个间隙,而后重置子元素的 font-size,让其恢复子元素文字字符,使用该方法时须要特别注意其子元素必定要重置 font-size,否则很容易掉进坑里(文字显示不出来)
      .nav {
          background: #999;
          font-size: 0; /* 空白字符大小为0 */
      }
      .nav-item {
          display:inline-block;
          width: 100px;
          font-size: 16px; /* 重置 font-size 为16px*/
          background: #ddd;
      }
      复制代码
    • 原本觉得上面可以彻底解决问题,但经测试将父级标签字符设置为 0 在 Safari 浏览器依然出现间隔空白;既然设置字符大小为 0 不行,那咱就将间隔消除了,将下面代码替换上面的代码,目前测试完美解决。一样随来而来的问题是 item 内的字符间隔也被设置了,须要将其内的字符间隔设为默认
      .nav { letter-spacing: -5px; }
      .nav-item { letter-spacing: normal; }
      复制代码

溢出打点

  • 当文字超过所规定的范围后后面的所有文字就会变成 “…” 的形式来出现

  • 单行文字溢出打点,须要三个属性来配合使用

    • overflow: hidden; 实现让文字溢出容器的部分隐藏起来,方便后面的打点功能
    • text-overflow: ellipsis; 文字溢出以后怎么处理,ellipsis 是指处理方式是以点状显示
    • white-space: nowrap; 让文字不换行,文字的默认状态是换行的,当到达容器壁以后自动换到下一行,该属性让文字一直在一行显示,即便到了容器壁也不换行
  • 多行文字溢出打点

    • 虽然有属性可达到多行文字溢出打点的功能,但兼容性十分很差,除了移动端的网页(由于移动端的浏览器通常版本都比较高)以外
    • pc 端的网页通常都是用其余方式来实现,像百度就是经过计算文字的宽高,而后在最后手写 “…” 来实现多行文字溢出打点效果
    • 而若想要以属性方式来完成多行文字溢出打点的功能,要用到如下属性
      • line-clamp 属性是指让文字显示几行。-webkit 是兼容 webkit 内核的浏览器,目前还有不少浏览器不支持 line-clamp 属性,只有 webkit 较高版本勉强支持
      • box-orient 也是很是勉强,所以该功能虽然存在,但因为兼容性问题不多有公司会使用
      • display: -webkit-box 是 CSS3.0 的一个属性
      text-overflow: ellipsis;
      overflow: hidden;
      display: -webkit-box;
      -webkit-line-clamp: 3; //行数
      -webkit-box-orient: vertical;  
      复制代码

如何让背景图片出不来时显示文字

  • 有时网页会被用户禁止加载图片和 CSS 样式,若没有给背景图片设置任何信息,那用户就彻底不知道这个空白地方是什么东西,因此要让图片加载不出来时也可以有文字展现出来,可使用如下两种方法来实现这种效果

text-indent

  • 比较传统的作法:利用 text-indent 配合 white-space: nowrap 、overflow: hidden; 让元素内部的文字在有 CSS 时会被缩进到元素外面并被隐藏起来,当 CSS 不能加载时文字不会被缩进,因此能够展现出来

背景图片放到 padding 里,高度强制为 0

  • background-image 是能够放到 padding 里,元素自己的高度为 0,利用 padding-top 撑起元素的内容区,这样当有 CSS 样式时配合 overflow: hidden 一块儿使用就可让文字隐藏,没有 CSS 样式时文字就会正常显示出来
.taobao-head .header .logo-bd {
    display: block;
    margin-left: 22px;
    width: 142px;
    padding-top: 58px;
    height: 0;
    overflow: hidden;
    background: url(xxxx) 0 0 no-repeat;
}
复制代码

为何有时用 translate 来改变位置而不是定位?

  • translate 是 transform 的一个值,改变 transform 或 opacity 不会触发浏览器从新布局(reflow)或重绘(repaint),只会触发复合(compositions)
  • 而改变绝对定位会触发从新布局,进而触发重绘和复合
  • transform 使浏览器为元素建立一个 GPU 图层,但改变绝对定位会使用到 CPU,所以 translate 更高效,能够缩短平滑动画的绘制时间
  • 而 translate 改变位置时元素依然会占据其原始空间,绝对定位就不会发生这种状况
相关文章
相关标签/搜索