美化文档
HTML内部添加样式
本节我们来学习如何在标签中引入CSS样式。
1 在标签中添加声明
声明的关键字是style
后接等号(=
)再接引号(""
),即style=""
具体声明如下:
<input type="text" placeholder="手机号码" style="">
-
声明位置不分先后
<input type="text" style="" placeholder="手机号码"> <!-- 或者 --> <input style="" type="text" placeholder="手机号码">
以上两种方式都正确
-
与其他关键字之间用空格隔开
关键字和关键字之间要用空格隔开,比如type
和placeholder
之间会加一个空格
<input type="text" placeholder="手机号码" style="">
注意:关键字和标签名之间也要用空格隔开,比如下面这种写法就是错误的
<pstyle=""></p>
2 在引号之间添加样式
<p style="font-size:14px;color:white"></p>
这段代码的意思就是:设置p标签中的字体大小为14px,颜色为白色。
CSS样式我们在后面会学到,这段代码不理解也不要紧。
字体大小/字体粗细
在这一章当中我们要学习的是一些常见的与字体相关的 CSS 样式。
在 CSS 中,样式是由属性和值组成,中间用冒号(:
)隔开,用分号(;
)收尾,其中属性可以理解为身高、体重,值可以理解为 1.8 米、60kg,在现实生活中我们用这样一对组合来描述人或者物,在 CSS 中,我们用这样一对组合来描述文字的粗细、大小、颜色等等。
字体大小
设置格式为:font-size:36px;
font-size --> 字体的大小 36px --> 字体大小的尺寸
注意:
你可能会在以后的代码中看到这样的现象,style = "font-size: 12px; font-weight:bold"。可以看到,bold 后面没有分号
;
,这是因为这一组属性后面再没有其他的属性了,所以可以把结尾的分号;
省略,但是这样的写法允许,但不规范。
核心代码如下:
<!-- 设置字体的大小为12px -->
<p style="font-size: 12px;">一个轻量级和模块化的前端框架,用于开发快速和强大的web接口。
</p>
<!-- 设置字体的大小为24px -->
<p style="font-size: 24px;">一个轻量级和模块化的前端框架,用于开发快速和强大的web接口。
</p>
字体加粗
设置格式:font-weight:100;
设置文字粗细的时候,其值可以是 100,200,300,400,500,600,700,800,900 中的任何一个,或者可以用英文代替,normal(正常粗细),lighter(细),bold(粗),bolder(更粗)
<p style="font-weight: 200;">优课达--学的比别人好一点~</p>
<p style="font-weight: lighter;">优课达--学的比别人好一点~</p>
<p style="font-weight: 400;">优课达--学的比别人好一点~</p>
<p style="font-weight: normal;">优课达--学的比别人好一点~</p>
<p style="font-weight: 700;">优课达--学的比别人好一点~</p>
<p style="font-weight: bold;">优课达--学的比别人好一点~</p>
字体颜色/文字对齐方式
颜色
颜色是页面中不可或缺的属性,在背景、文字中应用非常广泛,颜色的值的设置方式分为四种:
1. 英文字母形式
- color: black;
- color: blue;
-
color: red;
2. 十六进制颜色
十六进制颜色由#开头,后面跟三个数字,每个数字的范围为 00 ~ FF,每个数字代表一种颜色,最终的颜色由这三种颜色调和而成; 这个颜色一般由设计师给我们,或者可以用吸色工具去获取。
- color: #DAE8FC;
- color: #D5E8D4;
3. rgb 形式
rgb 形式和十六进制的原理相同,其最终的颜色由三种颜色的深浅决定,即 r(red),g(green),b(blue),每种颜色的范围为 0 ~ 255,代表这每种颜色的深浅,值越大越深;同样的,我们不必去深入研究它,设计师给我们什么,我们就用什么。
- color: rgb(253, 217, 106);
4. rgba 形式
rgba 形式相比 rgb 形式,多了一个 a,这里的 a 代表的是 Alpha(透明度),a 的值在 0 ~ 1 之间,为了简化书写,也可以直接省略 0,写成.4,等同于 0.4。
- color: rgba(253, 217, 106,1.0);
- color: rgba(253, 217, 106,0.3);
注意:以上四种表达方式:
- 多数情况下建议使用十六进制表达方式;
- 调试的时候可以用英文字母形式,初期的调试就是随便设置一个颜色,查看区块是否存在,区块大小等,在盒模型中我们会遇到;
- 如果要设置文字透明度或者背景透明度,就要用到
rgba
形式,在第八章我们会遇到。
下面我们来使用字体颜色来实现下图效果:
核心代码如下:
<h3 style="color:#ff9a9e;font-weight:700;font-size: 24px;">UIzards</h3>
<h4 style="font-size: 16px;color: #474d5d;font-weight: 400;">Senior UX Designer
</h4>
<p style="font-size: 14px;color:#84868d;">Nam liber tempor cum soluta nobis eleifend option congue nihil imperdietdoming id quom placerat facer possim assum. Typi non habent claritateminsitam; est usus legentis in iis qui faorum claritatem. Investigationesdemonstraverunt lectores legere me lius quod ii legunt saepius.
</p>
文字居中/居左/居右
在学习这一节的文字对齐方式的时候,大家可以结合 word 这个办公软件的文字对齐方式去理解,原理是一样的。具体对齐方式效果如下图所示:
文字左对齐
文字对齐方式左对齐文字对齐方式左对齐文字对齐方式左对齐文字对齐方式左对齐文字对齐方式左对齐
文字右对齐
文字对齐方式右对齐文字对齐方式右对齐文字对齐方式右对齐文字对齐方式右对齐文字对齐方式 右对齐
文字居中对齐
文字对齐方式居中对齐文字对齐方式居中对齐文字对齐方式居中对齐文字对齐方式居中对齐
对齐方式居中对齐文字对齐方式居中对齐
设置文字对齐的格式如下:
- text-align: center; 文字居中对齐
- text-align: left; 文字左对齐
- text-align: right; 文字右对齐
文字行高/字间距/字体
行高
首先来解释一下行高,我们先来看一张图:
图中虚线框的高度就是我们之前学过的font-size
(字体大小),以图中的行高为例,20px
的行高除去文字大小12px
后,将剩下的8px
均分为两部分,分别填充在文字上下;
两行文字之间的距离就是由第一行文字下面的4px
加第二行文字上面的4px
形成一个8px
的间距,因此行高的大小决定了文字行与行之间距离的大小。
行高的设置格式:line-height: 30px;
在实际应用中,行高的作用主要有两个:
第一个作用:改变段落中行与行之间的距离
段落中默认是有行高的,但是这个默认的行高未必能满足我们的需求,因此我们就需要改变行高来实现我们需要的效果;
核心代码如下:
<p>We understand every aspect of project and we put a great amount of time inunderstanding the project.
</p><p style="line-height:32px;">We understand every aspect of project and we put a great amount of time inunderstanding the project.
</p>
第二个作用:使文字上下居中
从下图可以看出,随着行高的变化,文字的位置也在不断变化,当行高和矩形的高度一样的时候,文字在矩形中上下居中。
例如:文字外面的矩形高度为 80px,要想让文字在矩形中上下居中,就要设置文字的行高为 80px
核心代码如下: 为了美观,背景颜色和圆角我们在 index.css 中写出,后面我们会学到,这里不用纠结
<buttonstyle="width: 120px;height:50px;text-align: center;line-height:50px;color:white;font-size: 18px;"
>提交
</button>
字间距
字间距就是文字之间的间距,但是中文和英文的字间距是不一样的
- 英文的字间距是每个字母之间的距离,单词和单词之间的距离不属于字间距
- 中文是每个汉字之间的距离
设置字间距的格式为:letter-spacing: 30px;
字体
字体的概念我们在生活中肯定接触了很多,比如说宋体,隶书,黑体,草书等等,当然还有很多外国字体,比如微软雅黑。
字体了解了,那么我们如何去设置字体呢?其实设置字体的方式很简单,关键字+值即可,例如:
font-family: sans-serif;
我们设置的字体能否被应用在页面上取决于使用者的电脑有没有安装这个字体,所以网页中会使用一些常见的字体,使得自己的网站兼容性更好。
当然了,有的网站比较个性化,喜欢用一些个性化的字体,所以他们会多设置几个字体,比如:
font-family: 'Goudy Bookletter 1911', sans-serif, 'Gill Sans Extrabold';
这段代码怎么去理解呢?页面加载以后会先去找代码中设置的字体,这里有三个备选的字体,浏览器会按顺序加载:首先看看"Goudy Bookletter 1911"字体在电脑上是否安装;如果没有安装,就去看第二个字体;如果还没有,就去看第三个字体是否已经安装;如果都没有安装,那么就只能用默认的微软字体,这个字体是所有电脑默认会安装的。
字体写法有一些注意事项:
- 多个字体之间用英文逗号(
,
)隔开 - 字体名称中间有空格的时候,要加引号,单引号和双引号都行:
"Times News Roman"
- 中文字体名称要用引号,单引号和双引号都行:
"宋体"
了解了这些基础知识以后,我们就需要来动手练习一下了,那么就开始练习吧~
引入方式
CSS的三种引入方式
这一节我们要学习的是CSS
的三种引入方式,在前面我们修改字体的时候,已经接触了第一种CSS
的引入方式,即行内式。
下面我们来系统的介绍一下CSS
的三种引入方式。
1.行内样式
下面我们通过画图来理解第一种CSS
引入方式--行内式。
如上图所示:行内样式需要内嵌在每一个HTML
标签中,可想而知,当我们有几百行HTML
标签的时候,就需要写几百个style
,实际上在前面设置字体样式的时候,你一定体会到了这种书写方式的繁琐,比如说我们要修改两个p
标签,他们的样式明明是一样的,我们还不得不再去重写一次相同的CSS
样式,例如:
<p style="font-size: 18px;font-weight: 700;color: blue;">这是一个p标签,和第三个p标签样式一样
</p>
<p>这是一个中立的p标签</p>
<p style="font-size: 18px;font-weight: 700;color: blue;">这是一个p标签,和第一个p标签样式一样
</p>
因此,我们就要想办法把每一个标签中的CSS
样式抽取出来,抽取成一整段,放在HTML
文件中的某个位置。这时候我们就要去了解第二种CSS
的引入方式--内部样式
2.内部样式
接下来我们用一张图来介绍内部样式的抽离过程:
抽离步骤:
-
首先我们将每一个标签里的
CSS
样式抽取出来 -
然后在
head
标签里声明了一个<style></style>
标签 -
接下来将样式都放在了
style
标签里,注意,这里不是简单的粘贴复制。 -
将相同标签的样式写在相同的大括号(
{}
)里,大括号前面加上标签名,形如:
p {font-size: 16px;color: #ffffff;
}
最后来重点说一下头部样式的书写规则:
- 不要忘记写声明标签
<style></style>
- 样式要用花括号括起来
- 每个样式后面要用分号结尾
至此,我们就完成了CSS
样式从每一个标签到头部(head
)的搬迁工作,此时你的HTML
代码看起来是不是没有以前那样杂乱无章了呢?
可能画图的方式对于有些同学理解起来有点障碍,接下来以代码的方式来演示一下内部样式的书写方法
3.外部样式
随着代码量的逐渐增多,整个HTML
文件就会呈现出头重脚轻的现象,即CSS
代码要比HTML
代码多的多,这样很不利于阅读和复查代码,更重要的是为了实现代码的分离,让HTML
负责结构,CSS
代码负责样式。
所以我们要对代码进行进一步的分离。
- 新建一个
index.css
文件 - 将 html 代码头部中的
style
标签内的样式全部拷贝过来; - 将复制的
CSS
样式粘贴进 index.css 文件中; - 建立
HTML
和CSS
文件的联系,即用link
标签引入CSS
文件注意这里的 link 标签引入的位置一定要在 head 标签内;关于引入的时候
./
具体是什么意思,我们在下一节讲。
完成HTML
代码,并在头部引入外部CSS
文件和在外部index.css
文件中书写CSS
样式
补充知识点
CSS 注释
在前文中我们知道 HTML 的注释方式是<!-- 注释内容 -->
,在 CSS 代码中的注释方式跟 HTML 中是不同的,注释格式为/* CSS注释内容 */
CSS 的注释位置
1.内部样式注释
<style>
/* 写CSS的基础样式 */
.base{/* 基础字体大小 */font-size: 14px;/* 基础字体颜色 */color:#000000;
}
</style>
2.外部样式注释 直接在.css
文件中注释即可
/* 写CSS的基础样式 */
.base {/* 基础字体大小 */font-size: 14px;/* 基础字体颜色 */color: #000000;
}
link
最后再提一下link
标签里的一些属性,可能会有同学会对此有疑问,但是这是非必要掌握的知识点:
<link rel="stylesheet" type="text/css" href="index.css" />
rel
属性规定了当前文档与被链接文档之间的关系,但是rel
属性的stylesheet
值被所有浏览器支持,也就是说你只要记住一个值即可。
stylesheet
的意思就是文档的外部样式表。
-
type
属性规定了被链接文档的 MIME(多用途互联网邮件扩展类型)类型,type
属性对应的最常见的值就是text/css
,该类型描述样式表. -
href
属性后跟的是要引入的链接地址
相对路径/绝对路径
路径主要是为了在文件中引入外部资源,比如说我们前面一节在学外部样式的时候,就用到了路径./
路径分为相对路径和绝对路径两种。
绝对路径
绝对路径指的是文件在硬盘上真正存在的路径。 例如,在电脑E盘里面的book文件夹里面的“网页布局”文件夹里面有一个bg.jpg图片,现在需要引入bg.jpg这张图片,用绝对路径需要这样写:
<img src="E:\book\网页布局\bg.jpg" />
这种路径看起来很好理解,但是在实际应用中却有很多问题,比如你的项目拷贝到了你同学的电脑上,你就会发现你引入的图片,或者样式文件没有了。这是因为你引入样式或者图片资源的时候是这样写的:
<link rel="stylesheet" href="E:\style\css\index.css">
<img src="E:\images\beauty.jpg" />
但是同学的电脑的E盘下面根本不存在style文件夹,所以计算机根据你给的路径无法找到要引入的文件。
因此我们要尽量避免使用绝对路径。
相对路径
为了避免绝对路径造成的页面资源丢失现象,在引入外部资源的时候,都会选择使用相对路径。
所谓相对路径就是相对于文件自身位置,去寻找要引入的资源文件。
上面这句话很重要,理解了这句话,相对路径的学习就非常轻松了。
使用相对路径引用文件的时候需要掌握以下内容:
./
:当前文件夹目录,比如在下面这个目录结构下(test文件夹下有index.css和index.html两个文件),要在index.html中引入index.css就需要用到./
。
具体写法如下:
<link rel="stylesheet" href="./index.css">
<!-- 或者./去掉也可以,效果是一样的 -->
<link rel="stylesheet" href="index.css">
../
:回到上一级文件夹目录,比如下面这个文件目录结构中(index.html在test文件夹里面,index.css和test文件夹在同一级目录下),我们要在index.html中引入index.css文件,首先要从index.html文件所在目录即test文件夹里出来,才能找到index.css,从某个文件夹里面出来,就要用到../
具体写法如下:
<link rel="stylesheet" href="../index.css">
用相对路径引入文件记住三点:
- 找到引用资源的文件所在位置,以引用资源的文件为基准,寻找资源
- ../返回一层,如果有多层,就用多个../,比如返回两层就用
../../
- 文件夹名代表进入该文件夹,例如css/,表示进入css文件夹,比如从test文件夹里出来进入css文件夹找到index.css文件,可以这样写
../css/index.css
常用选择器
标签选择器
我们之前在学习CSS
的三种引入方式的时候,其实已经接触了其中一种选择器,即标签选择器,使用标签的名字将标签选中,然后给标签中的文字设置字体样式。
下图可以清楚的看到标签选择器的作用--选中所有叫p
的标签,然后就可以统一给所有的p
标签设置样式
在今后我们还会接触很多其他的选择器,但是请大家记住一点,选择器的作用,就是选中,因为只有选中了以后,才能去对应的做出修改。接下来我们要去理解选择器的一个好处--减少代码量
首先我们来写一个案例,使用最初的行内样式:
核心代码如下:
<h3 style="font-size: 25px;color: #330867;">孟航沛</h3>
<h4 style="font-size: 18px;color: #30cfd0;">平面设计师</h4>
<p style="font-size: 14px;line-height: 28px;color: #4a5252">专业综合性强,具有较强的综合能力,学习认真刻苦,虽然我的专业是思想政治教育,但是我们所学的除了马克思主义的相关理论之外,同时还学习了管理学、心理学和法学的相关理论知识,专业具有较强的综合性,使我具备较强的综合能力,基本能够胜任行政设计师助力这个岗位。
</p>
接下来我们将行内样式抽离出来,写在头部,即内部样式:
核心代码如下:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><title>标签选择器</title><style>h3 {font-size: 25px;color: #330867;}h4 {font-size: 18px;color: #30cfd0;}p {font-size: 14px;line-height: 28px;color: #4a5252;}</style></head><body><h3>孟航沛</h3><h4>平面设计师</h4><p>专业综合性强,具有较强的综合能力,学习认真刻苦,虽然我的专业是思想政治教育,但是我们所学的除了马克思主义的相关理论之外,同时还学习了管理学、心理学和法学的相关理论知识,专业具有较强的综合性,使我具备较强的综合能力,基本能够胜任行政设计师助力这个岗位。</p></body>
</html>
这时候并不能体现出代码量有所减少,只不过是将 CSS 代码换了个位置而已,对于几块除了文字内容不一样,字体颜色,字体大小等都一样。
如果还是使用常规的行内样式,就要在每个标签内重复的去写样式,如果用选择器,只需要添加几个HTML
标签即可。
接下来我们对第二个案例进行一点修改,完成上图所示的效果:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><title>标签选择器</title><style>/* 给h3标签添加样式 */h3 {font-size: 25px;color: #330867;}/* 给h4标签添加样式 */h4 {font-size: 18px;color: #30cfd0;}/* 给p标签添加样式 */p {font-size: 14px;line-height: 28px;color: #4a5252;}</style></head><body><h3>孟航沛</h3><h4>平面设计师</h4><p>专业综合性强,具有较强的综合能力,学习认真刻苦,虽然我的专业是思想政治教育,但是我们所学的除了马克思主义的相关理论之外,同时还学习了管理学、心理学和法学的相关理论知识,专业具有较强的综合性,使我具备较强的综合能力,基本能够胜任行政设计师助力这个岗位。</p><h3>江晓风</h3><h4>UI</h4><p>专业综合性强,具有较强的综合能力,学习认真刻苦,虽然我的专业是思想政治教育,但是我们所学的除了马克思主义的相关理论之外,同时还学习了管理学、心理学和法学的相关理论知识,专业具有较强的综合性,使我具备较强的综合能力,基本能够胜任行政设计师助力这个岗位。</p><h3>左小青</h3><h4>插画师</h4><p>专业综合性强,具有较强的综合能力,学习认真刻苦,虽然我的专业是思想政治教育,但是我们所学的除了马克思主义的相关理论之外,同时还学习了管理学、心理学和法学的相关理论知识,专业具有较强的综合性,使我具备较强的综合能力,基本能够胜任行政设计师助力这个岗位。</p><h3>蒋小鱼</h3><h4>Java工程师</h4><p>专业综合性强,具有较强的综合能力,学习认真刻苦,虽然我的专业是思想政治教育,但是我们所学的除了马克思主义的相关理论之外,同时还学习了管理学、心理学和法学的相关理论知识,专业具有较强的综合性,使我具备较强的综合能力,基本能够胜任行政设计师助力这个岗位。</p></body>
</html>
选择器的层叠性
在写CSS
样式的时候,有时候因为粗心,之前写过的标签又会重新写一次,然后给{}里面添加样式,这样做可能会造成两种结果:
- 添加新的效果(如果添加的是一个新属性)
- 改变之前已经存在的效果(如果该属性之前就存在)
核心代码如下:
h3 {font-size: 25px;color: #330867;
}h4 {font-size: 18px;color: #30cfd0;
}p {font-size: 14px;line-height: 28px;color: #4a5252;
}
/*在这里写一个同名标签名h3,所以你只要关注“孟航沛”的变化即可*/
h3 {/*font-weight属性在之前的h3标签里没有写,那么这里就会添加新的效果*/font-weight: 700;/*color这个属性前面已经定义了,这里再写,就会覆盖前面的字体颜色*/color: red;
}
注意:选择器的层叠性,在后面的类选择器和 id 选择器同样适用
类选择器
在前面的标签选择器中我们通过标签选择器将很多重复的模块批量化的设置了它们的样式,但是在实际应用中,仅仅一个标签选择器还不足以满足我们日常的开发需求; 比如说,在标签选择器的案例中,我们是否想过,给“左小青”设置一个特殊的颜色呢?此时标签选择器的功能就不足以实现我们预期的效果了。
首先我们来了解一下类选择器的定义和使用
定义
<p class="article">class是定义类的关键字,article是类名,类名可以任意,但是要符合规范
</p>
class 是定义类的关键字,article 是类名,类名可以任意,但是要符合规范
使用
.article {color: red;font-size: 14px;
}
如果是内部样式,上面的代码就要写在<style></style>
标签之间,如果是外部样式,直接写在.css
文件中即可。
类选择器的作用就是在普通中寻找特别,下面我们就来实现上面的需求,给“左小青”设置一个特殊的颜色:
除此之外呢,一个标签上面还可以添加多个类名,类名之间要用空格隔开,就像这样:
<p class="common color font-size">common设置通用样式,color设置特殊颜色,font-size设置特殊字体大小
</p>
前面我们学过选择器的层叠性,那么这里是class="common current"
类名的先后顺序影响最终样式呢?还是<style></style>
标签中的类名先后顺序影响结果呢?
将class="common current"
改为class="current common"
,不会影响页面效果
再将
.common {font-size: 22px;color: #333333;letter-spacing: 8px;
}.current {color: #ff6973;
}
改为
.current {color: #ff6973;
}.common {font-size: 22px;color: #333333;letter-spacing: 8px;
}
.current
中的颜色会被.common
中的颜色层叠掉。
id 选择器
id 选择器与类选择器非常相似,首先我们看一下它的定义和使用格式:
在标签中定义 id
<p id="p-item">这是一段文字</p>
使用 id 选择器
#p-item {font-size: 24px;font-weight: 400;
}
可以看出,除了定义和使用的规范不同之外,基本没有什么变化,不同的地方是:
- id 选择器在文档中只会出现一次,像下面这种使用方式是不对的:
<a href="#" id="link">点击进入详情</a>
<!-- link这个id名已经被使用,就不可以再次定义 -->
<a href="#" id="link">点击进入主页</a>
id 就像身份证号码一样,全国只能有一个,同样,id 选择器亦是如此,这里的 link 重复了。
- 不能像类选择器一样,一个标签上定义多个 id 名,像下面这种写法是错误的:
<a href="#" id="link linkto">点击进入详情页</a>
id 选择器在写页面的时候用的不是很广泛,其性质与类选择器也相似,因此这里不做过多讲述。可以去用 id 选择器尝试修改之前的案例。
高级选择器
常用的高级选择器有四种:
- 后代选择器
- 交集选择器
- 子选择器
- 并集选择器
1. 后代选择器(空格)
p a
---- 选择所有p标签内的所有a标签
后代选择器的书写规则:用空格隔开,例如:
/* 选择id名为password的标签内部所有类名为box的元素内部的所有p标签 */
#password .box p{}
/* 选择所有p标签内部的所有span标签 */
p span{}
/* 选择所有p标签内部的所有类名为spanItem的标签 */
p .spanItem{}
代码如下:
<ul class="first-ul"><li>苍苍竹林寺,杳杳钟声晚。</li><li>荷笠带斜阳,青山独归远。</li>
</ul>
<ul class="second-ul"><li>白日依山尽,黄河入海流。</li><li>欲穷千里目,更上一层楼。</li>
</ul>
ul li {/* 去除li标签前面的小圆点 */list-style: none;font-size: 22px;
}.first-ul li {color: rgb(212, 166, 28);
}.second-ul li {color: rgb(230, 127, 122);
}
补充一点:从上面这个例子可以看出一种编程思想,就是抽离,将li
标签公有的属性抽离在ul li
选择器内,因为这个选择器选中的是所有的li
,然后再分别用.first-ul li
和.second-ul li
选择器来设置不同的属性。可能一开始我们会这样写:
.first-ul li {list-style: none;font-size: 22px;color: rgb(212, 166, 28);
}.second-ul li {list-style: none;font-size: 22px;color: rgb(230, 127, 122);
}
不过随着经验的积累,你或许会慢慢的会去思考着抽离。
重点理解后代
什么是后代?比如说,某某某是孔子的88代孙,那么某某某就是孔子的后代,在HTML
中,随着页面复杂程度的增加,会出现很多标签嵌套(标签里面写标签)的现象,比如:
<ul>父<li>子<p>孙<span>曾孙<a href="">曾曾孙</a></span></p></li>
</ul>
在这段代码中,标签和标签当中就形成了子代关系,a、span、p、li就是ul标签的后代,li既是ul的后代又是ul的子元素。 以上面的这段HTML代码为例,我要选中a标签,可以有很多办法:
/* 方法一: */
a{}
/* 方法二 */
ul a{}
/* 方法三 */
ul li p a{}
/* 方法四 */
ul li p span a{}
具体要用哪种方法呢?这是要根据具体情况(HTML的结构)来定的,比如说现在HTML的代码结构变了:
<ul>父<li>子<p class="p-one">孙<span>曾孙<a href="">曾曾孙1</a></span></p><p class="p-two">孙<span>曾孙<a href="">曾曾孙2</a></span></p></li>
</ul>
此时我们用上面的四种方法都会选到两个a标签,但是我们的目的是选中“曾曾孙1”,所以我们要在最开始出现重复标签的那一级来做区分,给这一级分别加上类名,或者你可以只给你需要的那个标签添加类名即可,此时我们要选中“曾曾孙1”可以这样做:
/* 方法一 */
ul li .p-one span a{}
/* 方法二 */
.p-one span a{}
2. 交集选择器
交集选择器的书写规则是:
a.special{}
<a href="#" class="special">超链接</a>
<a href="#">超链接</a>
<a href="#">超链接</a>
<a href="#">超链接</a>
它的意思是,在所有a标签内,类名为special
的标签。
举个例子:
实现效果如下:
- 电子产品
- 家居服饰
- 电竞手办
- 家装服务
- 房屋出租
核心代码如下:
<ul><li><a href="" class="special">电子产品</a></li><li><a href="">家居服饰</a></li><li><a href="">电竞手办</a></li><li><a href="" class="special">家装服务</a></li><li><a href="">房屋出租</a></li>
</ul>
ul li {list-style: none;font-size: 22px;
}ul li a {/* 去除a标签的下划线 */text-decoration: none;/* 这里的颜色一定要在a标签上设置,因为a标签默认会去设置字体颜色,会层叠掉默认的黑色 */color: black;
}ul li a.special {color: orangered;
}
3.子选择器
子选择器与后代选择器类似,不同的是后代选择器突出的是“后代”,子选择器突出的是“子”。 比如同样的HTML
代码,但是用不同的选择器,得到的结果就就不同,HTML
代码如下:
<p><span>Span 1. 在p标签内<span>Span 2. 在p标签的span标签内</span></span>
</p>
<span>Span 3. 与p标签相邻</span>
使用后代选择器:
span {color: black;
}p span {color: orangered;
}
使用子选择器:
span {color: black;
}p>span {color: orangered;
}
4.并集选择器
如果要给不同的标签,或者不同类名的标签添加相同的样式,此时就要用到并集选择器,并集选择器的规则是在标签名或者类名后面用逗号(,
)隔开,例如:。
.box,p,h3,.phone{}
并集选择器的作用是--“和”,上面这段代码的意思就是给类名为box
、phone
标签名为p
、h3
的标签添加相同的属性。
有了前面的选择器基础,相信并集选择器大家都可以理解,这里就不做过多解释啦~
选择器的优先级
单个选择器的优先级
单个选择器的优先级很容易理解,可以记下这个顺序id 选择器>类选择器>标签选择器,什么意思呢?举个例子来说明一下。
比如说我们有这样一段HTML
代码:
<p class="poem" id="ch-poem">百川东到海,何时复西归?</p>
第一步
用p
标签来设置文字的颜色:
p {color: blue;
}
第二步
在p
标签的基础上加上类选择器:
p {color: blue;
}.poem {color: red;
}
在这里,有人会想,是不是因为.poem
在p
后面,层叠掉了之前设置的blue
呢?其实并不是,层叠是在优先级相同的情况下,上下位置的不同会导致属性被层叠
第三步
在上面两步的基础上添加 id 选择器:
p {color: blue;
}.poem {color: red;
}#ch-poem {color: purple;
}
同样,在这里不论如何移动选择器在CSS
代码中的位置,都不会影响最终的结果。
文字属性的继承性
在前面我们已经学过关于文字的一些属性,例如font-size
(文字大小)、font-weight
(文字粗细)、font-family
(字体)、color
(文字颜色)等,在这里我们要学一下文字的另一个知识点--文字属性的继承性。
大家有没有发现,除了h
标签,其它的标签内写了文字以后,默认会有相同的颜色、大小,这就是文字属性的继承性导致的,他们都继承了body
标签的字体大小、颜色。
为了验证这个说法,我们可以用代码来验证一下,HTML
代码如下:
<ul class="ul-item">蒹葭<li>蒹葭苍苍,白露为霜。所谓伊人,在水一方。</li><li>溯洄从之,道阻且长。溯游从之,宛在水中央。</li><li>蒹葭萋萋,白露未晞。所谓伊人,在水之湄。</li>
</ul>
下面我们在ul
标签上修改文字的颜色:
.ul-item {color: #ff6973;
}
我们本想修改 ul 标签里的“蒹葭”二字,但是却把li
标签内的文字颜色也一起修改了,这就是---文字属性的继承性
这里只是用文字颜色做了实验,另外文字的字体大小,字体,字间距等都会被继承到。
高级选择器的优先级
权重的计算方法
单个选择器的优先级可以通过id 选择器>类选择器>标签选择器的顺序去判断,那么多个选择器的优先级该如何去判断呢?
这里就要用到选择器权重的叠加性,按照优先级越高,权重越大的规则,假设 id 选择器的权重为 100,类选择器的权重为 10,标签选择器的权重为 1,我们可以计算一下下面这个高级选择器的权重:
.param #item span {
}
根据规则可以计算得出,这个高级选择器的权重为 111=100(#item
)+10(.param
)+1(span
)。再比如下面这个选择器的权重:
#item1 #item2 .param1 .param2 p span {
}
它的权重为:222=200(#item1 #item2
)+20(.param1 .param2
)+2(p span
)
那么权重的计算会不会进位呢?比如高级选择器有 11 个标签选择器,会不会往类选择器上进一位呢?答案是不会的,当然了,你也不会遇到这种情况,标签套十层已经不便于阅读了。
权重的应用
权重的作用
学会了如何计算权重以后,我们就要去想怎么去用权重呢?权重的作用是什么?权重的作用就是决定当用两个不同的选择器给同一个标签设置了相同的属性,该听谁的?
例如下面这个案例:
<ul class="ul-item"><li><p>文字的颜色到底是什么颜色?</p></li>
</ul>
ul li p {color: blue;
}
p {color: red;
}
在这里,为了消除有同学质疑是因为层叠性的原因导致字体颜色是blue
,我专门将设置blue
的选择器放在了上面。在这里要注意一点,层叠性只有在权重一样的情况下才会适用。
接下来我们来推导一下为什么字体颜色是blue
,根据前文所学,我们知道,权重的作用就是决定当用两个不同的选择器给同一个标签设置了相同的属性,该听谁的,根据权重的计算公式可以知道,第一个选择器的权重为 3,第二个选择器的权重为 1,所以最终字体颜色应该由第一个选择器决定,也就是蓝色。
什么情况下可以考虑权重?
我们来再看一个案例:
<ul class="ul-item"><li><p>文字的颜色到底是什么颜色?</p></li>
</ul>
.ul-item li {color: blue;
}
接下来在CSS
代码中增加一点代码:
.ul-item li {color: blue;
}
p {color: red;
}
此时就有点“违背常理”了,根据计算,第一个选择器的权重是 11,第二个是 1,权重决定着谁设置的属性会生效,一切都有理有据,但是结果却和我们想的不一样,这是因为第一个选择器脱离了权重的适用范围,即选中。
可以看到,第一个选择器权重虽然大,但是它只选到了li
标签,而第二个选择器是直接选中了p
标签,没有选中,当然权重再大也无济于事。
那么在这个案例中,第一次通过.ul-item li
选择器设置颜色的时候,为什么会生效呢?这是因为字体属性的继承性,p
标签的字体继承了它父元素li
的字体属性。
再来一个案例,具体代码如下:
<ul class="ul-item"><li class="li-item"><p>文字的颜色到底是什么颜色?</p></li>
</ul>
.ul-item .li-item {color: yellowgreen;
}.ul-item li {color: black;
}
在这个案例中我们如何去确定颜色呢?答案是根据权重+继承性
:
首先我们要知道字体属性的继承性的另一个性质,就是字体属性继承的是离它最近的一个父类标签,什么是最近?就是最先包裹住它的标签,在这个案例中,最近的父类标签就是li
标签。
li
标签的字体颜色直接决定着p
标签的字体颜色,接下来我们就要看设置li
标签的选择器有哪些?案例中两个选择器都选中了li
标签,在都选中的情况下,就要想到权重,根据计算,第一个选择器.ul-item .li-item
权重为 20,第二个选择器.ul-item li
权重为 11,所以最终的颜色自然是yellowgreen
。
盒模型
content
在网页布局中,页面其实是由一个个大小不一的小块构成,例如淘宝页面当中就很常见,比如浏览商品的时候,商品的缩略图:
下面我们来学习如何在页面中画出一个矩形的格子:
要画一个矩形的格子,首先要了解一个新的标签 -- div
标签。
在学习HTML
的时候,我们已经接触过了类似于div
的标签,比如
h
标签p
标签ul
标签li
标签
这些标签有一个共同的特性,就是可以独占一行,它们都是在div
标签的基础上进行改造的,添加了 margin、padding、文字大小等等,当然了,还被赋予了其它默认的特性,这里我们不做过多解释。
最后可以总结为,div
就是一个干净透彻的矩形:
由四部分组成:
- 内容区
content
- 内边距
padding
- 边框
border
- 外边距
margin
注意顺序,由内到外。
如果由外到内讲,就是 外边距、边框、内边距、内容区
如果你觉得有些抽象,那么可以用现实生活中的例子帮助我们理解:
编程的概念总是抽象的,现实例子可以 帮助 我们理解概念,但千万不要等同
由于 div
是一个矩形,那么实际上 内边距、边框、外边距 又由 上、下、左、右 四条边组成。
把 div 拆分的这么细,就意味着四条边既可以统一设置样式,也可以分开设置样式。
内容区是最中心的完整区域,就没有四边的概念了。换句话说,内容区的四条边的样式,由 内边距、边框、外边距 的样式决定
div 矩形的四个组成部分,就是所谓的“盒模型”,也是本章的主要内容,我们会一一学到。
内容区:content
首先我们要学习的是 div 的 content
。
div
标签写出来的时候是没有高度的,但是有宽度,宽度默认和父标签的宽度是一样的。比如我们在页面中只写一句代码:
<div></div>
通过审查元素(审查元素的技术在进阶中会讲到)可以看到div
的尺寸如下:
可以看到,div 的宽度是1661px
高度是0px
,与前文中讲到的div
标签默认是没有高度的,宽度和父标签的宽度一样,如果直接在body
标签里写一个div
标签,那么div
的父标签就是body
标签,如果是下面代码中这样写的,那么div
的父标签就是li
标签,那么div
的默认宽度就是li
标签的宽度。
<ul><li><div></div></li>
</ul>
这里所说的宽度不是肉眼看到的宽度,而是 width 属性设置的宽度
width/height
要画一个矩形,首先要设置矩形的宽高,矩形的宽高对应两个 CSS 属性width
,height
,它们的值是数字,单位是px
。
下面我们来画一个宽 200px,高 100px 的矩形:
核心代码如下:
<div class="box"></div>
.box {width: 200px;height: 100px;
}
但仅仅这样写,我们在页面上是看不到这个矩形的,因为我们还没有给它着色,而 div 默认是不填充颜色的。
要给矩形添加背景颜色,需要学习一个新的 CSS 属性,background-color
--背景颜色,这个属性的值跟我们设置字体颜色时候学的一样,有十六进制,rgb
,rgba
,英文单词形式的颜色,下面我们给刚才设置的矩形添加一下背景颜色,最终实现的效果如下:
核心代码如下:
<div class="box"></div>
.box {width: 200px;height: 100px;background-color: purple;
}
百分百尺寸
设置块元素的宽高,除了px
形式,还有%
形式,比如说:
<div class="father"><div class="son"></div>
</div>
.father {width: 200px;height: 80px;background-color: #5b6dcd;
}
.son {width: 60%;height: 20%;background-color: #fec03e;
}
注意:这里的%
是相对于父元素的,也就是说,子元素的宽度是父元素的60%
(200px*60%=120px
),子元素的高度的20%
(80px*20%=16px
),所以首先要确定父元素的尺寸是存在的。
什么情况下,父元素的尺寸是不存在的呢?比如说,我们想设置一个矩形,矩形铺满整个浏览器的屏幕,我们或许会这样去设置:
<div class="bg"></div>
.bg {width: 100%;height: 100%;background-color: blue;
}
这时候你会发现,浏览器依然是白色,这是因为.bg
的父元素body
的高度默认是0px
,0px
的百分之百还是0px
,但是body
的宽是有的,默认和浏览器页面宽度一样。
盒模型--padding
经过上一节的学习,大家已经了解了盒模型的一部分,即内容部分,接下来要学习的是盒模型中的内边距--padding
,比如说我们最常见的网页的标题栏部分(点击可以放大图片):
我们可以很清楚的看到,由绿色边框圈起来的文字,距离上、下、左、右都有一定的距离,或许这个例子看起来有点难受,它太小了,我们可以换一个更大更明显的例子:
这样看起来就舒服多了,接下来我们来仿写一个上面的案例:
核心代码如下:
<div class="box">All afternoon his tractor pulls a flat wagon with bales to the barn, then back to the waiting chopped field. It trails a feather of smoke. Down the block we bend with the season: shoes to polish for a big game,storm windows to batten or patch. And how like a field is the whole sky now that the maples have shed their leaves, too.
</div>
.box{width:300px;height:300px;background-color:purple;padding:20px;color:white;
}
为了能够更好的理解padding,可以参考一下下面这张图:
注意:padding
区域是包含在背景颜色区域内的,也就是说背景颜色包含了padding
和content
。
padding分开写
padding默认是给矩形四周添加相同的内边距,但是我们在实际应用当中会有四周内边距不同的情况,因此我们就要分别给矩形设置内边距,没有设置的内边距默认为0。
.box {padding: 20px;
}
上面的代码等价于:
.box {padding-top: 20px; /*上内边距*/padding-right: 20px; /*右内边距*/padding-bottom: 20px; /*下内边距*/padding-left: 20px; /*左内边距*/
}
padding简写
学习padding
分开写的形式主要是为了更好的理解如何简写padding
,现在我们知道了padding
分为top
、right
、bottom
、left
,在简写的时候就会从这四个方向上去设置。
之前我们知道这种形式的简写padding: 20px
,意思是给content
的上、右、下、左四个方向上都设置了相同的padding
,它最初的形式是这样
div{padding:20px 20px 20px 20px;
}
这四个值分别代表,上、右、下、左,如果四个值都一样,就可以写成padding:20px;
,如果不一样,可以分为一下几种情况:
1. 上下一样,左右一样
例如:
div{padding-top: 20px;padding-bottom: 20px;padding-left: 30px;padding-right: 30px;
}
上下一样,写一个即可,左右一样,写一个即可,最后变成:
div{padding: 20px 30px;
}
那么,有人会问,后面的两个值可以颠倒位置吗?答案是不可以
div{padding: 30px 20px;
}/* 这句话就会被翻译为 */
div{padding-top: 30px;padding-bottom: 30px;padding-left: 20px;padding-right: 20px;
}
永远记住,第一个值是上,第二个值是右,第三个值如果没有,就和第一个值保持一致,第四个值如果没有就和第二个值保持一致。
2. 上下一样,左右不一样
比如:
div{padding-top: 20px;padding-bottom: 20px;padding-left: 10px;padding-right: 30px;
}
使用简写形式要这样写:
div{padding: 20px 30px 20px 10px;
}
3. 上下不一样,左右一样
比如:
div{padding-top: 30px;padding-bottom: 20px;padding-left: 10px;padding-right: 10px;
}
使用简写形式要这样写:
div{padding: 30px 10px 20px;
}
可以这样来理解,第一个值是上30px
,第二个值是右10px
,第三个值是下20px
,第四个值是左,但是没有,所以要跟右一致。
总结下来就是上、右、下、左按照顺序去填写,没有的值就跟对立面的值一样,下对上,左对右。
box-sizing
box-sizing
规定了如何计算一个元素的总宽度和高度,它有两个值content-box
,border-box
,默认是content-box
。
-
content-box
尺寸计算公式:width = 内容的宽度 height = 内容的高度
-
border-box
尺寸计算公式:width = border + padding + 内容的宽度 height = border + padding + 内容的高度
也就是说,
box-sizing
规定了两种计算方法,每个值代表一种计算方法。工程师 不能 任意写计算公式
这里的内容就是我们学过的content
,border
属性我们还没有学,但是在这里已经可以说明一下box-sizing
属性的性质,下一节学习border
的时候,我们会将border
的尺寸也算进去。
举个例子说明一下:
<div class="father"><div class="son"></div>
</div>
.father{width:200px;height: 100px;background-color: #5C70CA;
}.son{box-sizing: content-box;width: 100%;height: 40px;background-color:#FEC03E;
}
修改一下CSS
代码:
.father{width:200px;height: 100px;background-color: #5C70CA;
}.son{box-sizing: content-box;width: 100%;height: 40px;/* 添加padding */padding: 0px 20px;background-color:#FEC03E;
}
子元素超出的原因就是,width: 100%
属性给子元素设置了和父元素content
一样的宽,又设置了padding
在原有的基础上又增加了左右padding
超出了父元素content
区域。
.father{width:200px;height: 100px;background-color: #5C70CA;
}.son{/* 修改box-sizing */box-sizing: border-box;width: 100%;height: 40px;/* 添加padding */padding: 0px 20px;background-color:#FEC03E;
}
效果如下:
border-box
的width
包含了content
、padding
、border
,所以设置padding
,border
后不会溢出父元素的content
。
盒模型--border
学习了盒模型的content
、padding
之后,基本上我们就可以满足很多开发的需求,接下来我们要学习的是盒模型中的边框--border
。
边框就是包裹在padding
外面的一层线,说到线,肯定会有粗细、颜色,首先我们要学习如何给一个矩形设置边框线。
给矩形设置边框线
设置边框线的语法是(请注意花括号里面的内容,.box 是类名,类名是可以自己定义的):
.box {/* 设置矩形大小 */width: 200px;height: 30px;/* 设置边框线 */border-width: 2px;border-color: grey;border-style: solid;
}
显示效果如下:
这样我们就给一个类名为 box 的矩形的四周添加上了边框线,接下来我们要来解释一下每一个属性具体是什么意思:
border-width
:边框的粗细,单位是 px
border-width:1px;
border-width:3px;
border-color
:边框的颜色,颜色值和我们之前学的文字、背景的颜色表示方法是一样的
border-color: red;
border-color: #2AA3FF
border-color:rgb(251, 186, 8)
border-style
:边框的线型,solid
为实线,dashed
为虚线,当然还有其它的线型,最常用的是这两种
border-style: solid;
border-style: dashed;
边框的简写
通过上面的演示我们发现,仅仅是简单的设置了一个边框,就需要三行代码,显得很繁琐,其实 CSS 代码中是有很多简写的方式的,拿边框来说,我们完全可以用一行代码来实现上面三行代码的效果。
.box {border: 2px solid blue;
}
补充一点:border
后面跟的三个值之间要用空格隔开,值的顺序是可以忽略的,比如你可以写成 2px blue solid
,效果是一样的。
分别设置边框
在我们学习padding
的时候,我们曾经给padding
的上下左右设置了不同的值,那么在border
中同样是可以这样设置的。
首先我们来看一种繁琐的设置方式,但是并不推荐这种:
.box {/*设置顶部border*/border-top-color: blue;border-top-style: solid;border-top-width: 2px;/*那么接下来,left,right,bottom是类似的,这里忽略不写*/
}
效果如下:
我们重点关注推荐的书写方式:
.box {/* 添加顶部border */border-top: 1px solid black;/*添加右侧border*/border-right: 3px solid orange;/*添加底部border*/border-bottom: 5px dashed pink;/*添加左侧border*/border-left: 10px dashed purple;
}
这样我们就可以随心所欲的给矩形的四周添加不同的边框了。点击查看一下下方案例的最终效果,感受一下吧~
利用层叠性设置边框
在实际应用当中,我们可能会遇到这样一种情况,要设置一个矩形,矩形的左、右、上的边框样式是相同的,但是下边框的样式是不一样的。
这时候我们就可以用属性的层叠性来实现,核心代码如下:
.box {/*设置矩形的宽*/width: 300px;/*设置矩形的高*/height: 300px;/*设置矩形的背景颜色*/background-color: white;/*设置矩形的边框*//*统一设置矩形的所有边框样式*/border: 2px solid black;/*重新设置一个下边框的样式来层叠掉统一设置的边框的样式*/border-bottom: 5px solid orange;
}
代码演示
有了这个方法,我们就可以在特定的情况下,加以灵活的应用,来减少代码书写量。
无边框
在上一个案例中,我们用排除法将下边框设置成了特殊的样式,那么如果我们需要让下边框不显示呢?
这时候就需要border
的另一个属性值--none
.box {border-bottom: none;
}
代码演示
圆角
在很多场景下,矩形一般都不是四四方方的,需要一点点的圆角来点缀,圆角的属性是归类于边框的,即border-radius
。有了之前的基础,相信圆角对大家来说很好理解。
圆角的统一设置
首先先来说一下圆角的设置方法:
.box {border-radius: 12px;
}
上面这段代码只是设置圆角的方法,此时如果不设置矩形的宽、高,背景色或者边框颜色,圆角是看不出来的,但是请记住,看不到并不代表不存在。
如果要看到效果,需要这样写:
div {width: 200px;height: 200px;border-radius: 18px;border: 1px solid black;
}
实现效果如下:
或者设置背景颜色也可以看到效果:
div {width: 200px;height: 200px;background-color: violet;border-radius: 18px;
}
实现效果如下:
圆角分开设置
与padding
、border
属性一样,border-radius
属性也是可以拆开来设置的,只不过它没有上下左右,而是左上角,右上角,右下角,左下角。具体写法如下:
.box {width: 200px;height: 200px;background-color: violet;border-top-left-radius: 5px;border-top-right-radius: 10px;border-bottom-left-radius: 20px;border-bottom-right-radius: 15px;
}
实现效果如下:
阴影
<div class="box"></div>
.box {width: 200px;height: 200px;border: 1px solid #c4c4c4;/* x偏移量 | y偏移量 | 阴影模糊半径 | 阴影扩散半径 | 阴影颜色 */box-shadow: 2px 2px 2px 1px rgba(0, 0, 0, 0.2);border-radius: 15px;
}
实现效果如下:
阴影的实现原理可以看作是在矩形下面有一个重叠的,同样大小的矩形,如果它在 x 轴、y 轴上移动,就会有阴影的效果。
- x 偏移量:在 x 轴上移动,向右为正
- y 偏移量:在 y 轴上移动,向下为正
- 阴影模糊半径:就是边线的清晰度
- 阴影扩散半径:就是向外伸展
- 阴影颜色:就是矩形下面那个矩形的背景色。
盒模型--margin
在这一节我们要学习的是盒模型中的margin---外边距。所谓外边距就是矩形和矩形之间的距离,我们可以看一下下面这张图:
如果想要中间红色边框的矩形与四周绿色背景的矩形之间有一定的间隙,就可以给红色边框的矩形设置一个margin属性。
接下来我们来实现一下下图的页面效果,来感受一下margin的作用(因为我们还没有学习浮动,所以暂时还不能设置左右margin):
具体实现代码如下:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>案例</title><style>div {width: 300px;height: 100px;background-color: #D5E8D4;border: 1px solid #82B366;}.box{background-color: #F5F5F5;border: 1px solid #FF0818;margin-top: 20px;margin-bottom: 20px;}</style>
</head><body><div></div><div class="box"></div><div></div>
</body></html>
下面我们看一下这段代码:
.box{background-color: #F5F5F5;border: 1px solid #FF0818;margin-top: 20px;margin-bottom: 20px;
}
在这个代码演示中,我们可以通过这一段代码看出,其实margin的设置方式跟padding是一样的,可以得出margin的书写方式:
.box{/*总写*/margin: 20px;/*分开写*/margin-top: 20px;margin-right: 20px;margin-bottom: 20px;margin-left: 20px;
}
两个盒子之间margin的计算
水平距离
首先我们来看最容易理解的水平距离,下图中,第一个盒子的右margin为30px,第二个盒子的左margin为20x,那么最后两个盒子之间的水平距离就是30px+20px=50px;如果第二个盒子没有设置magrin-left,那么默认为第二个盒子的margin-left为0px。
垂直距离
水平距离很符合我们的常规理解,但是垂直距离就略有不同,垂直距离取两个盒子margin的最大值。
如下图所示,首先,只给其中一个盒子设置margin-bottom,两个盒子之间的垂直距离就是第一个盒子的margin-bottom; 然后,给第二个盒子设置一个margin-top,但是值小于第一个盒子的margin-bottom的值,得到两个盒子之间的垂直距离,是取两个margin的最大值; 最后,将下方盒子的margin-top设置为50px,大于第一个盒子的margin-bottom,两盒子之间的垂直距离变成了50px。
在实际应用当中,我们如果要设置两个盒子之间的垂直距离,一般不会去写两个margin,比如我要设置两个盒子之间的垂直距离为50px
不推荐
.box1{margin-bottom: 20px;
}
.box2{margin-top: 50px;
}
推荐
.box1{margin-bottom: 50px;
}
不推荐
.box2{margin-top: 50px;
}
因此,要设置两个盒子之间的垂直距离,选择其中的一个去设置即可。
盒子左右居中
margin还有一个作用就是使盒子可以在父盒子中左右居中,但是有一个前提,就是必须有宽度。
例如下面这个案例:
<div class="father"> <div class="son"></div>
</div>
.father{width:400px;height:200px;border: 1px solid #ccc;
}.son{width:200px;height:100px;margin:0 auto;border: 1px solid #ccc;
}
此时如果将son中的width去掉,你就会发现居中效果失效了。
盒模型--display:block/none
display: block
块元素性质一--独占一行
在学HTML
的标签的时候,我们应该对块、行内这种词汇有所了解,比如说我们常用的h
标签就是一个块级标签,这样的标签的性质就是独占一行,例如:
<span>这是一个span标签</span>
<h3>这是一个h3标签</h3>
<h4>这是一个h4标签</h4>
这段代码的结果只能是这样:
这是一个 span 标签
这是一个h3标签
这是一个h4标签
而不会是这样:
这就是块元素的性质,独占一行,如下图所示,第一行是两个行内元素,可以并排显示;第二行是一个块元素,内容部分是蓝色部分,剩下的部分用灰色占位,所以其它的标签元素不能跟它在同一行显示。
块元素性质二--可以设置宽高
首先我们做一个对比实验,在一个行内元素上添加背景颜色,设置宽高,看看背景颜色的范围是否可以扩大,以span
标签为例:
<span class="demo"> 这是一个span标签 </span>
.demo {width: 300px;height: 100px;background-color: #fff2cc;
}
可以看到,我们即使给行内元素span
设置了宽、高,却根本不会生效。
接下来我们在上面的代码基础上将span
标签修改成div
标签看看效果:
<div class="demo">这是一个div标签</div>
.demo {width: 300px;height: 100px;background-color: #fff2cc;
}
行内元素和块元素之间的转换
标签是行内元素还是块元素,其根本原因就是标签自带的默认display
属性:
- 块元素默认的
display
属性的值是block
- 行内元素默认的
display
属性的值是inline
行内元素转块元素
接上面的那个案例,我们要想给span
标签设置宽、高,首先要让span
标签转换成块元素,然后再给它设置宽高,我们的做法是这样:
<span class="demo"> 这是一个span标签 </span>
.demo {/*将span标签转换成块元素*/display: block;width: 300px;height: 100px;background-color: #fff2cc;
}
行内元素可以通过display
属性转换成块元素,从而达到设置宽高的目的,那么我们也可以用这个方法让块元素失去设置宽高的能力,我们的做法是这样:
<div class="demo">这是一个span标签</div>
.demo {/*将div标签转换成行内元素*/display: inline;/* 转换成行内元素以后,宽、高的设置就会失效,即使我们仍然设置了它们 */width: 300px;height: 100px;/* 背景颜色也不会是300*100范围,而是文字有多少面积,背景颜色就又多少面积 */background-color: #fff2cc;
}
display: none;
none
就是无的意思,也就是说,当给标签设置了这个属性值,标签就会消失,在网页布局中最常用的就是用none
、block
来控制元素的显示和隐藏。
可以看一下下面这个例子:
<div>盒子1</div>
<div class="box2">盒子2</div>
<div>盒子3</div>
div {width: 300px;height: 100px;/* 使用text-align属性让文字左右居中 */text-align: center;margin-bottom: 10px;background-color: #d5e8d4;/* 使用行高让文字上下居中 */line-height: 100px;
}.box2 {display: none;
}
盒模型--display:inline/inline-block
inline
在上一节我们已经用过inline
,在这一节我们需要更细致的探索它的性质
1. 行内元素不能设置宽、高;
这个属性我们在上一节的时候已经接触,这里不做解释
2. 行内元素可以设置padding
;
<a href="#">超链接</a>
a {background-color: #fff2cc;padding: 20px;
}
注意:虽然这样做可以给人块元素的感觉,但是还是有区别的,不要用这种方式去设置一个规定大小的块,否则会出现如下的奇怪现象。
<a href="#">超链接</a>
<div></div>
a {background-color: #fff2cc;padding: 20px;
}
div {width: 300px;height: 50px;background-color: #b0e3e6;
}
效果如下
点击下方播放按钮查看演示
代码演示
3. 行内元素可以设置左右margin
,但是不能设置上下margin
<a href="#">点击跳转到</a>
<span>优课达</span>
<div></div>
a {margin-left: 40px;margin-right: 30px;margin-top: 400px;margin-bottom: 400px;
}span {margin-left: 20px;
}div {width: 300px;height: 50px;background-color: #b0e3e6;
}
可以看到,我们虽然设置了很大上下margin
,但是毫无效果,但是左右margin
实现的效果与块元素的margin
效果是一样的。
inline-block
从名字可以看出,inline-block
既具有block
的性质,还具有inline
的性质,可以简单的理解为,inline-block
就是一个可以在同一行显示的块元素。
inline-block
要比block
在应用中更为广泛,因为我们更多的时候需要的是一个能和其他元素共存的盒子,相比而言,block
显得较为孤僻。
关于inline-block
这个值的作用,大家可以根据block
的性质去理解,这里主要给大家介绍一下空白折叠的现象。
按照常理,我们将div
的display
属性从block
切换成inline-block
之后,我们希望得到的效果是这样的:
可以看到,两个盒子中间多了一点空白,但是我们并没有设置margin
,这就是传说中的空白折叠现象,其原因就是因为两个 div 之间多了一个回车,在html
中,回车被当作是一个文字,所以这里的空白就是文字的空白,相当于在两个div
之间加了一个字母。
解决这个空白的办法有三种:
1. 去除回车
<!-- 将div标签写在一行 -->
<div class="box1"></div><div class="box2"></div>
div {width: 200px;height: 50px;display: inline-block;
}.box1 {background-color: #fff2cc;
}.box2 {background-color: #b0e3e6;
}
2. 给父元素添加 word-spacing 属性
word-spacing
就是单词和单词之间的距离,这里将这个距离写成负值就可以了,这个值要尽量小,我们一般写小于-20px 的值。
具体做法如下:
<div class="father"><div class="box1"></div><div class="box2"></div>
</div>
.father {word-spacing: -50px;
}.box1 {width: 200px;height: 50px;display: inline-block;background-color: #fff2cc;
}.box2 {width: 200px;height: 50px;display: inline-block;background-color: #b0e3e6;
}
因为预览屏幕宽度问题,可能会出现上下排列的问题,此时我们可以拖动预览屏幕的边框,让预览屏幕的宽度变宽一点,就会显示我们需要的效果。
3. 给父元素设置 font-size: 0px;
从第二点我们了解到,回车可以当作是一个文字,那么如果将文字大小设置为 0,空隙自然就会消失。
具体做法如下:
<div class="father"><div class="box1"></div><div class="box2"></div>
</div>
.father {font-size: 0px;
}.box1 {width: 200px;height: 50px;display: inline-block;background-color: #fff2cc;
}.box2 {width: 200px;height: 50px;display: inline-block;background-color: #b0e3e6;
}
定位
Position-static(默认定位)
这一节我们学习一下 CSS 的一个非常关键的属性 — position
,这个属性在 CSS 用于定位 DOM 元素,修改 DOM 元素的布局。
我们会继续沿用之前的文章例子进行讲解,我们先来实现如下视频的网页效果。
大家学到这一章节,上面网页效果应该很容易实现。我们先开看看 HTML 代码:
<!DOCTYPE html>
<head><link rel="stylesheet" type="text/css" href="./index.css" /><title>优课达</title>
</head>
<body><h1 class="title">MOUNTAIN</h1><p>The Facebook post was heartfelt. We like our little town just as it is:Little. Homey. Just us’ns.</p><div class="img-box"><imgalt=""class="first"src="https://document.youkeda.com/P3-1-HTML-CSS/1.8/1.jpg?x-oss-process=image/resize,h_300"/><imgalt=""src="https://document.youkeda.com/P3-1-HTML-CSS/1.8/2.jpg?x-oss-process=image/resize,h_300"/><imgalt=""src="https://document.youkeda.com/P3-1-HTML-CSS/1.8/3.jpg?x-oss-process=image/resize,h_300"/><imgalt=""src="https://document.youkeda.com/P3-1-HTML-CSS/1.8/4.jpg?x-oss-process=image/resize,h_300"/></div><h2>LISTEN</h2><p>Listen, I can empathize. As someone who’s lived in the Denver area since1971 — right about the time John Denver’s songs were enticing folks to move</p><footer></footer>
</body>
CSS 文件中,我们设置一些基础样式。
body {margin: 0; /*去掉默认的样式*/font-family: Sans-serif;color: rgba(0, 0, 0, 0.84);font-size: 16px;padding: 30px;
}img {width: 100%;
}
注意: img 默认会根据图片自身的宽度展示,因此我们给他设置 width:100%,撑满左右屏幕。
大家可能会发现,我们在index.css
中并没有设置任何的position
属性。浏览器会自动给所有的 DOM 元素,添加position: static
,如下图所示。
因此 static 遵循默认的文档流布局,top、left、right、bottom(我们在后面几节会讲到这几个属性)属性都无效。
position 除了 static 属性值外,还有 4 个常用值,分别为:
- relative(相对定位)
- absolute(绝对定位)
- fixed(固定定位)
- sticky(粘性定位)
接下来,我们分别来学些下这几个值有什么特点。
Position-relative(相对定位)
在上一节课的基础上,如果我们想让第一张图片往右下角分别移动 50px,如下效果图,那我们该怎么实现?
大家第一反应,可以使用margin
使图片进行偏移,设置下 CSS 如下所示
.first {margin-left: 50px;margin-top: 50px;
}
结果预览和我们想要的效果不太一样。第一张图片确实右下移动了,但是文档下面部分也同样往下移动了 50px。也就是margin
会引起文档流的变化。大家可以自己手动在右侧修改测试一下效果。
这里我们就可以利用 left, top
来实现想要的效果。在上一节中,我们知道 position: static
下不能使用 left, top, right, bottom
属性,如果我们想在当前位置进行偏移,同时不影响整体页面布局。可以使用 relative
CSS 如下:
.first {position: relative;left: 50px;top: 50px;
}
- left:50px,表示距离自己原来位置左侧 50px
- top: 50px,表示距离自己原来位置顶部 50px
注意:
relative 先遵循默认的文档流布局也就是上一文说的 static 布局,然后再在不改变页面布局的前提下根据 left、right、top、bottom 调整此元素的位置。
也就是 left、right、top、bottom 的调整都是 相对于当前元素 static 布局位置进行的调整。
relative 也被称为 相对定位
Position-absolute(绝对定位)
我们继续修改 position 的属性,在上面代码的基础上,如果我们把 position: relative
改为 position: absolute
结果会怎么样呢?
CSS 代码如下:
.first {position: absolute;left: 50px;top: 50px;
}
我们来看看结果
在图中 和 relative
相比较
- 文档第一张下面的所有 DOM 元素,自动往上移动占据了第一张图片的位置,文档流(布局)已经没有为第一张图预留空间了
- 第一张图片脱离了文档流,变成了第二个图层,再在新的图层中往右下偏移 50px
在 MDN 中,官方描述为
absolute 被称为 绝对定位 绝对定位不为元素预留空间,通过指定元素相对于最近的非 static 定位祖先元素的偏移,来确定元素位置
我们重点理解下,什么叫做 相对于最近的非 static 定位祖先元素的偏移 ?
在这里,我们提取三个关键词 最近 和 非 static 定位 和 祖先元素。连贯起来分析下在上面的网页中,浏览器是怎么布局 absolute 元素的。
- 首先我们获取到第一张图片元素
<img class="first" src="xxx"/>
,我们发现它是 absolute 布局 - 因此寻找它的父亲节点
<div class="img-box">
,我们发现此元素并未配置 position 属性,其遵循默认布局 position = static,并不符合非 static要求。 - 因此继续找
<div class="img-box">
的父亲节点,找到<body>
<body>
已经没有父亲节点了,所以按照<body>
的位置为标准进行偏移
大家一定要顺着上面的思路捋一捋布局逻辑!
接下来,如果我们把 <div class="img-box">
元素设置 position: relative 会出现什么样的情况呢?
……
.img-box {position: relative;
}.first {position: absolute;left: 50px;top: 50px;
}
……
实际结果为:
我们会发现第一张图片相对于 <div class="img-box">
进行了偏移,而不是之前的body
元素。
总结 absolute(绝对定位) 和 relative(相对定位)的区别:relative 是相对自己进行 top、left、right、bottom 进行偏移;而 absolute 是寻找最近的 非 static 的祖先节点进行偏移。
Position-fixed(固定定位)
在很多场景下,文章的标题会一直停留在浏览器的顶部,不会随着页面的滚动而消失,比如下面视频效果:
MOUNTAIN 这个单词不会随着页面而滚动,会一直停留在顶部 50px 的地方。
这就是 fixed 的功能,和英文单词意思非常相近 —— 固定。
我们给 H1 标签添加 fixed
属性。
为了方便观看,我们注释掉原来的第一张图的 CSS 代码,最终的 CSS 代码如下:
body {margin: 0; /*去掉默认的样式*/font-family: Sans-serif;color: rgba(0, 0, 0, 0.84);font-size: 16px;padding: 30px;
}img {width: 100%;
}h1 {position: fixed;/*去掉H1默认的样式*/padding: 0;margin: 0;left: 30px;top: 50px;color: yellowgreen; /*为了方便观看,我们修改MOUNTAIN的颜色*/
}.img-box {position: relative;
}/*
.first {position: relative;left: 50px;right: 50px;
} */
我们会发现无论怎么滚动,MOUNTAIN 永远在窗口的左上角。
fixed 为 固定定位
固定定位和绝对定位类似,但元素的包含块为屏幕视口(viewport)
固定定位不为元素预留空间,而是通过指定元素相对于屏幕视口(viewport)的位置来指定元素位置。元素的位置在屏幕滚动时不会改变。
但继续滚动,我们会发现 MOUNTAIN 被图片区域遮挡了,这是为什么呢?如下图:
这就需要 z-index
来解决了。
z-index
在刚才 absolute
, fixed
演示中,我们知道 HTML 页面是由多个图层构成的,那浏览器怎么决定不同的图层优先级呢(到底是谁覆盖谁、谁在谁的上面,谁离观察者最近)?这就是 z-index
决定。
- 默认非 static 元素的 z-index 都为 0
- z-index 越大,则越在最上面,离观察者越近
- 同样的 z-index, 在 HTML 中的元素越靠后,则越在最上面,离观察者越近
因此,分析下上面的场景中 <h1>MOUNTAIN</h1>
元素 和 <div class="img-box"></div>
元素 都是非 static 元素,z-index
都为 0。 而因为<h1>
在文档流前部,因此会被后者遮挡,所以 MOUNTAIN 移动到图片区域时,被图片遮挡了,那我们如何解决?
很简单,我们修改 <h1>
的 z-index
大于 0 即可!大家可以修改下代码,观察下效果,如下所示:
h1 {position: fixed;left: 30px;top: 30px;z-index: 1;color: yellowgreen;
}
举例:
<!DOCTYPE html>
<head><meta charset="utf-8" /><link rel="stylesheet" type="text/css" href="./index.css" /><title>优课达</title>
</head>
<body><h1 class="title">MOUNTAIN</h1><p>The Facebook post was heartfelt. We like our little town just as it is:Little. Homey. Just us’ns.</p><div class="img-box"><div class="img-item"><imgclass="first"src="https://document.youkeda.com/P3-1-HTML-CSS/1.8/1.jpg?x-oss-process=image/resize,h_300"/><span>图片1</span></div><div class="img-item"><imgsrc="https://document.youkeda.com/P3-1-HTML-CSS/1.8/2.jpg?x-oss-process=image/resize,h_300"/><span>图片2</span></div><div class="img-item"><imgsrc="https://document.youkeda.com/P3-1-HTML-CSS/1.8/3.jpg?x-oss-process=image/resize,h_300"/><span>图片3</span></div><div class="img-item"><imgsrc="https://document.youkeda.com/P3-1-HTML-CSS/1.8/4.jpg?x-oss-process=image/resize,h_300"/><span>图片4</span></div></div><h2>LISTEN</h2><p>Listen, I can empathize. As someone who’s lived in the Denver area since1971 — right about the time John Denver’s songs were enticing folks to move</p><footer></footer>
</body>
body {margin: 0; /*去掉默认的样式*/font-family: Sans-serif;color: rgba(0, 0, 0, 0.84);font-size: 16px;padding: 30px;
}img {width: 100%;
}.img-item {position: relative;
}.img-item > span {position: absolute;right: 10px;top: 10px;font-size: 20px;color: yellow;
}
Position-sticky
本节是课外阅读,大家只需要了解这个功能,增长下见识。
我们先来看下 sticky 是什么效果,为了方便演示效果,我们在 h1 标签的上面加了一个头图。
注意 MOUNTAIN 的效果,在它滚动到顶部时,黏在了顶部。而当页面往下面滚动时,MOUNTAIN 又会恢复其在文档中的位置,这种效果就是 sticky 的效果,我们看下代码
h1 {position: sticky;color: yellowgreen;top: 50px;z-index: 1;
}
sticky 是新的 position 属性,右侧的编辑器不支持,会提醒 warning,没关系,大家忽略它。
这个布局是 position 的新特性,sticky 中文叫做粘性,因此这种布局,我们叫做粘性布局。
在很多网站都有 sticky
效果,我们来看几个实际场景,大家可以实际滚动页面,观察高亮元素的位置。
淘宝网 淘宝
知乎 知乎 - 有问题,就会有答案
苹果 MacBook Air 13 英寸和 MacBook Air 15 英寸 - Apple (中国大陆)
还有其他场景,大家自己去发掘下。。。
Float
float 是 CSS 中最常用的布局属性,使用他可以让元素靠左或者靠右排版。
它使用起来的是非常简单的。但使用后引起的行为是千变万化了,可能会引起祖先,兄弟,后代元素布局的变化,如果以后因为 float 遇到奇奇怪怪问题,不要着急,耐心解决。我们先从一个案例开始:
大家可以发现,我们在上一篇文章的基础上,加上了一个导航栏,显示优课达 logo 和用户头像。
分析下整个网页,它主要由两部分构成
- 顶部导航栏,分为左边 logo 和右边人物头像
- 主体区域是 4 个图片组成
主体布局实现
我们先用上一节的知识实现一下上下布局,我们看一下 HTML 代码
<!DOCTYPE html>
<html><head><title>优课达</title><link rel="stylesheet" type="text/css" href="./index.css" /></head><body><nav></nav><main><imgsrc="https://document.youkeda.com/P3-1-HTML-CSS/1.8/1.jpg?x-oss-process=image/resize,h_500"/><imgsrc="https://document.youkeda.com/P3-1-HTML-CSS/1.8/2.jpg?x-oss-process=image/resize,h_500"/><imgsrc="https://document.youkeda.com/P3-1-HTML-CSS/1.8/3.jpg?x-oss-process=image/resize,h_500"/><imgsrc="https://document.youkeda.com/P3-1-HTML-CSS/1.8/4.jpg?x-oss-process=image/resize,h_500"/></main></body>
</html>
在这里我们看到两个新标签 nav
main
,这两个标签都是 HTML5
标签。相比较 div,它们是有含义的,可以更明确的传达区块的含义。
nav:一般用于表示此区块是导航区域 main:一般用户表示此区块是网页的主体区域 还有其他标签,我们之后会慢慢学到
然后我们用上一节学到的知识,把头部导航 fixed
住,CSS 如下
body {/*去除默认的样式*/padding: 0;margin: 0;background-color: #f5f5f5;
}nav {position: fixed;width: 100%;height: 68px;border: 1px solid #f4f4f4;background-color: #fff;
}img {width: 100%;
}main {padding-top: 68px; /*1*/
}
注意 1 处代码,因为 nav 的 fixed 属性会导致其脱离正常的文档流,因此 main 区域会上移,导致第一张图片被遮挡显示不全,所以我们设置一个 padding-top 解决遮挡问题,最终效果如下:
已经基本实现我们想要的布局,大家可以点击右侧代码进行预览,看看实际的效果,接下来我们学习下头部细节的开发。
头部导航实现
基本头部元素
在这里,我给大家标注了具体的导航栏区域,如下所示:
我们先补全 html 代码
<nav class="nav"><imgclass="logo"src="https://style.youkeda.com/img/ykd-components/logo.png"/><imgclass="avatar"src="https://thirdqq.qlogo.cn/g?b=oidb&k=xnT9D0hzSGjSOOZkzqoutA&s=100&t=1555898643"/>
</nav>
在导航栏中,加入两张图片,一张 logo,一张头像。
补全标注中基本的宽高样式
.logo {width: 100px;height: 36px;
}.avatar {width: 36px;height: 36px;
}
我们看一下现在的效果:
已经完成了头部元素的创建,接下来我们怎么才能使 优课达 图标靠左,而 头像 靠右呢?这就是本节的重点 float 。
float —— 中文意思 浮动,当然就有往左浮动,往右浮动。这就是 float 的两个最基本的属性:
- left
- right
在这里,我们分别设置两个图标的 CSS 如下:
.logo {float: left;
}.avatar {float: right;
}
代码演示
我们在看一下效果
是不是基本已经完成了大致的效果,接下来,就交给大家了,把间距调整一下,实现完整的效果。
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><link rel="stylesheet" type="text/css" href="./index.css" /><title>QQ注册</title></head><body><nav class="nav"><a class="qq"><img src="https://document.youkeda.com/P3-1-HTML-CSS/1.9/3-qq/qq.png" /><span>QQ</span></a><ul class="right"><li class="bright"><imgsrc="https://document.youkeda.com/P3-1-HTML-CSS/1.9/3-qq/bright.png"alt="QQ靓号"/></li><li class="language"><span>简体中文</span><imgclass="arrow"src="https://document.youkeda.com/P3-1-HTML-CSS/1.9/3-qq/arrow-down.png"/></li><li class="contact">意见反馈</li></ul></nav></body>
</html>
html,
body {height: 100%;margin: 0;
}ul,
li {margin: 0;padding: 0;
}
li {list-style: none;
}h1,
h2 {margin: 0;
}p {margin: 0;padding: 0;
}/* 浏览器都有自己的默认样式,以上部分为清除浏览器默认样式 */.nav {/* 用fixed使导航固定在头部 */position: fixed;top: 0;/* 设置左右距离为0,可以使导航在长度上和页面宽度相等 */left: 0;right: 0;padding: 0 20px;
}a.qq {margin-left: 10px;margin-top: 20px;float: left;cursor: pointer;font-size: 0;
}a.qq > img {width: 40px;height: 40px;/* 指定行内元素的垂直对齐方式为居中对齐 */vertical-align: middle;
}a.qq > span {/* 指定行内元素的垂直对齐方式为居中对齐 */vertical-align: middle;font-size: 36px;line-height: 43px;margin-left: 6px;
}/* ul整体向右浮动,和 a.qq 处于同一行 */
/* ul内部的li向左浮动,三个 li 处于同一行 */
ul.right {float: right;
}ul.right > li {float: left;margin-top: 20px;margin-right: 40px;font-size: 16px;line-height: 24px;cursor: pointer;
}.bright {width: 95px;height: 34px;
}.bright > img {width: 100%;height: 100%;
}ul.right > li.language {font-size: 0;margin-top: 30px;
}ul.right > li.language span {font-size: 16px;vertical-align: middle;
}ul.right > li.language .arrow {vertical-align: middle;width: 12px;height: 8px;
}ul.right > li.contact {margin-top: 30px;
}
定位实战(一):模态框
什么是模态框
大家可能对模态框这个概念比较模糊,我们来看几个案例,注意这几个页面弹框部分
- QQ 快捷登录 https://im.qq.com/
- 微博登录 Sina Visitor System
- 知乎删除操作 知乎 - 有问题,就会有答案
当然还有很多很多,通过这些案例,我们总结下模态框的特点
- 模态框总是在浏览器的中心,浏览器随意的放大缩小,模态框还是在浏览器中心
- 模态框总有一个半透明的背景
接下来,我们试着开发下模态框
目标
我们继续在float
小节的案例上继续开发,在页面中心完成一个 优课达 模态框, 如下图所示:
大家可以先回顾下之前的代码HTML
如下:
<!DOCTYPE html>
<head><link rel="stylesheet" type="text/css" href="./index.css" />
</head>
<body><nav class="nav"><imgclass="logo"src="https://style.youkeda.com/img/ykd-components/logo.png"/><imgclass="avatar"src="https://thirdqq.qlogo.cn/g?b=oidb&k=xnT9D0hzSGjSOOZkzqoutA&s=100&t=1555898643"/></nav><main><imgsrc="https://document.youkeda.com/P3-1-HTML-CSS/1.8/1.jpg?x-oss-process=image/resize,h_500"/><imgsrc="https://document.youkeda.com/P3-1-HTML-CSS/1.8/2.jpg?x-oss-process=image/resize,h_500"/><imgsrc="https://document.youkeda.com/P3-1-HTML-CSS/1.8/3.jpg?x-oss-process=image/resize,h_500"/><imgsrc="https://document.youkeda.com/P3-1-HTML-CSS/1.8/4.jpg?x-oss-process=image/resize,h_500"/></main>
</body>
CSS 如下:
body {/*去除默认的样式*/padding: 0;margin: 0;background-color: #f5f5f5;
}nav {position: fixed;width: 100%;height: 68px;border: 1px solid #f4f4f4;background-color: #fff;
}img {width: 100%;
}main {padding-top: 68px;
}.logo {float: left;width: 100px;height: 36px;margin-left: 30px;margin-top: 16px;
}.avatar {float: right;width: 36px;height: 36px;margin-right: 30px;margin-top: 17px;border-radius: 50%;
}
第一步:完成半透明背景
整个半透明背景是撑满整个浏览器的,并且覆盖在所有的网页内容上面,因此我们需要设置一个 fixed 的容器放在 BODY 的最下面,如下面的 HTML 代码中的<div class="mask"></div>
。
<!DOCTYPE html>
<head><link rel="stylesheet" type="text/css" href="./index.css" />
</head>
<body><nav class="nav">……</nav><main>……</main><div class="mask"></div>
</body>
我们继续给这个 mask 添加 CSS 属性
.mask {position: fixed; /*1*/left: 0;right: 0;top: 0;bottom: 0;background-color: rgba(0, 0, 0, 0.7); /*2*/
}
我们来解读下 CSS 的代码
- 通过 fixed,上下左右都为 0,设置 mask 是撑满整个屏幕的
- background-color 我们使用了 rgba 颜色设置方法,最后一位可以设置颜色透明度,在这里,我们设置 黑色 0.7 透明
到这里,我们变完成了模态框背景半透明效果。如下图所示,我们可以尝试在全屏模式下改变浏览器大小,会发现蒙层会一直覆盖整个页面,完美达到我们想要的效果。
第二步:完成模态框内部
我们先来看看内部元素的标注
我们先完成内部样式,在刚才的蒙层下面,我们继续添加 dom 元素
<!DOCTYPE html>
<head><link rel="stylesheet" type="text/css" href="./index.css" />
</head>
<body><nav class="nav">……</nav><main>……</main><div class="mask"></div><div class="modal"><img src="https://style.youkeda.com/img/ykd-components/logo.png?x-oss-process=image/resize,w_800/watermark,image_d2F0ZXJtYXNrLnBuZz94LW9zcy1wcm9jZXNzPWltYWdlL3Jlc2l6ZSx3XzEwMA==,t_60,g_se,x_10,y_10" /></div>
</body>
html 代码很简单, div
里面套一个 img
标签。我们继续完善 CSS 代码,如下所示
.modal {background-color: #fff;/* 设置长宽 */width: 300px;height: 150px;/* 设置圆角20px */border-radius: 20px;
}.modal > img {display: block;width: 200px;margin: 39px auto; /*1*/
}
上面 CSS 代码基本没问题,我们需要强调一点,大家注意 标注 1 处的代码,这里的代码是为了让 优课达 Logo 上下左右居中。
常用的居中方法如下:
元素水平居中
- 如果内部是行内元素,我们可以在父容器上使用
text-align: center
。 - 如果内部是块状元素,我们可以在子容器上使用
margin: 0 auto
(如果此元素不是块状元素,需要设置display: block;
)。
元素垂直居中
之后我们会讲到如何使用 flex
实现元素的垂直居中。在这里,大家可以先使用 margin
完成垂直居中效果。
margin-top =(modal 高度 - img 高度)/ 2 //因此算下来 margin-top: 39px;
到目前为止,我们完成了模态框内部的开发,下面我们将完成模态框在整个页面中居中显示。
第三步:完成模态框布局
我们需要把整个中间区域显示在浏览器的中间,我们肯定需要把设置为 position: fixed
,如下 CSS
.modal {position: fixed; /*1*/left: 50%; /*2*/top: 50%; /*3*/background-color: #fff;/* 设置长宽 */width: 300px;height: 150px;/* 设置圆角20px */border-radius: 20px;
}.modal > img {display: block;width: 200px;margin: 39px auto;
}
通过 1、2、3 设置可以初步将 modal 居中,但是会往右下偏移部分,如下图所示
为什么呢?因为 left, top
都是 DOM 元素 左上角 顶点的偏移。
在这种情况下,我们需要使用 margin
进行修正。
.modal {position: fixed;left: 50%;top: 50%;margin-left: -150px; /*1*/margin-top: -75px; /*2*/background-color: #fff;/*设置长宽*/width: 300px;height: 150px;/*设置圆角20px*/border-radius: 20px;
}
定位实战(二):搜索框
搜索框
在很多网站的头部都有一个搜索框,我们这一小节就来学习下这种搜索框如何进行开发,我们先来看下需要完成的案例:
大家注意图片中红色部分,就是我们这小节需要搞定的部分,这部分由两个组件构建,一个搜索框,一个搜索结果列表。
由于我们还没学习 JS,因此我们不需要完成鼠标点击,键盘输入响应事件,我们默认搜索结果是直接展示的。
再次回到第二小节的代码
在第二小节,不含模态框的 HTML 代码如下(为了方便窄屏浏览器预览,我们把左侧的 LOGO 去掉)
<!DOCTYPE html>
<head><meta charset="UTF-8" /><link rel="stylesheet" type="text/css" href="./index.css" />
</head>
<body><nav class="nav"><imgclass="avatar"src="https://thirdqq.qlogo.cn/g?b=oidb&k=xnT9D0hzSGjSOOZkzqoutA&s=100&t=1555898643"/></nav><main><imgsrc="https://document.youkeda.com/P3-1-HTML-CSS/1.8/1.jpg?x-oss-process=image/resize,h_500"/><imgsrc="https://document.youkeda.com/P3-1-HTML-CSS/1.8/2.jpg?x-oss-process=image/resize,h_500"/><imgsrc="https://document.youkeda.com/P3-1-HTML-CSS/1.8/3.jpg?x-oss-process=image/resize,h_500"/><imgsrc="https://document.youkeda.com/P3-1-HTML-CSS/1.8/4.jpg?x-oss-process=image/resize,h_500"/></main>
</body>
CSS 为
body {padding: 0;margin: 0;background-color: #f5f5f5;
}nav {position: fixed;width: 100%;height: 68px;border: 1px solid #f4f4f4;background-color: #fff;
}.logo {width: 100px;height: 36px;margin-top: 16px;margin-left: 30px;float: left;
}.avatar {height: 34px;width: 34px;margin-top: 17px;border-radius: 50%;margin-right: 30px;float: right;
}
第一步:完成搜索框
我们来看看头部搜索框的标注
在效果图中, 优课达 靠左,搜索框和头像 靠右,通过第二节的学习,我们知道可以用 float
来实现。在这里,我们需要把右侧输入框和头像整体包裹起来,实现靠右效果,我们来看下 HTML 代码
……
<nav class="nav"><div class="right"><div class="search"><input placeholder="搜你想要的东西" /><imgsrc="//style.youkeda.com/img/ykd-components/search.png?x-oss-process=image/resize,w_800/watermark,image_d2F0ZXJtYXNrLnBuZz94LW9zcy1wcm9jZXNzPWltYWdlL3Jlc2l6ZSx3XzEwMA==,t_60,g_se,x_10,y_10"/></div><imgclass="avatar"src="https://thirdqq.qlogo.cn/g?b=oidb&k=xnT9D0hzSGjSOOZkzqoutA&s=100&t=1555898643"/></div>
</nav>
……
我们通过一个 <div class="right">
容器 包裹 <div class="search">
和 <img class="avatar"/>
元素,那只要我们设置 <div class="right">
靠右,那其所有的内容则会跟着靠右了。我们添加一些基础的 CSS 样式
.right {float: right;
}.search {float: left;margin-right: 20px;margin-top: 16px; /*1*/
}.search > input {width: 220px;height: 36px;font-size: 12px;box-sizing: border-box; /*2*/padding: 0 50px 0 15px;background-color: #ededed;border-radius: 18px;/*3*/border: none;outline: none;
}.search > img {/*4*/width: 34px;height: 34px;
}
我们稍微解释下上面的代码
margin-top: 16px
是计算出来的,(nav 高度 - input 高度)/ 2,和模态框中使用的计算规则一致。box-sizing
在同时设置width
height
padding
的时候一般会使用,防止宽度或高度异常,忘记的同学可以回顾 盒模型章节- 去掉默认的 input 效果
>
CSS 代表直接子元素,见 CSS 样式章节
大家可以在右侧点击预览,查看基础样式之后的效果
可以看到 搜索图标 还占用页面位置,我们希望其能往左下移动到 Input 框里面。利用之前的知识,我们可以使用 position: absolute
让其脱离文档流。
我们给.search > img
元素添加定位属性, 切勿忘记父元素设置position: relative
。
.search {position: relative;……
}
.search > img {position: absolute;right: 10px;top: 1px;width: 34px;height: 34px;
}
结果和我们想要的效果一样
第二步:完成搜索结果
我们分析下搜索结果列表的特性:
- 搜索结果宽度和头部搜索框的宽度一致。
- 搜索结果脱离文档流,是浮在所有元素上面。
我们在原来的 search
元素中加入搜索结果的内容,如下 HTML 所示:
……
<nav class="nav"><div class="right"><div class="search"><input placeholder="搜你想要的东西" /><imgsrc="//style.youkeda.com/img/ykd-components/search.png?x-oss-process=image/resize,w_800/watermark,image_d2F0ZXJtYXNrLnBuZz94LW9zcy1wcm9jZXNzPWltYWdlL3Jlc2l6ZSx3XzEwMA==,t_60,g_se,x_10,y_10"/><!-- 搜索结果页面 --><ul class="search-result"><li>优课达1号</li><li>优课达2号</li><li>优课达3号</li><li>优课达4号</li></ul></div><imgclass="avatar"src="https://thirdqq.qlogo.cn/g?b=oidb&k=xnT9D0hzSGjSOOZkzqoutA&s=100&t=1555898643"/></div>
</nav>
……
注意 HTML 元素含义, search-result
属于搜索内容,所以和输入框、搜索图标,一起包裹放在 search
元素内部。
我们继续给搜索结果添加样式
.search-result {position: absolute; /*1*/left: 0;top: 60px;padding: 0 15px;background-color: #fff;border-radius: 5px;box-shadow: 0px 1px 11px 0px rgba(0, 0, 0, 0.16); /*2*/
}.search-result > li {font-size: 12px;color: #1f2c41;height: 36px;line-height: 36px; /*3*/width: 190px;border-bottom: 1px solid #f3f3f3;
}
重点解释下 标注 1、2、3
- 因为要脱离文档流,并且相对于
search
父元素进行定位,因此使用绝对布局。 - 这个 CSS 的一个新属性——阴影,合适的阴影让元素具有层次感 MDN 阴影
- 为了使文字在每个 li 元素中垂直居中,我们使用 line-height = height 进行解决。
最后我们在加入去掉 ul 和 li 的默认样式
ul {margin: 0;padding: 0;
}li {margin: 0;padding: 0;list-style: none; /*去掉li左侧的点*/
}
背景
背景颜色
渐变色
在之前的课程中,我们已经介绍了怎么设置 背景颜色,我们先来温故一下普通颜色的几种写法:
background: red;
background: #ffffff;
background: rgba(200, 200, 200);
background: rgba(0, 0, 0, 0.5);
之前的颜色都是纯色,这一节我们来学习一些高级的技巧,怎么利用 background
这个属性设置渐变色。
我们先来看一个案例,在 优课达问吧 中,发布按钮如下图:
左边的色值: #95CA47
右边的色值为: #4DC891
我们先实现主体的按钮样式,HTML 和 CSS 如下:
<!DOCTYPE html>
<head><meta charset="utf-8" /><link rel="stylesheet" type="text/css" href="./index.css" /><title>优课达</title>
</head>
<body><button class="publish">我要提问</button>
</body>
.publish {width: 100%;height: 50px;line-height: 50px;color: #fff;font-size: 18px;border-radius: 4px;font-weight: 500;box-shadow: 0 2px 6px 0 rgba(104, 200, 116, 0.3); /*1*/
}
标注 1 处的代码是添加阴影效果,大家在下一个课程中很快就能学到,先不用特别纠结
演示一下:
代码演示
现在的效果如图:
在图中,我们看到已经有了 边框,阴影,圆角 效果,文字因为是白色所以看不出来,下面我们需要给按钮加入渐变背景色。
我们得学习 background
的一个新的值 —— linear-gradient
根据上图,我们设置好 渐变类型、渐变方向、开始颜色、结束颜色 即可实现简单的渐变效果。
演示一下:
代码演示
效果很完美,我们再仔细介绍下每个值的含义。
渐变方向
渐变方向使用的语义化英文实现,具体有如下值
- to right / to left 向右/向左渐变
- to top / to bottom 向上/向下渐变
- to right bottom / to right top 向右下/向右上渐变
- to left bottom / to left top 向左下/向左上渐变
- xxxdeg xxx 范围(0 到 360) 更精确的渐变方向
演示一下,如何把背景渐变色改为从右上到左下
代码演示
渐变位置
渐变不一定是从开始到结束,我们可以设置各种中间状态。我们来看一个更复杂的例子,在上面的例子下升级,我们不需要一开始就进行渐变,而是在 30% ~ 70% 之间进行渐变,如图所示:
我们可以在每个色值后面跟一个值 百分比,PX,来约定变色起止位置。
上面讲的是最通用,最常见的渐变效果。除此之外,还支持 多颜色渐变、弧形渐变,完整文档见 MDN https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Using_CSS_gradients,有兴趣的同学可以仔细学习下。
背景图片
案例
CSS 除了设置背景颜色,还可以设置背景图片,背景图片在网页中使用十分常见。我们来看一下网上一些背景图片使用案例。
- 优课达下载页面【学得比别人好一点-优课达】黄色标注区域
- 微博的个人主页 【Sina Visitor System】头部区域 和 整个页面背景
- 网易云音乐【网易云音乐】客户端下载区域
基础使用
我们现在来学习背景图片的使用方法,先看看我们的目标,实现如下简单的效果
一个容器中,有一串 HELLO WORLD 文字, 同时有一张居中的 优课达 LOGO 的背景图。
我们继续来看下 HTML 代码
<!DOCTYPE html>
<head><meta charset="utf-8" /><link rel="stylesheet" type="text/css" href="./index.css" /><title>优课达</title>
</head>
<body><div class="box">HELLO WORLD</div>
</body>
原始的 CSS 代码
.box {width: 100%;height: 250px;border: 1px solid #e8e8e8;font-size: 30px;font-weight: bold;color: yellowgreen;
}
下面我们需要给 box
元素设置背景图片 https://style.youkeda.com/img/ykd-components/logo.png
我们首先学习怎么给一个元素设置背景图片,代码很简单如下所示:
一个 background-image
标签,加一个 url
包裹的远程或者本地图片地址。
注意 url 里面的图片地址不需要用引号包裹
效果大大出乎我们意料,为什么呢?我们来看看需要解决的问题。
1. 背景图片出现了重复
当背景图片长宽任意一项小于容器的长宽,默认 CSS 会让图片重复,直到铺满整个容器位置。
我们可以使用 background-repeat: no-repeat;
禁止图片的重复。
现在的效果如下:
我们来完整的学习下background-repeat
的值。
值 | 描述 |
---|---|
repeat | 这是默认值。如果背景图片比容器小,将在垂直和水平方向进行重复 |
repeat-x | 背景图片只在水平方向重复 |
repeat-y | 背景图片只在垂直方向重复 |
no-repeat | 背景图片将只显示一次,不重复 |
演示一下使用no-repeat、repeat-x、repeat-y的情况
2.背景图片不居中
默认情况下,背景图片是从容器的左上角开始布局,为了使容器垂直水平居中,我们可以使用 background-position: center;
解决, 到现在为止的完整代码如下:
.box {width: 350px;height: 250px;border: 1px solid #e8e8e8;font-size: 30px;font-weight: bold;color: yellowgreen;background-image: url(https://style.youkeda.com/img/ykd-components/logo.png);background-repeat: no-repeat;background-position: center;
}
我们来完整的学习下background-position
的值。
值 | 描述 |
---|---|
| 左侧两个元素为一组一起出现,分别代表垂直和水平布局 比如: background-position: top left; 效果等于 background-position-x: left; background-position-y: top; 如果只写一个关键词,那么另一个关键词默认是center |
x% y% | 第一个值是水平位置,第二个值是垂直位置。 左上角是 0% 0%。右下角是 100% 100%。如果只写一个值,另一个值将是 50%。 |
xpx ypx | 第一个值是水平位置,第二个值是垂直位置。 左上角是 0 0,单位是像素 (0px 0px) 或任何其他的 CSS 单位。如果只写一个值,另一个值将是50% |
演示一下background-position
的用法:
高级特性
背景图片撑满整个容器
在上面的基础上,我们希望背景图片放大撑满整个容器,如下图所示:
我们需要认识一个新的属性 background-size
,用这个属性可以设置背景图片的大小,我们直接来看看这个属性有哪些值。
值 | 描述 |
---|---|
cover | 把背景图像扩展至足够大,以使背景图像完全覆盖背景区域。 背景图像的某些部分也许无法显示在背景定位区域中。 |
contain | 把图像图像扩展至最大尺寸,以使其宽度和高度完全适应内容区域。 |
xpx ypx | 手动设置宽度和高度 |
x% y% | 手动设置宽度和高度相对于容器的百分比 |
通过描述,我们想想要实现上图效果,我们应该选用那个值?
如果还是不知道,不如我们直接用代码试一下。前端开发的好处,可以直接在线测试。
演示设置为contain
和cover
我们分别把 position-size
设置为 contain cover
(左图是 contain, 右图是 cover)。
效果很明显,左边是我们想要的效果。回过头来,我们再仔细分析下这两个值的区别,其实也比较容易理解:
cover 就是满足图片长宽中较小的一方撑满屏幕。 contain 就是满足图片长宽中较大的一方撑满屏幕。
background 合并写法
我们看下现在完整的 CSS 样式
.box {width: 350px;height: 250px;border: 1px solid #e8e8e8;font-size: 30px;font-weight: bold;color: yellowgreen;background-image: url(https://style.youkeda.com/img/ykd-components/logo.png);background-repeat: no-repeat;background-size: contain;background-position: center;
}
下面 4 条都用于背景图片布局,会不会觉得很繁琐?在 CSS 中对于背景有一种非常简单书写的方式
在
background
后连续跟随多个背景属性值,如果没有此属性,则置空。在上面例子中,我们会使用background-image
,background-repeat
,background-position
,background-size
四个属性,合并之后的结果是:
.box {width: 350px;height: 250px;border: 1px solid #e8e8e8;font-size: 30px;font-weight: bold;color: yellowgreen;background: url(https://style.youkeda.com/img/ykd-components/logo.png)no-repeat center / contain;
}
其他属性
position-attachment: background-attachment - CSS:层叠样式表 | MDN
position-clip background-clip - CSS:层叠样式表 | MDN
这两个属性大家可以简单阅读下,不是重点。