写在开头:这是一篇有关于HTTP和CSS的基础入门教程。你也可以将他当作一本字典,因为我将所有可能用到的语法结构全部设置了标题,你只需要点击标题即可跳转过去。同时,我在最后放置了两个CSS实战,以供读者练习使用。这是一篇十分值得收藏的web前端基础文章,希望对看到的读者有所帮助。
内联标签不会为自己的被人占据新的一行,将会和前面的文字显示在同一行,如img标签,a标签,span标签,strong标签等。
块标签会为自己的内容占据新的一行,而与前面的空位将会用占位符代替,如p标签,标题标签,div标签等。
HTML提供了六个标签来表示文章的标题,分别是~
,字数越大级别越低,对应的子就越小。
注意,标题之间不可越级,这样会导致文章失去清晰的结构。
段落标签
是HTML里最常用的一个标签,是一个块状标签,代表文章中的一个段落(paragraph)。
此标签说明它包含的内容有很强的重要性,需要引起注意。浏览器会粗体显示内容。
<p>一句话中的<strong>重点内容strong>p>
显示效果:
一句话中的重点内容
小知识:
标签页能使内容变粗,但没有语义,只是单纯的表示样式加粗。
下面的段落中,我们将岛名“Maldives”用包裹起来。
这是一个内联标签(即不会产生换行),通常表示一个行内短语,使用
可以使网页更有条理。
标签可以使文本变粗体,
则不是这样的,如果没有加样式文件,
在样式上与普通文本不会有区别。
写法如下:
<img src="xxx" alt="" />
src
中写入图片的 相对路径 或 绝对路径 就可以啦。
图片标签还有个 alt 属性,这个属性定义了描述图像的替换文本。如果图像的 URL 是错误的,该图像不在 支持的格式 列表中,或者如果图像还没有被下载,用户将看到这里的替换文本。
除了静态的 jpg、jpeg、png 之类的图片,我们还可以用 img 标签向网页中插入 gif 动图哦:
网页显示效果:
连接标签为内联标签,用户点击后就会跳到对应网址。
<a herf="https://www.csdn.net/?spm=1001.2101.3001.4476">CSDN——专业开发者社区a>
效果如下:
CSDN——专业开发者社区
a标签还可以放置段落,图像,多媒体等等。
下面讲解一下连接标签的重要属性。
HTML提供了无序标签
和有序标签
,列表的每一项都用标签表示。
显示效果:
我们尝试完成如下表单:
可以看到,在这个注册表单里都是输入框、按钮等表单元素,对于这些表单控件,我们需要用一个块状元素把它们包起来,属于同一个表单的表单控件要包含在同一个块状元素
里。
这个标签有两个属性需要了解:
action
:一个处理此表单信息的程序所在的 URL,所述表格信息将在表单提交时被发送到定义的地址;
method
:它的值可以是 GET 或 POST,用来规定如何发送表单信息。
<form action="">
form>
<form action="">
<input type="text" />
form>
效果如下:
下面介绍他的几种属性。
<form action="">
<input type="text" placeholder="昵称" />
form>
效果如下:
为了区别于其他input,我们要给昵称输入框加上属性name,在提交表单时就不会和其他数据搞混了:
<input type="text" placeholder="昵称" name="nick" />
如果希望在输入框中预填写用户的昵称,可以用标签属性value:
<input type="text" placeholder="昵称" name="nick" value="小明" />
效果如下:
在一些特殊情况中,我们会给用户分配昵称,这个时候并不希望用户可以自行修改,我们可以这么做:
<input type="text" placeholder="昵称" name="nick" value="小明" readonly />
如此便可以把输入框变成 只读 输入框,这样用户就不能自己修改预填写的内容啦。
除了用”readonly”这个属性,我们还可以用”disabled”,这个属性也能使用户无法更改输入框中的内容。
<input type="text" placeholder="昵称" name="nick" value="小明" disabled />
但是这两个是有一定区别的:
属性 | disabled | readonly |
---|---|---|
对象 | 所有表单元素 | input 和 textarea |
作用 | 使文本框不能输入,当表单以 POST 或 GET 的方式提交时,使用了 disabled 的元素的值不会被传递出去 | 仅使文本框不能输入 |
外观 * | 使文本框变灰 | 外观没有变化 |
外观 * :在不同浏览器中输入框的外观可能会有区别,因此“readonly”和“disabled” 这两种输入框在外观上的差别可能与上表所述有所不同。
图中的个性签名框即为多行输入框。当多行文本框中输入的内容超过一行以后,它就会自动换行。我们使用textarea
标签来写多行输入文本框。
<textarea
name="sign"
rows="5"
cols="30"
placeholder="请输入个性签名"
>textarea>
效果如下:
rows表示行数,clos表示可视宽度。
密码输入框的内容将会以黑色圆点显示,我们只需要把标签属性中的type="text"
改为type="password"
就可以了:
<input type="password" name="password" placeholder="密码" />
效果如下:
在这里我们只考虑了男女两种性别,并默认用户只有一种性别。 就像做单选题一样,用户只能选择男性或者女性,因此我们使用单选框实现:
<input type="radio" name="gender" value="male" />
<input type="radio" name="gender" value="female" />
属于同一道单选题的每个单选按钮,应该拥有相同的name属性。
这里面value的值是我们要提交上去的值,想要显示出来数据只需要将其加在input标签中就行了。
<input type="radio" name="gender" value="male" />男
<input type="radio" name="gender" value="female" />女
效果如下:
男 女 此时我们只有点击小圆点时,才能选中性别,这样点击的范围有点小,如果点击文字也能选中对应的性别就更好了。 为了达到这个目的,我们常常会把单选框和标签``配合使用:<label> <input type="radio" name="gender" value="male" />男 label>
<label> <input type="radio" name="gender" value="female" />女 label>
另一种写法:
<input id="male" type="radio" name="gender" value="male" />
<label for="male">男label>
<input id="female" type="radio" name="gender" value="female" />
<label for="female">女label>
我们给单选框
加了一个属性
id="male"
,给标签也加了一个属性
for="male"
。这样,两者之间就产生了一一对应的关系。 显示效果: 男
女 点击播放上述代码:代码演示
用户可能对很多领域感兴趣,所以在兴趣的选择上我们要用复选框。
复选框的使用就像一道多选题,用户可以选择多个选项。除此之外,复选框和单选框很像,它的类型是checkbox
:
<input type="checkbox" />
效果如下:
你会在页面上看到一个小方框,点击它,可以看到它被选中了,再次点击,选中会被取消。
为了写好我们的兴趣复选框,我们需要在上面这个简单的复选框的基础上,给它们加上文字(配合标签)、name 属性和 value 值:
<label> <input type="checkbox" name="interest" value="coding" />编程 label>
<label> <input type="checkbox" name="interest" value="other" />其他 label>
* 属于同一道“多选题”的每个复选框元素,应该拥有 相同 的name
属性值。
需要注意的是:复选框是只有 2 种状态的表单控件:已选中或未选中。在只有一个复选框的情况下,它允许用户对某事说“是”或“否”,比如同意或不同意某个条款。而只有一个单选框的情况下,用户一旦选择了这个单选框,就不能再取消选择了,除非他刷新了网页。
对于职业的选择我们会提供几个固定的选择,而且选项较多,所以我们不采用复选框,而是使用和
,选项菜单。
每个选项用标签表示,一组选项用
包裹:
<select name="career">
<option value="default">请选择职业option>
<option value="staff">公司职员option>
<option value="freelancer">自由职业者option>
<option value="student">学生option>
<option value="other">其他option>
select>
效果如下:
请选择职业 公司职员 自由职业者 学生 其他 需要注意的是,这是一个单选菜单,如果用户选择了“学生”,那么提交的数据将会是:career:"student"
而不是“学生”,是标签的标签属性
value
的值。所以每个 option 的 value 值要互不相同。
如果我们想要的是一个多选菜单,该怎么办呢?
很简单,给标签添加 multiple 属性,就可以通过按住 Ctrl(或 ⌘)并单击选项来选中多个选项啦:
<select name="career" multiple>
<option value="default">请选择职业option>
<option value="staff">公司职员option>
<option value="freelancer">自由职业者option>
<option value="student">学生option>
<option value="other">其他option>
select>
效果如下:
请选择职业 公司职员 自由职业者 学生 其他 ### 7.按钮语法如下:
<button type="submit">注册button>
这个按钮放在 form 中会在点击的时候自动提交表单数据,但是在 button 提交表单数据这一点上是有浏览器兼容性问题的,一般还是需要加上 type=“submit”来确保数据的提交。
到这里,我们便完成了一个简单的注册表。
完整的注册表单:
<form action="">
<input type="text" name="name" placeholder="请输入昵称" />
<textarea
name="sign"
rows="5"
cols="30"
placeholder="请输入个性签名"
>textarea>
<input name="password" type="password" placeholder="请输入密码" />
<label> <input type="radio" name="gender" value="male" />男 label>
<label> <input type="radio" name="gender" value="female" />女 label>
<label> <input type="checkbox" name="interest" value="coding" />编程 label>
<label> <input type="checkbox" name="interest" value="other" />其他 label>
<select name="career">
<option value="default">请选择职业option>
<option value="staff">公司职员option>
<option value="freelancer">自由职业者option>
<option value="student">学生option>
<option value="other">其他option>
select>
<button type="submit">注册button>
form>
设置格式为: font-size:36px;
设置字体的大小为36px。
设置格式为:font-size:100;
设置字体的粗细为100。其值可以是100,200一直到900,或者采用英文代替,normal(正常粗细),lighter(细),bold(粗),bolder(更粗)
设置格式:color:#ff9a9e;
颜色的值的设置方式分为四种:
color:black;
color:blue;
color:red;
十六进制颜色由#开头,后面跟三个数字,每个数字的范围为 00 ~ FF,每个数字代表一种颜色,最终的颜色由这三种颜色调和而成; 这个颜色一般由设计师给我们,或者可以用吸色工具去获取。
例如:
color:#dae8fc
rgb 形式和十六进制的原理相同,其最终的颜色由三种颜色的深浅决定,即 r(red),g(green),b(blue),每种颜色的范围为 0 ~ 255,代表这每种颜色的深浅,值越大越深;同样的,我们不必去深入研究它,设计师给我们什么,我们就用什么。
例如:
color:rgb(253,271,106)
rgba 形式相比 rgb 形式,多了一个 a,这里的 a 代表的是 Alpha(透明度),a 的值在 0 ~ 1 之间,为了简化书写,也可以直接省略 0,写成.4,等同于 0.4。
例如:
color:rgb(253,271,106,0.3)
rgba
形式,在CSS定位中我们会遇到。line-height
作用:
- 改变段落中航宇行之间的距离;
- 使文字上下居中(通过设置行高使文字填满页面)。
letter-spacing
英文是字母之间的间距。
font-family: 字体;
设置的字体能否被使用取决于使用者的电脑上有没有安装这个字体。有时候我们会设置一些常用字体,如:
font-family: 'Goudy Bookletter 1911', sans-serif, 'Gill Sans Extrabold';
这段代码怎么去理解呢?页面加载以后会先去找代码中设置的字体,这里有三个备选的字体,浏览器会按顺序加载:首先看看"Goudy Bookletter 1911"字体在电脑上是否安装;如果没有安装,就去看第二个字体;如果还没有,就去看第三个字体是否已经安装;如果都没有安装,那么就只能用默认的微软字体,这个字体是所有电脑默认会安装的。
前面所使用的就是行内样式,即使是长得相同的段落我们仍需为其编写一样的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内的某个地方,这就是内部样式。
我们用一张图来介绍内部样式的抽离过程:
抽离步骤:
当代码量增多,如此写法就会出现头重脚轻的现象,不利于阅读和复查代码,因此我们要实现代码分离,让HTML负责结构,CSS代码负责样式。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HqZslCE9-1682580221449)(https://qgt-document.oss-cn-beijing.aliyuncs.com/P3-1-HTML-CSS/1.6/%E5%A4%96%E9%83%A8%E6%A0%B7%E5%BC%8F%E5%BC%95%E5%85%A5%E6%AD%A5%E9%AA%A4.png?x-oss-process=image/resize,w_800/watermark,image_d2F0ZXJtYXNrLnBuZz94LW9zcy1wcm9jZXNzPWltYWdlL3Jlc2l6ZSx3XzEwMA==,t_60,g_se,x_10,y_10)]
方法步骤:
index.css
文件;html
代码头部中的style
标签内的样式全部拷贝过来;CSS
样式粘贴进 index.css
文件中;link
标签引入CSS
文件<link rel="stylesheet" type="text/css" href="index.css" />
属性含义:
rel
属性 rel
属性规定了当前文档与被链接文档之间的关系,但是rel
属性的stylesheet
值被所有浏览器支持,也就是说你只要记住一个值即可。-
stylesheet
的意思就是文档的外部样式表。type
属性 type
属性规定了被链接文档的 MIME(多用途互联网邮件扩展类型)类型,type
属性对应的最常见的值就是text/css
,该类型描述样式表。
href
属性 href
属性后跟的是要引入的链接地址。
在CSS中,我们通过标签选择器给所有同类型的标签设置统一的样式。如下p标签:
前面介绍的引用方式便是用了标签选择器。
再写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;
}
定义
<p class="article">
class是定义类的关键字,article是类名,类名可以任意,但是要符合规范
p>
使用
.article {
color: red;
font-size: 14px;
}
类选择器的作用就是在普通中寻找特别的元素。将其定义到对应的标签内后,就可以在style标签或者CSS文件中编写类的内容,以达到特殊的引用。
一个标签还可以使用多个类名,类名之间要用空格隔开,比如:
<p class="common color font-size">
common设置通用样式,color设置特殊颜色,font-size设置特殊字体大小
p>
当我们同时引用两个类,如:class="common current"
,是类名的先后顺序影响最终样式呢?还是标签中的类名先后顺序影响结果呢?
将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
<p id="p-item">这是一段文字p>
使用 id 选择器
#p-item {
font-size: 24px;
font-weight: 400;
}
可以看出,除了定义和使用的规范不同之外,基本没有什么变化,不同的地方是:
<a href="#" id="link">点击进入详情a>
<a href="#" id="link">点击进入主页a>
id 就像身份证号码一样,全国只能有一个,同样,id 选择器亦是如此,这里的 link 重复了。
<a href="#" id="link linkto">点击进入详情页a>
常用的高级选择器有四种:
语法如下:
`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);
}
从上面这个例子可以看出一种编程思想,就是抽离。
什么是后代?比如说,某某某是孔子的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="">曾曾孙1a>
span>
p>
<p class="p-two">孙
<span>曾孙
<a href="">曾曾孙2a>
span>
p>
li>
ul>
此时我们用上面的四种方法都会选到两个a标签,但是我们的目的是选中“曾曾孙1”,所以我们要在最开始出现重复标签的那一级来做区分,给这一级分别加上类名,或者你可以只给你需要的那个标签添加类名即可,此时我们要选中“曾曾孙1”可以这样做:
/* 方法一 */
ul li .p-one span a{}
/* 方法二 */
.p-one span a{}
书写规则为:
a.special{}
"#" class="special">超链接
"#">超链接
"#">超链接
"#">超链接
它的意思是,在所有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;
}
后代选择器突出的是“后代”,而子选择器突出的是“子”。代码如下:
<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;
}
得到的结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CdHvde7r-1682580221450)(C:\Users\85437\AppData\Roaming\Typora\typora-user-images\CSS\23420907.png)]
使用子选择器:
span {
color: black;
}
p>span {
color: orangered;
}
得到的结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-67hK8H5r-1682580221451)(C:\Users\85437\AppData\Roaming\Typora\typora-user-images\CSS\image-20230423180153810.png)]
如果要给不同的标签,或者不同类名的标签添加相同的样式,此时就要用到并集选择器,并集选择器的规则是在标签名或者类名后面用逗号(,
)隔开,例如:
.box,p,h3,.phone{}
并集选择器的作用是“和”,上面这段代码的意思就是给类名为box
、phone
标签名为p
、h3
的标签添加相同的属性。
单个选择器的优先级为:id选择器>类选择器>标签选择器。我们举例说明一下:
代码如下:
<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
。
盒模型就是一个div
标签,如h,p,ul,li标签都是div
标签,他们都是div标签改造的,拥有一个共同的特性就是都可以独占一行。可以总结为,div
就是一个干净透彻的矩形:
由四部分组成:
content
padding
border
margin
顺序由内到外。由于div
是一个矩形,因此内边距,边框,外边距又可以分为上下左右四条边,每个边都可以设置单独的样式。div
的四个组成部分,就是所谓的盒模型。
要画一个矩形,首先需要设置他的宽和高,对应的两个属性为width,height。
比如我们要画一个宽为200px,高为100px的矩形:
<div class="box">div>
.box {
width: 200px;
height: 100px;
}
div的宽度是继承他的父标签的,如果我们没有设置div的属性,那他便没有高度,宽度为父标签的宽度。
要给矩形添加背景颜色,需要一个新的CSS属性background-color
–背景颜色,这个属性的值跟我们设置字体颜色时候学的一样,有十六进制,rgb
,rgba
,英文单词形式的颜色,下面我们给刚才设置的矩形添加一下背景颜色。
核心代码如下:
<div class="box">div>
.box {
width: 200px;
height: 100px;
background-color: purple;
}
我们填充的颜色区域就是盒模型中的content
。
设置元素块的宽和高,除了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
的宽是有的,默认和浏览器页面宽度一样。
在如下图片中:
绿色边框框起来的文字跟其上下左右都有一定的距离,这就是我们所说的内边距。
我们来仿写斜阳一个案例:
<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默认是给四周添加相同的内边距,如果我们需要四周不同的情况,就需要单独设置内边距,没设置的内边距默认为0。
.box {
padding: 20px;
}
这段代码等价于:
.box {
padding-top: 20px; /*上内边距*/
padding-right: 20px; /*右内边距*/
padding-bottom: 20px; /*下内边距*/
padding-left: 20px; /*左内边距*/
}
padding
分开写的形式主要是为了更好的理解如何简写padding
,现在我们知道了padding
分为top
、right
、bottom
、left
,在简写的时候就会从这四个方向上去设置。
之前我们知道这种形式的简写padding: 20px
,意思是给content
的上、右、下、左四个方向上都设置了相同的padding
,它最初的形式是这样
div{
padding:20px 20px 20px 20px;
}
这四个值分别代表,上、右、下、左,如果四个值都一样,就可以写成padding:20px;
,如果不一样,可以分为一下几种情况:
例如:
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;
}
永远记住,第一个值是上,第二个值是右,第三个值如果没有,就和第一个值保持一致,第四个值如果没有就和第二个值保持一致。
比如:
div{
padding-top: 20px;
padding-bottom: 20px;
padding-left: 10px;
padding-right: 30px;
}
使用简写形式要这样写:
div{
padding: 20px 30px 20px 10px;
}
比如:
div{
padding-top: 30px;
padding-bottom: 20px;
padding-left: 10px;
padding-right: 10px;
}
使用简写形式要这样写:
div{
padding: 30px 10px 20px;
}
可以这样来理解,第一个值是上30px
,第二个值是右10px
,第三个值是下20px
,第四个值是左,但是没有,所以要跟右一致。
总结下来就是上、右、下、左按照顺序去填写,没有的值就跟对立面的值一样,下对上,左对右。
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
。
边框就是包裹在padding外的一层线,我们要设置的就是这条线的粗细、颜色。
给矩形设置边框线
设置边框线的语法如下:
.box {
/* 设置矩形大小 */
width: 200px;
height: 30px;
/* 设置边框线 */
border-width: 2px;
border-color: grey;
border-style: solid;
}
border-style:
边框的类型,solid为实线,dashed为虚线。
边框的简写
.box {
border: 2px solid blue;
}
三个值要用空格隔开,顺序可以变化。
.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;
}
.box {
border: none;
}
.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;
}
实现效果如下:
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 轴上移动,就会有阴影的效果。
所谓外边距就是矩形和矩形的距离。如下图所示:
两个盒子之间的的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时,一般推荐在其中一个盒子的下方设置。
推荐
.box1{
margin-bottom: 50px;
}
不推荐
.box2{
margin-top: 50px;
}
/*----------------------------*/
.box1{
margin-bottom: 20px;
}
.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;
}
首先我们需要了解块元素的性质:
独占一行。
块标签会将一行内剩下的部分用占位符填充,所以其他标签元素不能跟他在同一行显示。
可以设置宽高。
可以尝试给一个span标签设置宽高。可以发现即使设置了也不会生效,当我们将span标签换成div标签后,我们设置的宽高便生效了。
标签是行内元素还是块元素,其根本原因就是标签自带的默认元素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;
}
得到的效果如下:
none
就是无的意思,也就是说,当给标签设置了这个属性值,标签就会消失,在网页布局中最常用的就是用none
、block
来控制元素的显示和隐藏。
可以看一下下面这个例子:
<div>盒子1div>
<div class="box2">盒子2div>
<div>盒子3div>
div {
width: 300px;
height: 100px;
/* 使用text-align属性让文字左右居中 */
text-align: center;
margin-bottom: 10px;
background-color: #d5e8d4;
/* 使用行高让文字上下居中 */
line-height: 100px;
}
.box2 {
display: none;
}
得到的效果如下:
我们已经使用了inline,加下来探讨一下它的性质:
<a href="#">超链接a>
a {
background-color: #fff2cc;
padding: 20px;
}
<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的效果与块元素一样。
从名字可以看出,inline-block既具有block的性质,还具有inline的性质,可以理解为inline-block就是一个可以在同一行显示的块元素。
inline-block
要比block
在应用中更为广泛,因为我们更多的时候需要的是一个能和其他元素共存的盒子,相比而言,block
显得较为孤僻。
关于inline-block
这个值的作用,大家可以根据block
的性质去理解,这里主要给大家介绍一下空白折叠的现象。
按照常理,我们将div
的display
属性从block
切换成inline-block
之后,我们希望得到的效果是这样的:
可以看到,两个盒子中间多了一点空白,但是我们并没有设置margin
,这就是传说中的空白折叠现象,其原因就是因为两个 div 之间多了一个回车,在html
中,回车被当作是一个文字,所以这里的空白就是文字的空白,相当于在两个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;
}
效果如下:
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;
}
从第二点我们了解到,回车可以当作是一个文字,那么如果将文字大小设置为 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时CSS的一个非常关键的属性,这个属性在CSS中用于定位DOM元素,修改DOM元素的布局。
position-static属性会自动添加。我们在index.css
中并没有设置任何的position
属性,但浏览器会自动给所有的 DOM 元素,添加position: static
,如下图所示:
因此 static 遵循默认的文档流布局,top、left、right、bottom(后面会讲到这几个属性)属性都无效。
position除了static这几个属性外,还有四个常用属性,分别为:
先看一下如下代码:
DOCTYPE html>
<head>
<link rel="stylesheet" type="text/css" href="./index.css" />
<title>优课达title>
head>
<body>
<h1 class="title">MOUNTAINh1>
<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">
<img
alt=""
class="first"
src="https://document.youkeda.com/P3-1-HTML-CSS/1.8/1.jpg?x-oss-process=image/resize,h_300"
/>
<img
alt=""
src="https://document.youkeda.com/P3-1-HTML-CSS/1.8/2.jpg?x-oss-process=image/resize,h_300"
/>
<img
alt=""
src="https://document.youkeda.com/P3-1-HTML-CSS/1.8/3.jpg?x-oss-process=image/resize,h_300"
/>
<img
alt=""
src="https://document.youkeda.com/P3-1-HTML-CSS/1.8/4.jpg?x-oss-process=image/resize,h_300"
/>
div>
<h2>LISTENh2>
<p>
Listen, I can empathize. As someone who’s lived in the Denver area since
1971 — right about the time John Denver’s songs were enticing folks to move
p>
<footer>footer>
body>
效果如下:
我们想要让上图图一张图片向右下角分别移动50px,效果如下图,应该如何实现呢?
先尝试使用margin使图片进行偏移:
.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: relative
改为 position: absolute
结果会怎么样呢?
CSS 代码如下:
.first {
position: absolute;
left: 50px;
top: 50px;
}
结果如下:
在图中 和 relative
相比较:
在 MDN 中,官方描述为
absolute 被称为 绝对定位 绝对定位不为元素预留空间,通过指定元素相对于最近的非 static 定位祖先元素的偏移,来确定元素位置
我们重点理解下,什么叫做 相对于最近的非 static 定位祖先元素的偏移 ?
在这里,我们提取三个关键词 最近 和 非 static 定位 和 祖先元素。连贯起来分析下在上面的网页中,浏览器是怎么布局 absolute 元素的。
,我们发现它是 absolute 布局,我们发现此元素并未配置 position 属性,其遵循默认布局 position = static,并不符合非 static要求。
- 因此继续找
的父亲节点,找到
已经没有父亲节点了,所以按照
的位置为标准进行偏移
顺着上面的思路,便能捋清楚布局逻辑。
接下来,如果我们把 元素设置 position: relative 会出现什么样的情况呢?
……
.img-box {
position: relative;
}
.first {
position: absolute;
left: 50px;
top: 50px;
}
……
我们会发现第一张图片相对于 进行了偏移,而不是之前的body
元素。
总结下:absolute(绝对定位) 和 relation(相对定位)的区别,relation 是相对自己进行 top、left、right、bottom 进行偏移,而 absolute 是寻找最近的 非 static 的祖先节点进行偏移。
4.position - fixed(固定定位)
很多场景下,文章的标题会固定到浏览器顶部,不会随着页面滚动而消失,比如下面视频的效果:
MOUNTAIN不会随着页面滚动,而会一直停留在顶部50px的地方。这就是fixed的功能——固定。
我们给h1添加属性:
h1 {
position: fixed;
/*去掉H1默认的样式*/
padding: 0;
margin: 0;
left: 30px;
top: 50px;
color: yellowgreen; /*为了方便观看,我们修改MOUNTAIN的颜色*/
}
此时无论怎么滚动,MOUNTAIN 永远在窗口的左上角。
fixed 为 固定定位
固定定位和绝对定位类似,但元素的包含块为屏幕视口(viewport)
固定定位不为元素预留空间,而是通过指定元素相对于屏幕视口(viewport)的位置来指定元素位置。元素的位置在屏幕滚动时不会改变。
但继续滚动,我们会发现 MOUNTAIN 被图片区域遮挡了,这是为什么呢?如下图:
这就需要 z-index
来解决了。
z-index
在刚才 absolute
, fixed
演示中,我们知道 HTML 页面是由多个图层构成的,那浏览器怎么决定不同的图层优先级呢(到底是谁覆盖谁、谁在谁的上面,谁离观察者最近)?这就是 z-index
决定。
- 默认非 static 元素的 z-index 都为 0
- z-index 越大,则越在最上面,离观察者越近
- 同样的 z-index, 在 HTML 中的元素越靠后,则越在最上面,离观察者越近
因此,分析下上面的场景中 MOUNTAIN
元素 和
元素 都是非 static 元素,z-index
都为 0。 而因为
在文档流前部,因此会被后者遮挡,所以 MOUNTAIN 移动到图片区域时,被图片遮挡了,那我们如何解决?
很简单,我们修改
的 z-index
大于 0 即可!大家可以修改下代码,观察下效果,如下所示:
h1 {
position: fixed;
left: 30px;
top: 30px;
z-index: 1;
color: yellowgreen;
}
拓展阅读:position-sticky(粘性布局)
下面这个视频演示了position-sticky的作用:
代码如下:
h1 {
position: sticky;
color: yellowgreen;
top: 50px;
z-index: 1;
}
5.Float
float有两个最基本的属性:
- left——左浮动
- right——右浮动
它可以实现元素靠左或者靠右排版。
.logo {
float: left;
}
.avatar {
float: right;
}
定位实战:模态框
QQ登录模态框
微博登录模态框
知乎删除操作模态框
通过这些案例,我们总结下模态框的特点:
1.模态框总是在浏览器的中心,浏览器随意的放大缩小,模态框还是在浏览器中心。
2.模态框总有一个半透明的背景。
接下来我们尝试开发一个模态框。
目标
在Float的实例基础上继续开发,完成一个优课达模态框,如下图所示:
HTML源码如下:
DOCTYPE html>
<head>
<link rel="stylesheet" type="text/css" href="./index.css" />
head>
<body>
<nav class="nav">
<img
class="logo"
src="https://style.youkeda.com/img/ykd-components/logo.png"
/>
<img
class="avatar"
src="https://thirdqq.qlogo.cn/g?b=oidb&k=xnT9D0hzSGjSOOZkzqoutA&s=100&t=1555898643"
/>
nav>
<main>
<img
src="https://document.youkeda.com/P3-1-HTML-CSS/1.8/1.jpg?x-oss-process=image/resize,h_500"
/>
<img
src="https://document.youkeda.com/P3-1-HTML-CSS/1.8/2.jpg?x-oss-process=image/resize,h_500"
/>
<img
src="https://document.youkeda.com/P3-1-HTML-CSS/1.8/3.jpg?x-oss-process=image/resize,h_500"
/>
<img
src="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 代码中的
。
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;
}
通过 标注 1、2 修正 自身宽度和高度一半距离。
OK,这就达到了我们希望的模态框效果。
定位实战:搜索框
案例如下:
红色框部分有两个组件构成:一个是搜索框,一个属搜索结果列表。
第一步:完成搜索框
我们来看看头部搜索框的标注
在效果图中, 优课达 靠左,搜索框和头像 靠右,通过第二节的学习,我们知道可以用 float
来实现。在这里,我们需要把右侧输入框和头像整体包裹起来,实现靠右效果,我们来看下 HTML 代码:
……
<nav class="nav">
<div class="right">
<div class="search">
<input placeholder="搜你想要的东西" />
<img
src="//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>
<img
class="avatar"
src="https://thirdqq.qlogo.cn/g?b=oidb&k=xnT9D0hzSGjSOOZkzqoutA&s=100&t=1555898643"
/>
div>
nav>
……
我们通过一个 容器 包裹 和
元素,那只要我们设置 靠右,那其所有的内容则会跟着靠右了。我们添加一些基础的 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="搜你想要的东西" />
<img
src="//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>
<img
class="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左侧的点*/
}
CSS——背景
背景颜色
渐变色
先复习一下背景颜色的几种写法:
background: red;
background: #ffffff;
background: rgb(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 除了设置背景颜色,还可以设置背景图片,背景图片在网页中使用十分常见。我们来看一下网上一些背景图片使用案例。
- 优课达下载页面【https://www.youkeda.com/app】黄色标注区
- 微博个人主页【https://weibo.com/u/1350995007】头部区域 和 整个页面背景
网易云音乐【https://music.163.com/】客户端下载区域
使用基础
先看一下我们的目标:
代码如下:
DOCTYPE html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="./index.css" />
<title>优课达title>
head>
<body>
<div class="box">HELLO WORLDdiv>
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. 背景图片出现了重复:background-repeat:no-repeat
当背景图片长宽任意一项小于容器的长宽,默认 CSS 会让图片重复,直到铺满整个容器位置。
我们可以使用 background-repeat: no-repeat;
禁止图片的重复。
现在的效果如下:
我们来完整的学习下background-repeat
的值。
值
描述
repeat
这是默认值。如果背景图片比容器小,将在垂直和水平方向进行重复
repeat-x
背景图片只在水平方向重复
repeat-y
背景图片只在垂直方向重复
no-repeat
背景图片将只显示一次,不重复
2.背景图片不居中:background-position:center
默认情况下,背景图片是从容器的左上角开始布局,为了使容器垂直水平居中,我们可以使用 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
的值。
值
描述
- top left
- top center
- top right
- center left
- center center
- center right
- bottom left
- bottom center
- bottom right
左侧两个元素为一组一起出现,分别代表垂直和水平布局
比如:
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-size
在上面的基础上,我们希望背景图片放大撑满整个容器,如下图所示:
我们需要认识一个新的属性 background-size
,用这个属性可以设置背景图片的大小,我们直接来看看这个属性有哪些值。
值
描述
cover
把背景图像扩展至足够大,以使背景图像完全覆盖背景区域。 背景图像的某些部分也许无法显示在背景定位区域中。
contain
把图像图像扩展至最大尺寸,以使其宽度和高度完全适应内容区域。
xpx ypx
手动设置宽度和高度
x% y%
手动设置宽度和高度相对于容器的百分比
通过描述,我们想想要实现上图效果,我们应该选用那个值?
如果还是不知道,不如我们直接用代码试一下。前端开发的好处,可以直接在线测试。
我们分别把 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: https://developer.mozilla.org/zh-CN/docs/Web/CSS/background-attachment
position-clip: https://developer.mozilla.org/zh-CN/docs/Web/CSS/background-clip
这两个属性大家可以简单阅读下,不是重点。