深入CSS

96 阅读6分钟

深入学习CSS

这是我参与「第四届青训营 」笔记创作活动的的第2天

1、选择器的优先级

开篇:如下代码中,哪个选择器会生效?

 <article>
   <h1 class = "title">
     拉森火山国家公园
   </h1>
 </article>
 ​
 <style>
   .title {
     color: blue;
   }
   article h1 {
     color:red;
   }
 </style>

涉及到:选择器的优先级问题

特异度: 选择器的特殊程度

#id > . (伪)类 > E标签

 <button class="btn">普通按钮</button>
 <button class="btn primary">主要按钮</button>
 <style>
   .btn {
     display: inline-block;
     padding: .36em .8em;
     margin-right: .5em;
     line-height: 1.5;
     text-align: center;
     cursor: pointer;
     border-radius: .3em;
     border: none;
     background: #e6e6e6;
     color: #333;
   }
   .btn.primary {
   <!--两个类 优先级高于上面 故该选择器中渲染的 colorbackground 将覆盖初始所写的两个-->
   <!--可以较好地实现复用-->
     color: #fff;
     background: #218de6;
   }
 </style>

image.png

2、继承

定义:某些属性会自动继承其父元素的计算值,除非显示地指定一个值

在CSS中,与文字相关的属性一般都是可以继承的,与盒模型相关的是不可继承的

 <p>
   This is a <em>test</em> of <strong>inherit</strong>
 </p>
 ​
 <style>
   body {
     font-size: 20px;
   }
   p {
     color: blue;
   }
   em {
     color: red;
   }
   
   <!--在这里, strong 标签没有被定义颜色,故其寻找它的父元素 p 标签。 跟随 p 标签显示为蓝色-->
 </style>
  • 显示继承: inherit

如下所示:box-sizing 是一个不可继承的属性,为将其变为可继承的,做显示继承

 * {
   box-sizing: inherit;
 }
 html {
   box-sizing: border-box;
 }
 .some-widget {
   box-sizing: content-box;
 }
  • 初始值:

在CSS中,每个属性都有一个初始值

background-color: transparent

margin-left: 0

可以使用initial关键字显式重置为初始值

background-color: initial

3、CSS求值过程

image.png

  • 计算值:在 resolving 阶段,将一些相对值或者关键字转化为绝对值,浏览器会在不进行实际布局的情况下,所能得到的最具体的值 继承inherit的是父级的计算值
  • 实际值:在formatting阶段,将计算值进一步转换(比如:关键字、百分比等转化为绝对值),这是在进行实际布局时使用的值,不会再有相对值或者关键字

4、布局(Layout)是什么?

  • 确定内容的大小和位置的算法
  • 依据元素、容器、兄弟节点和内容等信息来计算

布局相关技术:

  • 常规流

    • 行级、块级、表格布局、FlexBox、Grid布局
  • 浮动
  • 绝对定位

盒模型:box

image.png

  1. width:指定 content box 宽度

    取值为:长度、百分数(相对于容器的 content box 宽度)、auto(由浏览器根据其他属性所决定)

  2. height:指定 content box 高度

    取值为:长度、百分数(相对于容器的 content box 高度 当容器有指定的高度时,百分数才生效! )、auto(由内容计算得来)

  1. padding:指定元素四个方向的内边距

    上 右 下 左

    百分数相对于容器宽度

  1. border:指定容器边框 样式、粗细和颜色

    border-style样式:实线 虚线 点画线 none

    border-width粗细

    border-color颜色

    四个方向:border-top/right/bottom/left

当四条边框颜色不同时,将会切割

  1. margin:指定元素四个方向的外边距

    取值可以是长度、百分数(相对于容器的 content box 宽度)、auto

在垂直方向上,margin将会合并 。

如上一盒子下外边框为100px,下一盒子上外边框也为100px,则得到的结果为:上下两个盒子之间的间距为100px(或者,当不一样时,会取较大的一个)

image.png

  1. box-sizing: border-box

height 和 width 将会包含border和padding的边距

  1. overflow:文本框溢出

    overflow: visible/hidden/scroll

    意为:盒子的宽高定下之后,可能其中的内容将会超出盒子。visible:超出部分可显示,hidden:超出部分隐藏,scroll:滚动条形式

块级 vs 行级

Block Level BoxInline Level Box
不和其他盒子并列摆放和其他行级盒子一起放在一行或拆开成多行
适用所有的盒模型属性盒模型中 width、height 不适用
块级元素行级元素
生成块级盒子生成行级盒子 内容分散在多个行盒(line box)中
body、article、div、main、section、h1~6、p、ul、li等span、em、strong、cite、code等
display:blockdisplay:inline

display属性:

  • block:块级盒子
  • inline:行级盒子
  • inline-block:本身是行级,可以放在行盒中;可以设置宽高;作为一个整体不会被拆散成多行
  • none:排版时完全被忽略

行级排版上下文:IFC

Inline Formatting Context

  • 只包含行级盒子的容器会创建一个IFC

  • IFC内的排版规则:

    • 盒子在一行内水平摆放
    • 一行放不下时,换行显示
    • text-align决定一行内盒子的水平对齐
    • vertical-align决定 一个盒子在行内的垂直对齐
    • 避开浮动元素
 <div>
   This is a paragraph of text with long word Honorificabilitudinitatibus. Here is an image
   <img src="https://assets.codepen.io/59477/cat.png" alt="cat">
   And <em>Inline Block</em>
 </div>
 ​
 <style>
   div {
     width: 10em;
     //overflow-wrap: break-word;
     background: #411;
   }
 ​
   em {
     display: inline-block;
     width: 3em;
     background: #33c;
   }
 </style>

块级排版上下文:BFC

Block Formatting Context

  • 某些容器会创建一个BFC:

    • 根元素
    • 浮动、绝对定位、inline-block
    • Flex子项和Grid子项
    • overflow值不是visible的块盒
    • display:flow-root
  • BFC内的排版规则:

    • 盒子从上到下摆放
    • 垂直margin合并
    • BFC内盒子的margin不会与外面的合并
    • BFC不会和浮动元素重叠

当既有块级又有行级的元素:

 <!--span本身是一个行级盒子 div是一个块级盒子-->
 <!--此时,创建两个匿名的盒子包裹上下两端文字-->
 <span>
   This is a text and
   <div>block</div>
   and other text.
 </span>
 ​
 <style>
   span {
     line-height: 3;
     border: 2px solid red;
     background: coral;
   }
 ​
   div {
     line-height: 1.5;
     background: lime;
   }
 </style>

image.png

FlexBox

FlexBox:是一种新的排版上下文

它可以控制子级盒子的:

  • 摆放的流向
  • 摆放顺序
  • 盒子宽度和高度
  • 水平和垂直方向的对齐
  • 是否允许拆行
 <div class="container">
   <div class="a">A</div>
   <div class="b">B</div>
   <div class="c">C</div>
 </div>
 <style>
   .container {
     display: flex;
     <!--创建一个flex布局的上下文-->
     border: 2px solid #966;
   }
 ​
   .a, .b, .c {
     text-align: center;
     padding: 1em;
   }
 ​
   .a {
     background: #fcc;
   }
 ​
   .b {
     background: #cfc;
   }
 ​
   .c {
     background: #ccf;
   }
 </style>

image.png

flex-direction ---控制流向 默认值是row

image.png

主轴与侧轴:

  • 主轴方向: 元素摆放的方向
  • 侧轴方向: 与主轴垂直的方向

image.png 属性justify-content:控制主轴

image.png

属性align-items 控制侧轴 默认值为stretch

image.png

align-self 给某一个元素设置特殊的对齐

image.png

order 排序

image.png

Flexibility : 可以设置子项的弹性: 当容器有剩余空间时, 会伸展; 容器空间不够时, 会收缩

flex-grow:有剩余空间时的伸展能力

flex-shrink:容器空间不足时的收缩能力

flex-basis:没有伸展或收缩时的长度

 <div class = "container">
   <div class="a">A</div>
   <div class="b">B</div>
   <div class="c">C</div>
 </div>
 ​
 <style>
   .container {
     display: flex;
   }
 ​
   .a, .b, .c {
     width: 100px;
   }
 ​
   .a {
     flex-grow: 2;
   }
 ​
   .b {
     flex-grow: 1;
   }
   <!--ab2:1的比例伸展-->
 </style>

image.png

 <div class="container">
   <div class="a">A</div>
   <div class="b">B</div>
   <div class="c">C</div>
 </div>
 ​
 <style>
   .container {
     display: flex;
   }
 ​
   .a, .b, .c {
     width: 400px;
   }
 ​
   .a {
     flex-shrink: 0;
     <!--表示 a块是刚性的-->
   }
 </style>

flex中的缩写:

image.png

Grid布局

flex是一个单一的方向上的布局

Grid是一个二级的

image.png

  • display: grid使元素生成一个块级的Grid容器
  • 使用 grid-template相关属性将容器划分为网络
  • 设置每一个子项占哪些行/列
 grid-template-colums:100px 100px 200px;
 grid-template-rows:100px 100px;
 ​
 grid-template-colums:30% 30% auto;
 grid-template-rows:100px auto;
 ​
 grid-template-colums:100px 1fr 1fr;
 grid-template-rows:100px 1fr;

grid line 网格线 :

对每条线进行编号,

image.png

image.png

 .a {
   grid-row-start: 1;
   grid-column-start: 1;
   grid-row-end: 3;
   grid-column-end: 3;
 }
 ​
 //或者写为:
 .a {
   grid-area: 1/1/3/3;
 }

float 浮动

图文混合 环绕

float:left

绝对定位

position属性 :

  • static: 默认值 非定位元素

  • relative: 相对自身原本位置偏移 不脱离文档流

    • 在常规流里面布局
    • 使用 top left bottom right 设置偏移长度
    • 流内其他元素当它没有偏移一样布局
  • absolute: 绝对定位 相对非static祖先元素定位(向上找 直到非static)

    • 脱离了常规流
    • 不会对流内元素布局造成影响
  • fixed: 相对于视口绝对定位

 <h1>页面标题</h1>
 <div class="container">
   <div class="box"></div>
   <p>段落内容段落内容 1</p>
   <p>段落内容段落内容 2</p>
   <p>段落内容段落内容 3</p>
   <p>段落内容段落内容 4</p>
 </div>
 ​
 <style>
   .container {
     background: lightblue;
   }
 ​
   .box {
     position: absolute;
     top: 0;
     left: 0;
     width: 100px;
     height: 100px;
     background: red;
   }
 </style>
 <nav>
   <a href="#">首页</a>
   <a href="#">导航1</a>
   <a href="#">导航2</a>
 </nav>
 <main>
   <section>1</section>
   <section>2</section>
   <section>3</section>
   <section>4</section>
   <section>5</section>
 </main>
 <a href="#" class="go-top">返回顶部</a>
 ​
 <style>
   nav {
     position: fixed;
     line-height: 3;
     background: rgba(0, 0, 0, 0.3);
     width: 100%;
   }
   
   .go-top {
     position: fixed;
     right: 1em;
     bottom: 1em;
     color: #fff;
   }
 ​
   nav a {
     padding: 0 1em;
     color: rgba(255, 255, 255, 0.7);
   }
 ​
   nav a:hover {
     color: #fff;
   }
 ​
   body {
     margin: 0;
     font-size: 14px;
   }
 ​
   a {
     color: #fff;
     text-decoration: none;
   }
 ​
   section {
     height: 100vh;
     color: #fff;
     text-align: center;
     font-size: 5em;
     line-height: 100vh;
   }
 ​
   section:nth-child(1) {
     background: #F44336;
   }
 ​
   section:nth-child(2) {
     background: #3F51B5;
   }
 ​
   section:nth-child(3) {
     background: #FFC107;
   }
 ​
   section:nth-child(4) {
     background: #607D8B;
   }
 ​
   section:nth-child(5) {
     background: #4CAF50;
   }
 </style>