我们来看一个例子,如下图所示:
我们编写这样一个界面,HTML可能会这样写:
<div>div>
<div>div>
<div>div>
但是这样,原本清晰的页面仅凭代码是无法在脑海中生成这个页面结构的。
HTML5中的语义化标签就可以解决这个问题。上面对应的每一个区块,在HTML5中都有对应的语义化标签:
<header>header>
<main>main>
<footer>footer>
常用语义标签:
对应的HTML代码如下:
<header>headerheader>
<main>
<nav>navnav>
<section>sectionsection>
<section>sectionsection>
main>
<aside>aside>
<footer>footer>
假设我们想完成如下设计:
核心代码如下:
<span class="icon">span><span class="words">主页span>
.icon {
display: inline-block;
width: 24px;
height: 24px;
background: url(https://qgt-document.oss-cn-beijing.aliyuncs.com/P3-2-HTML-CSS/1.2/source/first-page.png) no-repeat center;
background-size: contain;
vertical-align: top;
margin-right: 8px;
}
.words {
font-size: 18px;
line-height: 24px;
}
但其实我们还有一种更好的写法:伪元素。
伪元素就是利用CSS代码在标签内部的前面,或者后面添加一个行内元素,这个行内元素你可以理解为span
。
下面我们来认识一下伪元素的写法:
/* before */
选择器::before{
/* 使用空白符号占位 */
content: '';
}
/* after */
选择器::after{
/* 使用空白符号占位 */
content: '';
}
接下来我们来使用伪元素实现开头的案例:
HTML
代码中类名为icon
的span
标签<span>主页span>
/* 在span之前添加行内元素 */
span::before {
content: '';
/* 将添加的行内元素定位,并设置大小、背景 */
position: absolute;
left: 0px;
width: 24px;
height: 24px;
background: url(https://qgt-document.oss-cn-beijing.aliyuncs.com/P3-2-HTML-CSS/1.2/source/first-page.png) no-repeat center;
background-size: contain;
}
上述案例中我们将添加的行内元素做了定位处理,其实还可以将添加的行内元素转换成块元素(block
)或者行内块元素(inline-block
)来实现我们需要的效果。
::after
和::before
是一样的,当我们需要第二个行内元素的时候,就需要用after
。
首先看一个页面:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tIKllX7H-1683641540284)(…/…/AppData/Roaming/Typora/typora-user-images/css高级/
)]
这个页面最简单的方式就是设置子元素高度,父元素高度自适应,代码如下:
<div class="father-one">
<div class="son-one">son-onediv>
<div class="son-two">son-twodiv>
<div class="son-three">son-threediv>
div>
.father-one {
border: 2px solid #8E8A97;
text-align: center;
}
.son-one {
line-height: 50px;
background-color: #00FFFF;
}
.son-two {
line-height: 100px;
background-color: #00BFFF;
}
.son-three {
line-height: 50px;
background-color: #00FFFF;
}
下面我们给.father-one
后面添加一个兄弟元素,然后让.father-one
里面的所有子元素都浮动,看一下会出现什么现象:
核心代码如下(代码中省略了部分已有代码):
<div class="father-two">div>
.son-one{
/* 浮动后的元素宽度默认和它内容的宽度一致,即和文字的宽度一致。
这里为了美观,设置一个自定义宽度*/
width:33.3%;
float:left;
}
.son-two{
width:33.3%;
float:left;
}
.son-three{
width:33.3%;
float:left;
}
.father-two{
height: 150px;
background-color: #CACACA;
}
最终得到下图所示的页面效果:
观察上图,会发现类名为father-two
的div
的一部分内容会跑到father-one
的子元素的下面,这是因为father-two
会紧跟father-one
的下边界(即红色下边框线)。
这显然不是我们需要的效果,我们希望最终的页面效果应该是这样:
所以现在我们需要一种技术可以让父元素包住浮动的子元素,这种技术被称为清除浮动。
清除浮动的方法很多,这里我们只需要掌握一种最常用的方法即可,如下CSS
代码即是清除浮动的CSS
代码:
.clearfix::after{
content: '';
display: block;
clear: both;
}
比如说我们要解决之前案例中的浮动问题,只需要在父盒子上添加clearfix
类名即可,具体参见下方代码:
<div class="father-one clearfix">
<div class="son-one">son-onediv>
<div class="son-two">son-twodiv>
<div class="son-three">son-threediv>
div>
最后请记住一句话,哪个盒子的子元素有浮动,就在哪个盒子上添加清除浮动
什么是事件伪类?
通俗点说,就是鼠标移动上去,字体颜色、背景颜色或者边框中的一种或多种样式发生了改变;那么如何使得这些样式发生了改变呢?
一个白色的按钮,我们想让他在鼠标移动上去后变为蓝底白字,应该如何操作?
代码如下:
li:hover{
background-color: #47A0FC;
color: white;
}
active是鼠标点击时候的效果,这个效果在超链接中比较常见,注意这里的点击是点住鼠标不松开。
hover
的基础上,我们来再添加一个active
伪类,实现下图所示效果:
首先需要用选择器选中要添加伪类的标签,ul>li
.
然后在选择器后面添加对应的伪类,这里我们要添加的是active
ul>li:active{
/* 要改变的效果 */
}
最后在花括号内添加要改变的样式:
ul>li:active{
/* 要改变的效果 */
color: black;
}
下面我们通过代码演示来看一下最终的效果:
注意:
hover
一定要在active
之前,否则不会生效。
/* 正确 */
a:hover{}
a:active{}
/* 错误 */
a:active{}
a:hover{}
focus
:获取焦点的伪类,一般用于具有焦点的元素,比如input
,比如我们可以让input
获取到焦点以后,改变input
的边框颜色,操作方式与active相同。
假设有这样一个列表:
<ul>
<li>li>
<li>li>
.....
<li>li>
ul>
:first-child
我们尝试给第一个子元素改变颜色:
ul>li:first-child{
background-color: #3687FC;
color: #FFFFFF;
}
注意: 这里的选择器ul>li
一定要注意,选择器选到的是子元素li
而不是父元素ul
。
:last-child
我们只需要将上述案例中的:first-child
改成:last-child
即可实现.
:nth-child()
:nth-child()
较前两个来说略微复杂一点,但是理解起来并不困难,首先我们要关注的是child
后面的括号,在这个括号里我们可以添加任意数字,从1开始,1代表first-child
,以此类推。
比如说我们要选中第三个列表,可以这样来写:
ul>li:nth-child(3){
background-color: #3687FC;
color: #FFFFFF;
}
nth-child
后面的括号内除了写数字还可以写两个特定的单词odd
(奇数),even
(偶数),大家可以自行尝试一下这两个值。
下面来看一个实际应用中的案例,比如说淘宝网中有这样一个布局,如下图:
我们将详细内容简化为色块,变成下图所示的样子:
具体步骤如下:
<ul class="clearfix">
<li>li>
<li>li>
<li>li>
<li>li>
<li>li>
ul>
ul>li{
float: left;
width: 226px;
height: 80px;
/* 给所有的li着色为相同颜色 */
background: #9D24EC;
border-radius: 10px;
/* 统一为所有的色块设置右边距 */
margin-right: 11px;
}
/* 使用伪类层叠掉不同颜色的色块 */
ul>li:nth-child(2){
background: #FB9526;
}
ul>li:nth-child(3){
background: #FE59CE;
}
ul>li:nth-child(4){
background: #4CC1FE;
}
ul>li:last-child{
background: #4BC74A;
}
ul>li:last-child{
/* 最后一个元素不需要右边距,用伪类清除 */
margin-right: 0px;
background: #4BC74A;
}
注意:
在上面的代码中,我们一直用的是ul
、li
标签,有同学会误以为只有li
标签才可以用列表伪类,其实是不对的:
使用ul
、li
是为了考虑语义化的因素
列表伪类的适用条件是,同一级别,相同元素
<div>
<div>
<div>div>
<div>div>
<div>div>
<div>div>
div>
<div>div>
<div>div>
<div>div>
div>
span:nth-child(2){
}
这个属性可以改变光标的形状,cursor
实现的。
cursor
添加的方法很简单,与之前学习的属性添加方式一样:
<p>点击这里了解更多cursor性质p>
p{
cursor: pointer;
}
cursor
的值很多,pointer
只是其中一个,下面是一些其他属性:
cursor: pointer(点击手)
cursor: default(普通)
cursor: text(文本)
cursor: move(移动)
cursor: grab(托动手)
cursor: zoom-in(放大镜+)
cursor: zoom-out(放大镜-)
可以自己测试一下,将鼠标指针放到运行结果的条目上,查看鼠标指针的变化。
想要了解更多内容请查看MDN文档
box-shadow——盒子阴影
盒子的形成原理就是盒子下面的另一个盒子改变样式或者位置造成的现象,你可以点击这里,调节相关的属性值来查看效果,这个工具中每个参数代表的意思如下图:
阴影是一个常用且不重要的属性,我们只需要知道如何在设计稿里找到阴影值,然后用下面的方式去设置即可:
div{
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.11);
}
更多关于阴影的详细描述,请参见文档
text-shadow——文字阴影
文字阴影和盒子阴影一样,如果说盒子阴影的形成原因是盒子下面的另一个盒子改变样式或者位置造成的现象,那么文字阴影就是文字下面还有一层相同的文字。
当然了,原理在这里并不重要,重要的是我们可以用下面这段代码去设置文字阴影:
span{
text-shadow: 0px 0px 10px rgba(0, 0, 0, 0.11);
}
更多关于文字阴影的详细描述,请参见文档
网页布局是前端开发中一个重要的课题。根据我们在 “Web前端基础” 中学习到的盒模型、display 属性和 position 属性等知识,我们已经可以做出比较好看的布局了。
但是对于一些特殊布局,比如垂直居中,就会比较麻烦。
2009 年,W3C 提出了一种新的方案——Flex 布局,可以简便、完整、响应式地实现各种页面布局。到目前为止,它已经得到了所有浏览器的支持,我们可以安全放心的使用这项功能。
flex 布局有强大的空间分布和对齐能力,可以很容易解决传统布局 比较难解决的布局问题。目前 flex 布局是主流的布局方式,很多前端UI库用的都是flex布局。
传统布局,即基于盒模型,依赖 display 属性 、position 属性 、float 属性进行布局。
什么是flex
Flex 是 Flexible Box 的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性。任何一个容器都可以指定为 Flex 布局。它最显著的效果就是把原本从上到下排列的块状元素变成水平排列。
代码如下:
<div class="container">
<div class="item">项目1div>
<div class="item">项目2div>
<div class="item">项目3div>
div>
.container {
display: flex;
background: #D5E8D4;
border: 1px solid #5D9E5A;
}
.item {
width: 50px;
height: 50px;
background: #FFF2CC;
border: 1px solid #B7A570;
margin: 10px;
}
注意:设为 Flex 布局以后,子元素的 float、clear 和 vertical-align 属性将失效。
采用 Flex 布局的元素,称为 Flex 容器(flex container),简称”容器”。它的所有子元素称为 Flex 项目(flex item),简称”项目”。
在上面这个例子中,外层 div 是容器,内层的子元素是项目:
justify-content 属性定义了项目在水平方向上的对齐方式。
特别注意,justify-content 是容器的属性,设置在容器上。
justify-content 有六个有效值:
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
六个值的表现形式如下:
在六个值中,我们最常用到的就是 “space-between” 了。
我们已经设置了水平方向的格式,那么如何让图片和文字能够在垂直方向上居中呢,这里我们需要用到 flex 布局中控制垂直方向分布的属性 align-items。
align-items 属性定义项目在垂直方向上的对齐方式。
特别注意,align-items 是容器的属性,设置在容器上。
align-items 有五个有效值:
align-items: flex-start | flex-end | center | baseline | stretch;
五个值的表现形式如下:
在五个值中,我们最常用到的就是 “center” 了。另外要注意,align-items 的默认值是 stretch,也就是说,在没有给项目设置高度的时候,项目的高度会和容器等高。
从上面导航条的例子中,我们可以看到 flex 布局有非常强大的空间分布和对齐能力。justify-content 和 align-items 能够很方便的操控项目在水平方向和垂直方向上的分布。
默认情况下,项目都排在水平方向上,并且是单行排列,不会换行。即使所有项目加起来的宽度超过了容器的宽度,也不会换行,并且项目为了挤在一行里,会在宽度上进行压缩。
当一行排不下的时候,项目会自动压缩挤在一条线上,没有换行,也没有超出容器,而且即使给项目设置了宽度(50px)也阻止不了项目被压缩。
如果想让项目换行,我们可以用 flex-wrap 属性,定义项目是否换行、以及如何换行。
flex-wrap 可能取三个值:
flex-wrap: nowrap | wrap | wrap-reverse;
项目属性flex可以控制项目的放大和缩小。
如果我们希望项目排在一行里,但是项目的宽度又不被压缩,那么我们应该给项目设置 flex:none,使项目不能被压缩或放大。
之前我们接触到的属性,justify-content、align-items、flex-wrap,都是设置在 flex 容器上的。但是这个控制项目是否被压缩或放大的属性,是设置在 flex 项目上的。
对比不设置 flex 属性和设置 flex:none 两种情况下项目的缩放情况:
如果一行有剩余的情况下,希望项目能够均匀放大,撑满水平方向,我们应该给所有项目设置 flex: 1,注意这里是给所有项目都设置。
注意,因为所有项目设置的 flex 的值都为 1,所以所有项目的宽度都相同,这一点很重要,我们可以用这一点来平分一行的空间。
两栏自适应布局指的是一栏固定宽度,另一栏随浏览器宽度的变化自动调节自己的宽度。
我们可以使用如下代码完成上述效果:
<div class="flex-auto">
<div class="static">div>
<div class="flexible">div>
div>
.flex-auto {
display: flex;
}
.flex-auto .static {
width: 100px;
flex: none;
}
.flex-auto .flexible {
flex: 1;
}
其实如果一行有剩余的情况下,我们可以任意指定某个项目放大撑满剩余空间,只要给指定项目设置 flex: 1 即可。
现在我们给最后一个项目设置 flex: 1,看看变化。
对比不设置 flex 属性和设置 flex:1两种情况下项目的缩放情况:
有的时候我们需要的是垂直方向上的“三栏自适应布局”,上下两栏固定,中间栏高度充满剩余空间,这样在不同高度的手机上都能适应,如下所示:
要做上面这种自适应布局思路是很明确的,我们只需要改变横向的三栏自适应布局中三栏的排列方向就可以了(水平向右改成从上到下),那到底怎么实现呢?
很简单,flex 布局给我们提供了一个属性flex-direction,可以改变项目的排列方向(水平向右)。当我们设置 flex-direction:column 时,上面的横向三栏自适应布局会变成纵向的。
flex-direction 有四个有效值:
flex-direction: row | row-reverse | column | column-reverse;
row:即默认值,主轴为水平方向,起点在左端。
row-reverse:主轴为水平方向,起点在右端。
column:主轴为垂直方向,起点在上沿。
column-reverse:主轴为垂直方向,起点在下沿。
用 flex-direction 改变主轴方向后,justify-content和align-items控制的方向也会发生变化:
设置了flex-direction:column之后,justify-content:space-between;控制的是项目在垂直方向上的分布。
在网页中我们常常遇到文本内容溢出,用省略号代替剩余内容的情况,比如:
接下来我们就来学习一下,文本溢出省略的实现方法。
文本溢出省略分为单行溢出省略和多行溢出省略,我们先学习单行的溢出处理。
正常情况下,文本内容超出了所给的宽度范围,文字会自动换行,但我们并不希望它换行,这时候我们就需要进行单行文本溢出省略的操作了。
这里就涉及到三个知识:强制不换行、元素内容溢出处理和文本溢出省略。
HTML5 中推荐使用 “white-space: nowrap;” 实现不换行。
进一步设置,对超出的文本进行处理,我们的目标是超出部分不显示,并且出现省略号,所以这一步我们要给元素设置超出隐藏,这里要用到属性 overflow。
overflow 属性决定超出盒子的内容怎么显示,它有 5 个有效值:
overflow: visible | hidden | inherit | scroll | auto;
值 | 描述 |
---|---|
visible | 默认值。内容不会被修剪,会呈现在元素框之外。 |
hidden | 内容会被修剪,并且超出的内容不可见 |
inherit | 规定应该从父元素继承 overflow 属性的值。 |
scroll | 内容会被修剪,浏览器会显示滚动条以便查看超出的内容 |
auto | 由浏览器定夺,如果内容被修剪,就会显示滚动条 |
最后我们用省略号代替剩余内容。css有个专门处理文本溢出的属性可以完成这个功能:text-overflow。
它有两个值:
text-overflow: clip | ellipsis;
简单的总结一下,文本溢出省略的css代码:
/* 强制不换行 */
white-space: nowrap;
/* 隐藏超出部分 */
overflow: hidden;
/* 用省略号代替剩余内容 */
text-overflow: ellipsis;
WebKit内核浏览器多行文本溢出省略
WebKit内核的浏览器实现起来比较简单,具体代码如下:
/* 隐藏超出部分 */
overflow : hidden;
/* 文本超出就用省略号 */
text-overflow: ellipsis;
/* 把对象作为弹性伸缩盒子模型显示 */
display: -webkit-box;
/* WebKit内核的浏览器的私有属性,设置文本超出2行就用省略号 */
-webkit-line-clamp: 2;
/* WebKit内核的浏览器的私有属性,设置或检索伸缩盒对象的子元素的排列方式 */
-webkit-box-orient: vertical;
我们先把“white-space: nowrap;”去掉,这样文本不会被强制不换行。
其他浏览器目前没有CSS属性可以直接控制多行文本的省略显示。在我们之后学习了Javascript之后,可以用js做。
SASS 是一款 CSS 预编译器,它定义了一种新的编程语言,为CSS 增加了一些编程的特性,开发者使用这种语言进行编码后,代码需要被编译成 CSS 才能被浏览器理解。
SASS 比 CSS 更像一门编程语言,它可以有变量,函数,控制语句、导入、嵌套等高级功能,类似的 CSS 预编译器还有less,Stylus等。
有了这些高级功能,SASS 可以:
写好的 Sass/Scss 文件会在运行代码之后直接编译成同名的 CSS 文件,因此在 HTML 文件中引入编译后的 CSS 文件即可。
编译命令:⽅法⼀:sass --watch index.scss:css/index.css
⽅法⼆:sass --watch index.scss:index.css (更加推荐)
我们已经知道了 Sass 是一款 CSS 预编译器,那么大家说的 Scss 又是什么呢?
Scss 其实是 Sass 3 为了兼容 CSS 引入的新语法。
大家都学习过了CSS的写法,知道CSS的语法是选择器 + 声明块。声明块是由花括号 和 声明组成的。比如:
#sidebar {
width: 30%;
background-color: #faa;
}
但是最早的 Sass 语法格式,被称为 缩进格式 (Indented Sass) 通常简称 “Sass”,是一种简化格式。它使用 “缩进” 代替 “花括号” 表示属性属于某个选择器,用 “换行” 代替 “分号” 分隔属性,很多人认为这样做比 SCSS 更容易阅读,书写也更快速,比如上面这段样式用sass的语法可以这样写:
#sidebar
width: 30%
background-color: #faa
Sass 3 引入了新的语法,也就是 Scss ,其语法完全兼容 CSS3,并且继承了 Sass 的强大功能。也就是说,任何标准的 CSS3 样式表都是具有相同语义的有效的 Scss 文件。
Sass和Scss的大部分扩展,例如变量、parent references 和 指令都是一致的;唯一不同的是,SCSS 需要使用分号和花括号而不是换行和缩进。 比如上面这段样式用Scss的语法写的话看起来和CSS的写法是一样的:
#sidebar {
width: 30%;
background-color: #faa;
}
我们倡导大家使用 Scss 编写样式文件。文件的后缀请使用“.scss”。
在 CSS 属性的基础上 Sass 提供了一些名为 SassScript 的新功能。 SassScript 可作用于任何属性,允许属性使用变量、算数运算等额外功能。
SassScript 最普遍的用法就是变量,变量以美元符号”$”开头,赋值方法与 CSS 属性的写法一样:
$width: 10px;
使用变量:
#main {
width: $width;
}
编译成 css:
#main {
width: 10px;
}
如果变量类型为字符串,一般不需要加引号,但是有些特殊情况*,比如字符串中有双斜杠“//”,就需要用英文输入法状态下的单引号或者双引号包裹字符串,用引号的写法:
// 变量需要定义在使用之前
$position: "absolute";
$mainTxtColor: '#333';
// 应用
#main {
position: $position;
color: $mainTxtColor;
}
因为在Sass中双斜杠表示单行注释。
除了简单的赋值,Sass中变量还可以定义类似数组的变量:
$animals: puppy kitty chick;
这样的变量一般会配合Sass中的循环语句使用,我们在后面的课程中会讲到的。
还是上面这个例子:
$width: 10px;
#main {
width: $width / 2;
}
编译成 css:
#main {
width: 5px;
}
Sass 中支持在使用变量的时候进行简单的加减乘除的计算。
这样一来我们可以很方便的定义固定宽高比的元素。比如:
$width: 10px;
#main {
width: $width / 2;
height: $width * 2;
}
编译成 css:
#main {
width: 5px;
height: 20px;
}
上面这个元素的宽高比:width : height = 1 / 4,不管怎么改变 $width 的值,这个宽高比是不会变的。
#{}
插值几乎可以在Sass样式表的任何地方使用:
$name: "mail";
$top-or-bottom: "top";
$left-or-right: "left";
.icon-#{$name} {
background-image: url("/icons/#{$name}.svg");
position: absolute;
#{$top-or-bottom}: 0;
#{$left-or-right}: 0;
}
.icon-#{$name}
:“$name”为“mail”,编译后选择器为“.icon-mail”;url("/icons/#{$name}.svg")
:“$name”为“mail”,编译后图片路径为“/icons/mail.svg”;#{$top-or-bottom}: 0;
:“$top-or-bottom”为“top”,编译后声明为“top: 0;”完整的编译结果:
.icon-mail {
background-image: url("/icons/mail.svg");
position: absolute;
top: 0;
left: 0;
}
值得一提的是:你可以用插值法插入任何类型的变量,不仅仅是字符串。
下面是我们常见的css选择器写法:
main .double .item .links {
text-align: center;
}
main .double .item .links a {
margin-right: 20px;
}
特别是遇到比较复杂的页面结构,为了不影响其他元素的样式,写样式的时候我们往往会把选择器写的比较精确,导致这个选择器就会越写越长。
这就会产生很多问题,比如:一不小心手误写错了父选择器、选择器太长不知道选中的到底是哪个元素……
总而言之,过长的选择器不但写的时候抓狂,可读性可维护性也差。
Sass为了解决这个问题,提供了一个很实用的功能:嵌套。
比如上面的这两个选择器选中的元素是父子元素关系,在 Sass 里可以这样写,把共同的选择器提了出来:
main .double .item .links {
text-align: center;
a {
margin-right: 20px;
}
}
这样一来,元素之间的结构是不是就很清楚了呢。下面我们来详细的学习一下 Sass 中的嵌套功能。
Sass 允许将一套 CSS 样式嵌套进另一套样式中,内层的样式将它外层的选择器作为父选择器,比如:
嵌套功能避免了重复输入父选择器,而且令复杂的 CSS 结构更易于管理。
在嵌套 CSS 规则时,有时也需要直接使用嵌套外层的父选择器,例如,当给某个元素设定 hover 样式时,可以用 & 代表嵌套规则外层的父选择器,比如:
或者特殊一点的用法:
嵌套功能使样式代码的结构更清晰,大大降低了写错的概率,安全性、可读性、可维护性上都有很大的提升。
很多编程语言中都有解决代码复用的方案,sass也不例外,我们可以用混合(mixin/include)来定义可重复使用的样式。
mixin/include 除了可以用来解决代码复用问题,还能解决无语义的类名问题(比如:“.float-left”)。
在写网页样式的时候,我们常常遇到在不同元素中运用相同样式的情况,比如把页面上的头像都处理成宽高1:1的正方形的情况。
通过我们之前的学习,在css中我们可以通过复用类名,来实现代码的复用:
.square {
width: 100px;
height: 100px;
}
<div class="user-avatar square">...div>
<div class="admin-avatar square">...div>
现在,我们试着用Sass 的mixin/include来解决复用问题:
@mixin square {
width: 100px;
height: 100px;
}
// 应用:
.user-avatar {
@include square;
}
.admin-avatar {
@include square;
}
上面这段sass代码中,定义了一个可复用的代码块,并取名为 square,它的主要用途是把元素设置成宽高 1:1 的正方形。然后,通过使用关键词@include,我们在div.user-avatar和div.admin-avatar中应用了这个样式。
编译结果:
.user-avatar {
width: 100px;
height: 100px;
}
.admin-avatar {
width: 100px;
height: 100px;
}
这样是不是很方便呢,用了混合,我们就不用去改动 HTML代码了(在元素中添加类名)。
混合的使用方法: ”@mixin“:定义可复用的样式 ”@include“:应用可复用的样式
那我们可不可以指定正方形的大小呢?
可以的,只要给定义的样式代码传入参数就可以啦。
如何给定义的复用代码块传入参数,增加它的可用性呢,还是上面的例子,我们稍作修改:
@mixin square($size) {
width: $size;
height: $size;
}
// 应用
.avatar {
@include square(100px);
}
这里我们允许使用者在使用 square 的时候传入一个值 s i z e ,然后根据传入的值 ‘ size,然后根据传入的值 ` size,然后根据传入的值‘size` 把元素处理成正方形。
编译结果:
.avatar {
width: 100px;
height: 100px;
}
这样,头像就被处理成了宽高各为 100px 的正方形。
传参数的这种情况,我们还可以给参数设定默认值,比如:
@mixin square($size: 100px) {
width: $size;
height: $size;
}
// 不传参数就会使用默认的值 100px
.avatar {
@include square;
}
// 传入参数就会使用传入的值 200px
.avatar-200 {
@include square($size: 200px);
}
编译结果:
/* 不传参数就会使用默认的值 100px */
.avatar {
width: 100px;
height: 100px;
}
/* 传入参数就会使用传入的值 200px */
.avatar-200 {
width: 200px;
height: 200px;
}
什么是响应式网页设计?
响应式布局这个概念是Ethan Marcotte在2010年5月份提出的一个概念,简而言之,就是一个网站能够兼容多个终端,而不是为每个终端做一个特定的版本。
响应式布局主要通过规定特定的宽度范围使用特定的布局来实现在不同的设备上应用不同的布局。
下图是Github的网站:
可以看到 Github 在手机、平板、电脑上打开,页面的布局是有区别的。
下图是QQ注册页:
响应式不仅仅指页面在不同设备上布局不同,在同一设备(电脑)上通过调整浏览器的宽度,我们同样可以看到页面的布局发生了变化,这也是响应式布局。
要使页面在不同的宽度范围内使用特定的布局,就需要制定对应的规则,这里我们就要用到CSS3中的媒体查询 @media 了。
什么是媒体查询?
媒体查询是CSS3中引入的一种CSS技术。仅当满足特定条件时,它才使用对应的CSS属性块。
先来看一下媒体查询的基础语法:
“screen”:告知设备在打印页面时使用衬线字体,在屏幕上显示时用无衬线字体。如果你的网页不需要考虑用户去打印时,你可以直接这样把上图代码中的“screen and ”去掉。
我们以 QQ 注册页为例,来写一下简单的响应式布局。
QQ 注册页的响应式布局
在 QQ 注册页中,根据浏览器宽度不同,它有三种布局:
浏览器宽度小于等于 900px 右上角导航项保留“简体中文”和“意见反馈”,隐藏左侧大图,保留表单部分;
浏览器宽度大于 900px,小于等于 1080px 右上角导航项全展示,显示左侧大图,图宽 240px;
浏览器宽度大于 1080px 右上角导航项全展示,显示左侧大图,图宽 480px;
宽度小于等于 900px,意味着最大宽度是 900px,所以宽度条件是“max-width: 900px”:
接下来,我们写浏览器宽度大于 1080px时,设置左侧大图宽度为 480px 的样式代码,宽度大于 1080px,即浏览器的最小宽度为 1080px(min-width: 1080px):
最后,我们写浏览器宽度大于 900px,小于等于 1080px时,设置左侧大图宽度为 240px 的样式代码。
浏览器宽度大于 900px,小于等于 1080px,即浏览器的最小宽度是 900px(min-width: 900px),最大宽度是 1080px(max-width: 1080px),并用逻辑操作符 and 把两个条件结合起来:
在上面的案例中:
这两个点(900px 和 1080px)就是我们所说的断点(break points)。
在 QQ 注册页中,除了用上一章节的方法写媒体查询条件的,我们还可以这样写(变动的代码已在下面标出):
/* 小于等于 900px时应用此布局 */
@media screen and (max-width: 900px) {
.container .side {
/* 提示:把原来的 display:none; 改成了 width:0; */
width: 0;
}
}
/* 小于等于 1080px时应用此布局 */
/* 提示:把原来的条件 “(min-width: 900px) and (max-width: 1080px)” 改成了 “(max-width: 1080px)” */
@media screen and (max-width: 1080px) {
.container .side {
width: 240px;
}
}
/* 大于1080px时应用此布局 */
@media screen and (min-width: 1080px) {
.container .side {
width: 480px;
}
}
我们把上面的规则表示在数轴上:
这时候我们发现,当浏览器宽度小于 900px,它既满足第一个媒体查询的条件,又满足第二个媒体查询的条件,两个条件中的样式代码会发生冲突,根据css中越靠后的样式优先级越高的原则,左侧大图会应用width:240px
这段样式代码。
这不符合我们的预期。
由于css中越靠后的样式优先级越高,因此这里就存在一个问题,就是冲突的媒体查询条件的顺序怎么排。
在上面这个例子中,我们应该把第一个条件和第二个条件的顺序交换一下,在数轴上表示调整顺序后的规则:
由于条件(max-width: 900px)排到了(max-width: 1080px)后面,因此当浏览器宽度小于 900px时,根据css中越靠后的样式优先级越高的原则,左侧大图会应用width:0px
这段样式代码,这才是符合我们预期的。
总结: