【精读笔记】深入解析CSS 第一部分:基础回顾

第1章 层叠、优先级和继承

1.1 层叠

层叠规则

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yP358arK-1648781887720)(C:\Users\浅夏、\AppData\Roaming\Typora\typora-user-images\image-20220331113054614.png)]

1.1.1 样式表的来源

用户代理样式表:浏览器默认样式。

作者样式表:自己设置的样式。

作者样式覆盖用户代理样式,因为作者样式的优先级更高

!important声明

在声明的后面、分号的前面加上!important,该声明就会被标记为重要的声明

color: red !important;

总体的优先级

  1. 作者的!important
  2. 作者
  3. 用户代理

1.1.2 理解优先级

浏览器将优先级分为两部分:HTML的行内样式和选择器的样式

行内样式

如果用HTML的style属性写样式,这个声明智慧作用于当前元素。实际上行内元素属于“带作用域的”声明,它会覆盖任何来自样式表或者<style>标签的样式

选择器优先级

不同类型的选择器有不同的优先级。优先级的准确规则如下:

  • 如果选择器的ID数量更多,则它会胜出(即它更明确)。
  • 如果ID数量一致,那么拥有最多类的选择器胜出
  • 如果以上两次比较都一致,那么拥有最多标签名的选择器胜出

Attention! 伪类选择器和属性选择器与一个类选择器的优先级相同

​ 通用选择器(*)和组合器(>、<、~)对优先级没有影响

优先级标记

常用的表示优先级的方式

​ 用数值形式来标记,通常用逗号隔开每个数。比如,“1,2,2”表示选择器由1个ID、2个类、2个标签组成。优先级最高的ID列为第一位,紧接着是类,最后是标签。
在这里插入图片描述

​ 有时,还会用4个数的标记,其中将最重要的位置用0或1来表示,代表一个声明是否是用行内样式添加的。此时,行内样式的优先级为“1,0,0,0”。它会覆盖通过选择器添加的样式,比如优先级为“0,1,2,0”(1个ID和2个类)的选择器。

1.1.3 源码顺序

​ 如果两个声明的来源和优先级相同,其中一个声明在样式表中出现较晚,或者位于页面较晚引入的样式表中,则该声明胜出。

链接样式和源码顺序
//顺序不可改变
a:link {
  color: blue;
  text-decoration: none;
}

a:visited {
  color: purple;
}

a:hover {
  text-decoration: underline;
}

a:active {
  color: red;
}

​ 书写顺序之所以很重要,就是因为层叠。像上述的代码如果顺序发生变化,这个效果就会遭到破坏。

层叠值

​ 如果一个声明在层叠中“胜出”,它就被称作一个层叠值。元素的每个属性最多只有一个层叠值。

1.1.4 两条经验法则

(1)在选择器中不要使用ID

​ 就算只用一个ID,也会大幅提升优先级。当需要覆盖这个选择器时,通常找不到另一个有意义的ID,于是就会复制原来的选择器,然后加上另一个类,让它区别于想要覆盖的选择器。

(2)不要使用!important

​ 它比ID更难覆盖,一旦用了它,想要覆盖原先的声明,就需要再加上一个!important,而且依然要处理优先级的问题。

1.2 继承

如果一个元素的某个属性没有层叠值,则可能会继承某个祖先元素的值。但不是所有的属性都能被继承。

能继承的属性通常是我们希望被继承的那些。它们主要是跟文本相关的属性:colorfontfont-familyfont-sizefont-weightfont-variantfont-styleline-heightletter-spacingtext-aligntext-indenttext-transformwhite-space以及word-spacing

还有一些属性也可以被继承,比如列表属性:list-stylelist-style-typelist-style-position以及list-style-image。表格的边框属性border-collapseborder-spacing也能被继承。

1.3 特殊值

有两个特殊值可以赋给任意属性,用于控制层叠:inheritinitial

1.3.1 使用inherit关键字

​ 我们想用继承代替一个层叠值。这时候可以用inherit关键字。可以用它来覆盖另一个值,这样该元素就会继承其父元素的值。还可以使用inherit关键字强制继承一个通常不会被继承的属性。

1.3.2 使用initial关键字

撤销作用于某个元素的样式可以用initial关键字来实现。如果将initial值赋给某个属性,那么就会有效地将其重置为默认值,这种操作相当于硬复位了该值。

1.4 简写属性

简写属性是用于同时给多个属性赋值的属性。例如font

//用font简写属性来指定font-style、font-weight、font-size、font-height以及font-family。
font: italic bold 18px/1.2 "Helvetica", "Arial", sans-serif;

1.4.1 简写属性会默默覆盖其他样式

​ 大多数简写属性可以省略一些值,只指定我们关注的值。但是要知道,这样做仍然会设置省略的值,即它们会被隐式地设置为初始值。

1.4.2 理解简写值的顺序

​ 简写属性会尽量包容指定的属性值的顺序。

上、右、下、左

​ 当遇到像**marginpadding这样的属性,还有为元素的四条边分别指定值的边框属性时**,开发者容易弄错这些简写属性的顺序。这些属性的值是按顺时针方向,从上边开始的

第2章 相对单位

绝对单位:像素单位(px)

相对单位:em rem

2.1 相对值的好处

​ 相对单位就是CSS用来解决抽象的一种工具。我们可以基于窗口大小来等比例地缩放字号,而不是固定为14px,或者将网页上的任何元素的大小都相对于基础字号来设置,然后只用改一行代码就能缩放整个网页。

2.1 em和rem

em

​ em是最常见的相对长度单位,适合基于特定的字号进行排版。在CSS中,1em等于当前元素的字号,其准确值取决于作用的元素。

.padded {
  font-size: 16px;         
  padding: 1em;    ←---- 设置四个内边距为font-size
}

//内边距为1em,浏览器将其乘以字号,最终渲染为16px

浏览器会根据相对单位的值计算出绝对值,称作计算值

2.2.1 使用em定义字号

font-size: 1.2em   //这个font-size是根据继承的字号来计算的

例:

body {
  font-size: 16px;
}

.slogan {       (以下3行)计算结果为元素继承的字号的1.2倍
  font-size: 1.2em;    
}
<body>
  We love coffee                             
  <p class="slogan">We love coffee</p>   ←---- slogan继承了<body>的字号
</body>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JvaesSYG-1648781887721)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220331154046875.png)]

em同时用于字号和其他属性

​ 同时用它指定一个元素的字号和其他属性时,浏览器必须先计算字号然后使用这个计算值去算出其余的属性值

body {
  font-size: 16px;
}

.slogan {                   
  font-size: 1.2em;      ←---- 计算值为19.2px       
  padding: 1.2em;        ←---- 计算值为23.04px
  background-color: #ccc;
}
//padding值为1.2em乘以19.2px,得到23.04px
字体缩小的问题

当用em来指定多层嵌套元素的字号时,为了算出每个元素的准确值,需要知道继承的字号,如果这个值是在父元素上用em定义的,就要知道父元素的继承值。

body {
  font-size: 16px;
}

ul {
  font-size: .8em;
}
<ul>
  <li>Top level
    <ul>           (以下2行)这个列表嵌套在第一个列表中,继承它的字号
      <li>Second level     
        <ul>          (以下2行)这个嵌套在上一个列表中,继承第二个列表的字号
          <li>Third level      
            <ul>       (以下2行)以此类推
              <li>Fourth level    
                <ul>
                  <li>Fifth level</li>
                </ul>
              </li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Kguvs9Td-1648781887722)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220331163402931.png)]

纠正文字缩小的问题

ul {
  font-size: .8em;
}

ul ul {         (以下3行)嵌套的列表应当跟其父级的字号一致
  font-size: 1em;     
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i8JZe7ma-1648781887723)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220331163440282.png)]

2.2.2 使用rem设置字号

根节点是所有其他元素的祖先节点,根节点有一个伪类选择器(:root),可以用它来选中自己。

rem是root em的缩写,rem是相对于根元素的单位不管在文档的什么位置使用rem,1.2rem都会有相同的计算值:1.2乘以根元素的字号。

推荐使用rem设置字号,用px设置边框,用em设置其他大部分属性(尤其内边距、外边距和圆角)

2.3.1 设置一个合理的默认字号

将默认字号设置为14px:

:root {        ←----  使用HTML选择器
  font-size: 0.875em;     ←---- 14/16(理想的px/继承的px)=0.875
}

2.3.2 构造响应式面板

我们可以根据屏幕尺寸,用媒体查询改变根元素的字号。这样就能够基于不同用户的屏幕尺寸,渲染出不同大小的面板。

:root {          (以下3行)作用到所有的屏幕,但是在大屏上会被覆盖
  font-size: 0.75em;   
}                      

@media (min-width: 800px) {   (以下5行)仅作用到宽度800px及其以上的屏幕,覆盖之前的值
  :root {                     
    font-size: 0.875em;       
  }                           
}                             

@media (min-width: 1200px) {  (以下5行)仅作用到宽度1200px及其以上的屏幕,覆盖前面两个值
  :root {                      
    font-size: 1em;           
  }                            
}

2.3.3 缩放单个组件

需要让同一个组件在页面的某些部分显示不同的大小,可以通em来单独缩放一个组件

2.4 视窗的相对窗口

em和rem都是相对font-size定义的,CSS里还有相对于浏览器视口定义长度的视口的相对单位的。

  • vh:视口高度的1/100。
  • vw:视口宽度的1/100。
  • vmin:视口宽、高中较小的一方的1/100(IE9中叫vm,而不是vmin)。
  • vmax:视口宽、高中较大的一方的1/100(本书写作时IE和Edge均不支持vmax)2

2.4.1 使用vw定义字号

使用vh和vw设置字号非常实用,但优势在大屏上字还是太大了

2.4.2 使用calc()定义字号

calc()函数内可以对两个及其以上的值进行基本运算。注意加号和减号两边必须有空白

:root {
  font-size: calc(0.5em + 1vw);
}

0.5保证了最小字号,1vw则确保了字体会随视口缩放。

2.5 无单位的数值和行高

有些属性允许无单位的值:line-heightz-indexfont-weight(700等于bold,400等于normal,等等)

任何长度单位(如px、em、rem)都可以用无单位的值0,因为这些情况下单位不影响计算值,即0px、0%、0em均相等。

2.6 自定义属性(即CSS变量)

层叠变量的自定义属性

给CSS引进了变量的概念,开启了一种全新的基于上下文的动态样式。可以声明一个变量,为它赋值,然后再样式表的其他的地方引用这个值。

:root {
  --main-font: Helvetica, Arial, sans-serif;  //
}

变量名前面必须有两个连字符(--,用于跟CSS属性区分,剩下的部分可以随便命名。

变量必须在一个声明块内声明。这里是用了:root选择器,所以变量可以在整个网页使用。

使用:

:root {
  --main-font: Helvetica, Arial, sans-serif;
}

p {                (以下3行)将段落的字体设置为Helvetica、Arial、sans-serif
  font-family: var(--main-font);   
}
:root {
  --main-font: Helvetica, Arial, sans-serif;     
  --brand-color: #369;         ←---- 定义一个蓝色的brand-color变量
}

p {
  font-family: var(--main-font);
  color: var(--brand-color);
}
:root {
  --main-font: Helvetica, Arial, sans-serif;
  --brand-color: #369;
}

p {                                              
  font-family: var(--main-font, sans-serif);  ←---- 指定备用值为sans-serif       
  color: var(--secondary-color, blue);        ←---- secondary-color变量没有定义,因此会使用备用值blue
}

var()函数接受第二个参数,它指定了备用值。如果第一个参数指定的变量未定义,就会使用第二个值)

2.6.1 动态改变自定义属性

自定义属性真正的意义在于,自定义属性的声明能够层叠和继承:可以在多个选择器中定义相同的变量,这个变量在网页的不同地方有不同的值。

例:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RZ07S54E-1648781887724)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220331173247371.png)]

<body>
  <div class="panel">         ←-- 网页中的一个普通面板
    <h2>Single-origin</h2>
    <div class="body">
      We have built partnerships with small farms
      around the world to hand-select beans at the
      peak of season. We then careful roast in
      small batches to maximize their potential.
    </div>
  </div>

  <aside class="dark">    (以下2行)深色容器内的另一个面板
    <div class="panel">   
      <h2>Single-origin</h2>
      <div class="body">
        We have built partnerships with small farms
        around the world to hand-select beans at the
        peak of season. We then careful roast in
        small batches to maximize their potential.
      </div>
    </div>
  </aside>
</body>
//在:root选择器的规则中定义变量,这样的话这些值就可以提供给根元素(整个网页)下的任何元素。
:root {
  --main-bg: #fff;      (以下2行)分别将背景色和文字颜色变量定义为白色和黑色
  --main-color: #000;   
}

.panel {
  font-size: 1rem;
  padding: 1em;
  border: 1px solid #999;
  border-radius: 0.5em;
  background-color: var(--main-bg);    (以下2行)在面板样式中使用变量
  color: var(--main-color);             
}

.panel > h2 {
  margin-top: 0;
  font-size: 0.8em;
  font-weight: bold;
  text-transform: uppercase;
}
.dark {
  margin-top: 2em;  //给深色容器和前面的面板之间加上外边距
  padding: 1em;         

  background-color: #999;  //给深色容器加上深灰色背景
  --main-bg: #333;  //在容器内重定义--main-bg和--main-color变量
  --main-color: #fff;    
}

2.6.2 使用JavaScript改变自定义属性

<script type="text/javascript">
  var rootElement = document.documentElement;
  var styles = getComputedStyle(rootElement);    ←-- 获取一个元素的styles对象
  var mainColor = styles.getPropertyValue('--main-bg');   ←-- 获取styles对象的--main-bg值
  console.log(String(mainColor).trim());   ←---- 确保mainColor是一个字符串,并去掉前后空格;打印结果为“#fff”
</script>

在不支持自定义属性的浏览器上,任何使用var()的声明都会被忽略。请尽量为这些浏览器提供回退方案

第3章 盒模型

3.1 元素宽度的问题

案例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kv8Tn1nz-1648781887725)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220331191841266.png)]

<body>
  <header>
    <h1>Franklin Running Club</h1>
  </header>
  <div class="container">
    <main class="main">
      <h2>Come join us!</h2>
      <p>
        The Franklin Running club meets at 6:00pm every Thursday
        at the town square. Runs are three to five miles, at your
        own pace.
      </p>
    </main>
    <aside class="sidebar">
      <div class="widget"></div>
      <div class="widget"></div>
    </aside>
  </div>
</body>
body {
  background-color: #eee;
  font-family: Helvetica, Arial, sans-serif;
}

header {
  color: #fff;
  background-color: #0072b0;
  border-radius: .5em;
}

main {
  display: block;   ←-- 修复IE的bug
}

.main {
  background-color: #fff;
  border-radius: .5em;
}

.sidebar {
  padding: 1.5em;     ←-- 给侧边栏加上内边距
  background-color: #fff;
  border-radius: .5em;
}

此时效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-snfNPsti-1648782066574)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220331191954725.png)]

想要做出主栏和侧栏的效果,我们首先使用浮动布局,将mainsidebar向左浮动,分别设置70%和30%的宽度

.main {
  float: left;
  width: 70%;            ←---- 将main列向左浮动,设置宽度为70%
  background-color: #fff;   
  border-radius: .5em;
}

.sidebar {
  float: left;
  width: 30%;       ←---- 将sidebar向左浮动,设置宽度为30%
  padding: 1.5em;       
  background-color: #fff;
  border-radius: .5em;
}

但是效果却是这样

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mCUXi4gu-1648781887726)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220331192058612.png)]

因为虽然将两列宽度设置为70%和30%,但是这是指定的内容的宽和高,注意,当给一个元素设置宽或高的时候,指定的是内容的宽和高。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7soaDfRq-1648781887727)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220331192407839.png)]

在本例中,侧边栏的宽度等于30%宽度再加上各边1.5em左右的内边距

3.1.1 避免魔术数值

最笨的方法就是减少其中一列的宽度。替代魔术数值的一个方法就是让浏览器帮忙计算。

在本例中,因为加了内边距,两列的宽度总和超出了3em。所以我们可以使用calc()函数减去这个值,得到刚好100%的总和。比如设置侧边栏宽度为calc(30%-3em)。但是还有更好的解决办法

3.1.2 调整盒模型

使用box-sizing属性调整盒模型的行为,我们让指定的宽度包含内边距和边框

box-sizing的默认值为content-box,这意味着任何指定的宽或高都只会设置内容盒子的大小。把box-sizing设置为border-box后,height和width属性会设置内容、内边距以及边框的大小总和。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0peNm1F8-1648781887727)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220331193044419.png)]

所以我们相对应的修改代码,给两个盒子加上box-sizing:border-box;属性

.main {
  box-sizing: border-box;     (以下9行)将盒模型改为border-box
  float: left;                   
  width: 70%;                    
  background-color: #fff;        
  border-radius: .5em;            
}                                 

.sidebar {                       
  box-sizing: border-box;    
  float: left;
  width: 30%;
  padding: 1.5em;
  background-color: #fff;
  border-radius: .5em;
}

3.1.3 全局设置border-box

可以利用通用选择器,一劳永逸,再也不用想着调整盒模型

*,
::before,
::after{
	box-sizing:border-box;//给页面上所有的元素和伪元素设置border-box
}

但是用第三方组件的时候要小心,因为三方组件在开发CSS的过程中没有考虑到使用者会修改盒模型时。因为全局设置border-box时使用的通用选择器会选中第三方组件内的每个元素,修改盒模型可能会有问题,所以最终需要写另外的样式将组件内的元素恢复为content-box

也可以利用继承改一下修改盒模型的方式

:root{
	box-sizing:border-box;
}
*,
::before,
::after {
  box-sizing: inherit;    ←---- 告诉其他所有元素和伪元素继承其盒模型
}

用inherit强制继承border-box。在必要时选中第三方组件的顶级容器,将其恢复为content-box

.third-party-component {
  box-sizing: content-box;
}

3.1.4 给列之间加上间隔

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n3y0WgAX-1648781887728)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220331193933825.png)]

从宽度中减掉1.5em分给外边距

.main {
  float: left;
  width: 70%;
  background-color: #fff;
  border-radius: .5em;
}

.sidebar {
  float: left;                   
  width: calc(30% - 1.5em);   ←---- 从宽度中减去1.5em
  margin-left: 1.5em;      ←---- ……将其添加到外边距
  padding: 1.5em;             
  background-color: #fff;
  border-radius: .5em;
}

这种方式不仅能够使用em指定间距,而且能让代码意图更明显。之后再看代码,从代码清单3-7中可能看不出为什么使用29%,但是代码清单3-8中的30% - 1.5em则能提供线索,知道它是基于30%算出来的。

3.2 元素高度的问题

对border-box的修改适用于高度,但是通常最好避免给元素指定明确的高度。容器的高度应该由内容决定,而不是由容器自己决定

3.2.1 控制溢出行为

当明确设置一个元素的高度时,内容可能会溢出容器。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9QzT8xcR-1648781887728)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220331195442019.png)]

overflow属性

用overflow属性可以控制溢出内容的行为,该属性支持下面四个值

  • visible(默认值) 所有内容可见,即使溢出
  • hidden 溢出容器内边距边缘的内容被裁剪,无法看见
  • scroll 容器会一直出现滚动条,用户可以通过滚动查看剩余内容
  • auto 只有内容溢出时容器才会出现滚动条

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rzanqYKS-1648781887729)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220331195716458.png)]

3.2.2 百分比高度的备选方案

要想让百分比高度生效,必须给父元素明确定义一个高度。(因为容器的高度一般由子元素决定,不设定的话会造成死循环,浏览器无法处理,会忽略)

等高列

现代浏览器支持了CSS表格,可以轻松实现等高列。比如IE8+支持display: table,IE10+支持弹性盒子或者Flexbox,都默认支持等高列。

我现在想要将上面的例子主列和侧边栏高度对齐,看起来更好看。想要任意一列的内容增加,两列的高度都会增加的效果,同时要保持底部对齐

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sRbOo79W-1648782151465)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220331200304717.png)]

下面演示通过CSS表格和Flexbox两种方式实现这种效果。

CSS表格布局

用CSS表格布局替代浮动布局。给容器设置display: table,给每一列设置display: table-cell

.container {               
  display: table;      ←---- 让容器布局像表格一样
  width: 100%;      ←---- ❶让表格填充容器的宽度
}                      

.main {
  display: table-cell;
  width: 70%;              (以下7行)让列布局像表格的单元格一样
  background-color: #fff;      
  border-radius: .5em;         
}                              

.sidebar {                     
  display: table-cell;      
  width: 30%;
  margin-left: 1.5em;       ←---- ❷外边距不再生效
  padding: 1.5em;              
  background-color: #fff;      
  border-radius: .5em;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vjjoQwBP-1648782167172)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220331200723216.png)]

默认情况下,display:table的元素不会扩展到100%,所以需要明确指定宽度,下图是没有指定宽度的情况

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OONCsl8i-1648782182166)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220331200914101.png)]

border-spacing 定义单元格的间距。该属性接受两个长度值:水平间距和垂直间距

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ctgz9fj3-1648781887732)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220331201138728.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z02pbxbk-1648782203257)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220331201117533.png)]

但是会产生副作用,这个值也会作用于表格的外边缘。这样两列就无法跟头部左右对齐了

负外边距

需要给整个表格包裹一层新的容器

在表格容器外面包一个元素<div class="wrapper">,将其左右外边距设置为-1.5em,从而抵消表格容器外侧1.5em的border-spacing

正的外边距会将容器的边缘往里推,而负的外边距则会将边缘往外拉。结合border-spacing,两列靠近外侧的边缘跟<body>(包裹元素所在的容器盒子)的边缘对齐了。现在的布局满足了需求:两列等高,1.5em的间距,外边缘跟头部对齐
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nZeAIxF1-1648782249060)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220331201808357.png)]

在这里插入图片描述

在这里插入图片描述

Flexbox

可以利用Flexbox实现两列等高布局。Flexbox不需要一个额外的div包裹元素,它默认会产生等高的元素。此外也不需要使用负外边距。

.container {
  display: flex;   ←---- 将容器的display属性设置为flex
}                       

.main {  (以下7行)弹性容器内的元素不需要指定display或者float属性
  width: 70%;                   
  background-color: #fff;     
  border-radius: 0.5em;         
}                              

.sidebar {                   
  width: 30%;
  padding: 1.5em;
  margin-left: 1.5em;     ←---- 跟浮动布局一样,外边距可以生效
  background-color: #fff;        
  border-radius: .5em;
}

给容器设置display: flex,它就变成了一个弹性容器子元素默认等高

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jieRMCE2-1648782376008)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220331202406049.png)]

3.2.3 使用min-height和max-height

可以用这俩属性指定最小或最大值,而不是明确定义高度,这样元素就可以在这些界限内自动决定高度

有三个元素。左边的元素没有min-height,因此它的高度由自身决定,另外两个元素都设置了min-height为3em。中间的元素如果自己决定高度的话应该比现在矮,但是min-height值让它的高度为3em。右边的元素内容多到已经超过3em,容器自然地扩展高度,以容纳内容。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3c6yHZnd-1648781887735)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220331202837172.png)]

用人话讲就是,只要我设定了min-heigth,就算内容没有这么高也要设这么高,如果内容高于这个就自然扩容

同理,max-height允许元素自然地增高到一个特定界限。如果到达这个界限,元素就不再增高,内容会溢出。还有类似的属性是min-widthmax-width,用于限制元素的宽度。

3.2.4 垂直居中的内容

最简单的垂直居中方法:给容器相等的上下内边距

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vGWXHD5G-1648782405477)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220331203250359.png)]

3.3 负外边距

负外边距有一些特殊用途,比如让元素重叠或者拉伸到比容器还宽。

负外边距的具体行为取决于设置在元素的哪边

如果设置左边或顶部的负外边距,元素就会相应地向左或向上移动,导致元素与它前面的元素重叠,如果设置右边或者底部的负外边距,并不会移动元素,而是将它后面的元素拉过来

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SBmFzoxX-1648782435369)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220331203526762.png)]

在margin属性中一共有两类参考线,top和left的参考线属于一类,right和bottom的参考线属于另一类。top和left是以外元素为参考,right和bottom是以元素本身为参考

如果不给一个块级元素指定宽度,它会自然地填充容器的宽度。但如果在右边加上负外边距,则会把它拉出容器。如果在左边再加上相等的负外边距,元素的两边都会扩展到容器外面。这就是为什么可以拉宽图3-12里的表格容器布局,让它填满<body>的宽度,忽略border-spacing的影响。

3.4 外边距折叠

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GnuVFGnt-1648781887737)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220331210839894.png)]

3.4.1 文字折叠

段落(<p>)默认有1em的上外边距和1em的下外边距。这是用户代理的样式表添加的,但当前后叠放两个段落时,它们的外边距不会相加产生一个2em的间距,而会折叠,只产生1em的间隔

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H5uK34pa-1648781887738)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220331211927688.png)]

折叠外边距大小等于相邻外边距中的最大值

3.4.2 多个外边距折叠

即使两个元素不是相邻的兄弟节点也会产生外边距折叠。在没有其他CSS的影响下,所有相邻的顶部和底部外边距都会折叠。

也就是说可以给任何元素加上外边距,而不必担心它们前后的元素是什么。

3.4.3 容器外部折叠

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DzWWvONH-1648781887738)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220331212428381.png)]

网页标题是

,用户代理样式给他底部设置的外边距0.67em

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XczeuM6k-1648781887739)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220331212531732.png)]

它的父元素是

,没有设置任何外边距。因为它们底部外边距相邻,所以会真的,导致
下方出现了0.67em的外边距。

但是"Come join us"上方的外边距没有在容器外面折叠。这是因为弹性子元素的外边距不会折叠。利用Flexbox布局。

给头部添加上下内边距,外边距就不会在容器外部折叠

现在更新CSS:

header {
  padding: 1em 1.5em;
  color: #fff;
  background-color: #0072b0;
  border-radius: .5em;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F2t77ZHS-1648781887740)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220331213030065.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aD0hs7O7-1648781887740)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220331213056476.png)]

看看变化!

防止外边距折叠的方法

  • 对容器使用overflow:auto(或者非visible的值),防止内部元素的外边距跟容器外部的外边距折叠,此方法副作用小
  • 在两个外边距之间加上边框或者内边距,防止它们折叠(两个都要加!!)
  • 如果容器为浮动元素、内敛块、绝对定位或固定定位时,外边距不会在它外面折叠
  • 当使用flexbox布局时,弹性布局内的元素之间不会发生外边距折叠
  • 当元素显示为table-cell时不具备外边距属性,因此不会折叠

3.5 容器内的元素边距

想要的效果:加上两个按钮和一个链接

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AMUE803K-1648781887741)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220401101243549.png)]

<aside class="sidebar">
  <a href="/twitter" class="button-link">
    follow us on Twitter
  </a>
  <a href="/facebook" class="button-link">
    like us on Facebook
  </a>
</aside>
.button-link {
  display: block;            ←---- 块级元素填满了可用宽度,同时让每个链接单独一行
  padding: 0.5em;                
  color: #fff;
  background-color: #0090C9;
  text-align: center;
  text-decoration: none;
  text-transform: uppercase;
}

此时的效果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LBlTwqoN-1648781887741)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220401101751704.png)]

需要给两个按钮之间加间距

如果直接加上margin-top:1.5rem,效果如图

在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tmoKqfrz-1648781887743)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220401102022951.png)]

侧边栏的内部边距padding和按钮的外边距接触了,按钮的上外边距使得容器的内边距看起来更大了

解决办法:使用相邻的兄弟组合器(+)选中同一个父元素下紧跟在其他button-link后面的button-link元素。

.button-link {
  display: block;
  padding: .5em;
  color: #fff;
  background-color: #0090C9;
  text-align: center;
  text-decoration: none;
  text-transform: uppercase;
}

.button-link + .button-link {  
  //只给紧跟在其他button-link后面的button-link加上顶部外边距
  margin-top: 1.5em;             
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7X584Qha-1648781887744)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220401102534702.png)]

只有第二个按钮有margin-top,这样显示就正常了

但是,当我们再往侧边栏加点内容

<a href="/sponsors" class="sponsor-link">   (以下3行)给侧边栏加上另一种链接
    become a sponsor                          
  </a>                

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fWeeKnRI-1648781887745)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220401102739174.png)]

加上样式

.sponsor-link {
  display: block;
  color: #0072b0;
  font-weight: bold;
  text-decoration: none;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VOAG7Oec-1648781887745)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220401102906153.png)]

可以给这个链接增加顶部外边距以实现效果,但是每次增加内容、修改HTML都要改动,每次都要考虑这些外边距问题。

3.5.2 更通用的解决方案:猫头鹰选择器

Web设计师Heydon Pickering曾表示外边距“就像是给一个物体的一侧涂了胶水,而你还没有决定是否要将它贴到某处,或者还没想好要贴到什么东西上”。不要给网页当前的内容固定外边距,而是应该采取更通用的方式,不管网页结构如何变化都能够生效。这就是Heydon Pickering所说的迟钝的猫头鹰选择器(以下简称猫头鹰选择器),因为它长这样:* + *

该选择器开头是一个通用选择器(*),可以选中所有元素,后面是一个相邻兄弟组合器(+),最后是另一个通用选择器 。它会选中页面上有着相同父级的非第一个子元素

body * + * {
  margin-top: 1.5em;
}

我们将body放选择器的前面,这样该选择器就只能选中body内的元素。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3kADws99-1648781887746)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220401104254375.png)]

效果如图。此时sidebar上面也会有顶部外边距,header和container是兄弟,所以container被选中,然后container中main和siderbar是兄弟,所以siderbar被选中,所以siderbar上面有外间距

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-16RF5vHS-1648781887746)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220401104445467.png)]

要修正此错误,可以给主列补上内边距

.main {
  width: 70%;
  padding: 1em 1.5em;    ←----给主列加上内边距
  background-color: #fff;       
  border-radius: .5em;
}

.sidebar {
  width: 30%;
  padding: 1.5em;
  margin-top: 0;          ←---- 移除猫头鹰选择器设置的顶部外边距
  margin-left: 1.5em;         
  background-color: #fff;
  border-radius: .5em;
}

margin-top=0;修正顶部外边距

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yDoXr6QG-1648781887747)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220401104801109.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-trIN0oMY-1648781887748)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220401104830713.png)]

给main栏补上内边距

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rXyZcuLP-1648781887748)(D:\大学\学习资料\前端学习笔记\CSS\深入解析CSS.assets\image-20220401105640430.png)]

考虑这些外边距问题。

3.5.2 更通用的解决方案:猫头鹰选择器

Web设计师Heydon Pickering曾表示外边距“就像是给一个物体的一侧涂了胶水,而你还没有决定是否要将它贴到某处,或者还没想好要贴到什么东西上”。不要给网页当前的内容固定外边距,而是应该采取更通用的方式,不管网页结构如何变化都能够生效。这就是Heydon Pickering所说的迟钝的猫头鹰选择器(以下简称猫头鹰选择器),因为它长这样:* + *

该选择器开头是一个通用选择器(*),可以选中所有元素,后面是一个相邻兄弟组合器(+),最后是另一个通用选择器 。它会选中页面上有着相同父级的非第一个子元素

body * + * {
  margin-top: 1.5em;
}

我们将body放选择器的前面,这样该选择器就只能选中body内的元素。

[外链图片转存中...(img-3kADws99-1648781887746)]

效果如图。此时sidebar上面也会有顶部外边距,header和container是兄弟,所以container被选中,然后container中main和siderbar是兄弟,所以siderbar被选中,所以siderbar上面有外间距

[外链图片转存中...(img-16RF5vHS-1648781887746)]

要修正此错误,可以给主列补上内边距

.main {
  width: 70%;
  padding: 1em 1.5em;    ←----给主列加上内边距
  background-color: #fff;       
  border-radius: .5em;
}

.sidebar {
  width: 30%;
  padding: 1.5em;
  margin-top: 0;          ←---- 移除猫头鹰选择器设置的顶部外边距
  margin-left: 1.5em;         
  background-color: #fff;
  border-radius: .5em;
}

margin-top=0;修正顶部外边距

[外链图片转存中...(img-yDoXr6QG-1648781887747)]

[外链图片转存中...(img-trIN0oMY-1648781887748)]

给main栏补上内边距

[外链图片转存中...(img-rXyZcuLP-1648781887748)]

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Swin Transformer是一种新型的层次化视觉Transformer模型,它在Vision Transformer(ViT)的基础上进行了改进,并在多个视觉任务上取得了更好的效果。本文将对Swin Transformer论文进行精读,详细介绍其创新点和实验结果。 ## 创新点 Swin Transformer主要有以下三个创新点: ### 1. 层次化注意力 Swin Transformer引入了层次化注意力机制,将图像分成多个块进行处理,每个块内部使用全局自注意力机制,不同块之间使用局部注意力机制。这种层次化的注意力机制可以减少全局自注意力机制的计算量,同时保持局部信息的传递。 ### 2. Shifted Window 传统的ViT使用固定大小的图像块进行处理,而Swin Transformer使用了一种称为Shifted Window的方法,将每个块按照一定的步长进行平移,使得每个块都包含了周边的信息。这种方法可以更好地捕捉到图像中的全局信息。 ### 3. Swin Transformer Block Swin Transformer引入了一个新的Swin Transformer Block,它是由多个Shifted Window构成的,每个Shifted Window内部使用了类似于ViT的注意力机制。这种新的Transformer Block可以更好地捕捉到局部和全局的信息。 ## 实验结果 Swin Transformer在多个视觉任务上都取得了很好的效果,比如ImageNet分类、COCO目标检测、Cityscapes语义分割等。在ImageNet上,Swin Transformer比ViT-Large模型具有更好的性能,同时参数数量更少,计算效率更高。在COCO目标检测任务中,Swin Transformer在使用相同的backbone的情况下,比ViT-Large模型具有更高的AP值。在Cityscapes语义分割任务中,Swin Transformer在使用相同的backbone的情况下,比DeiT-base模型具有更高的mIoU值。 ## 总结 Swin Transformer是一种新的层次化视觉Transformer模型,它引入了层次化注意力机制、Shifted Window和Swin Transformer Block等创新点,并在多个视觉任务上取得了很好的效果。这些创新点可以更好地捕捉到图像中的局部和全局信息,同时减少了计算量,提高了计算效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值