1.说说你对盒子模型的理解?
一、是什么
对一个文档进行布局的时候,浏览器渲染引擎会根据标准之一的css基础盒模型,将所有元素表示为一个个矩形的盒子。
一个盒子由四个部分组成: content
,padding
,border
,margin
下面看看标准盒子模型的模型图:
从上图可以看到:
- 盒子总宽度 = width + padding + border + margin;
- 盒子总高度 = height + padding + border + margin
也就是,width/height 只是内容高度,不包含 padding 和 border值
所以上面问题中,设置width为200px,但由于存在padding,但实际上盒子的宽度有240px
三、IE 怪异盒子模型
同样看看IE 怪异盒子模型的模型图:
从上图可以看到:
- 盒子总宽度 = width + margin;
- 盒子总高度 = height + margin;
Box-sizing
css 中的 box-sizing 属性定义了引擎应该如何计算一个元素的总宽度和总高度
语法:
html">box-sizing: content-box | border-box | inherit;
- content-box 默认值,元素的 width/height 不包含padding,border,与标准盒子模型表现一致
- border-box 元素的 width/height 包含 padding,border,与怪异盒子模型表现一致
- inherit 指定 box-sizing 属性的值,应该从父元素继承
2.如何让一个盒子水平垂直居中
1:子绝父相,子盒子使用margin属性
css">.parent {position: relative;...
}.child {position: absolute;left: 50%;top: 50%;margin-left: -50%;margin-top: -50%;
}
2:子绝父相,子盒子使用transform属性
css">.parent {position: relative;
}.child {position: absolute;left: 50%;top: 50%;transform: translate(-50%, -50%);
}
3:子绝父相,子盒子使用偏移量配合margin属性
css">.parent {position: relative;
}.child{position: absolute;top: 0;left: 0;bottom: 0;right: 0;margin: auto;
}
4:通过父元素给开启flex布局
css">.parent {display: flex;justify-content: center;align-items: center;
}
3.什么是BFC
一、是什么
我们在页面布局的时候,经常出现以下情况:
- 这个元素高度怎么没了?
- 这两栏布局怎么没法自适应?
- 这两个元素的间距怎么有点奇怪的样子?
- ......
原因是元素之间相互的影响,导致了意料之外的情况,这里就涉及到BFC概念
BFC(Block Formatting Context),即块级格式化上下文,它是页面中的一块渲染区域,并且有一套属于自己的渲染规则:
- 内部的盒子会在垂直方向上一个接一个的放置
- 对于同一个BFC的俩个相邻的盒子的margin会发生重叠,与方向无关。
- 每个元素的左外边距与包含块的左边界相接触(从左到右),即使浮动元素也是如此
- BFC的区域不会与float的元素区域重叠
- 计算BFC的高度时,浮动子元素也参与计算
- BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然
BFC目的是形成一个相对于外界完全独立的空间,让内部的子元素不会影响到外部的元素
二、触发条件
触发BFC
的条件包含不限于:
- 根元素,即HTML元素
- 浮动元素:float值为left、right
- overflow值不为 visible,为 auto、scroll、hidden
- display的值为inline-block、inltable-cell、table-caption、table、inline-table、flex、inline-flex、grid、inline-grid
- position的值为absolute或fixed
三、应用场景
利用BFC
的特性,我们将BFC
应用在以下场景:
防止margin重叠(塌陷)
<style>p {color: #f55;background: #fcc;width: 200px;line-height: 100px;text-align:center;margin: 100px;}
</style>
<body><p>Haha</p ><p>Hehe</p >
</body>
页面显示如下:
两个p元素之间的距离为100px,发生了margin重叠(塌陷),以最大的为准,如果第一个P的margin为80的话,两个P之间的距离还是100,以最大的为准。
前面讲到,同一个BFC的俩个相邻的盒子的margin会发生重叠
可以在p外面包裹一层容器,并触发这个容器生成一个BFC,那么两个p就不属于同一个BFC,则不会出现margin重叠
<style>.wrap {overflow: hidden;// 新的BFC}p {color: #f55;background: #fcc;width: 200px;line-height: 100px;text-align:center;margin: 100px;}
</style>
<body><p>Haha</p ><div class="wrap"><p>Hehe</p ></div>
</body>
这时候,边距则不会重叠:
清除内部浮动
<style>.par {border: 5px solid #fcc;width: 300px;}.child {border: 5px solid #f66;width:100px;height: 100px;float: left;}
</style>
<body><div class="par"><div class="child"></div><div class="child"></div></div>
</body>
页面显示如下:
自适应多栏布局
这里举个两栏的布局
<style>body {width: 300px;position: relative;}.aside {width: 100px;height: 150px;float: left;background: #f66;}.main {height: 200px;background: #fcc;}
</style>
<body><div class="aside"></div><div class="main"></div>
</body>
效果图如下:
前面讲到,每个元素的左外边距与包含块的左边界相接触
因此,虽然.aslide为浮动元素,但是main的左边依然会与包含块的左边相接触
而BFC的区域不会与浮动盒子重叠
所以我们可以通过触发main生成BFC,以此适应两栏布局
.main {overflow: hidden;
}
这时候,新的BFC不会与浮动的.aside元素重叠。因此会根据包含块的宽度,和.aside的宽度,自动变窄
效果如下:
小结
可以看到上面几个案例,都体现了BFC实际就是页面一个独立的容器,里面的子元素不影响外面的元素
4.如何实现单行/多行文本溢出的省略样式?
单行文本溢出省略
理解也很简单,即文本在一行内显示,超出部分以省略号的形式展现
实现方式也很简单,涉及的css属性有:
- text-overflow:规定当文本溢出时,显示省略符号来代表被修剪的文本
- white-space:设置文字在一行显示,不能换行
- overflow:文字长度超出限定宽度,则隐藏超出的内容
overflow设为hidden,普通情况用在块级元素的外层隐藏内部溢出元素,或者配合下面两个属性实现文本溢出省略
white-space:nowrap,作用是设置文本不换行,是overflow:hidden和text-overflow:ellipsis生效的基础
text-overflow属性值有如下:
- clip:当对象内文本溢出部分裁切掉
- ellipsis:当对象内文本溢出时显示省略标记(...)
text-overflow只有在设置了overflow:hidden和white-space:nowrap才能够生效的
举个例子
css"><style>p{line-height: 40px;width:400px;height:40px;border:1px solid red;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;}
</style>
<p 这是一些文本这是一些文本这是一些文本这是一些文本这是一些文本这是一些文本这是一些文本这是一些文本这是一些文本这是一些文本</p >
多行文本溢出省略
多行文本溢出的时候,我们可以分为两种情况:
- 基于高度截断
- 基于行数截断
基于高度截断
伪元素 + 定位
核心的css代码结构如下:
- position: relative:为伪元素绝对定位
- overflow: hidden:文本溢出限定的宽度就隐藏内容)
- position: absolute:给省略号绝对定位
- line-height: 20px:结合元素高度,高度固定的情况下,设定行高, 控制显示行数
- height: 40px:设定当前元素高度
- ::after {} :设置省略号样式
代码如下所示:
<style>.demo {position: relative;line-height: 20px;height: 40px;overflow: hidden;}.demo::after {content: "...";position: absolute;bottom: 0;right: 0;padding: 0 20px 0 10px;}
</style><body><div class='demo'>这是一段很长的文本</div>
</body>
实现原理很好理解,就是通过伪元素绝对定位到行尾并遮住文字,再通过 overflow: hidden 隐藏多余文字
这种实现具有以下优点:
- 兼容性好,对各大主流浏览器有好的支持
- 响应式截断,根据不同宽度做出调整
一般文本存在英文的时候,可以设置word-break: break-all使一个单词能够在换行时进行拆分
基于行数截断
- -webkit-line-clamp: 2:用来限制在一个块元素显示的文本的行数,为了实现该效果,它需要组合其他的WebKit属性)
- display: -webkit-box:和1结合使用,将对象作为弹性伸缩盒子模型显示
- -webkit-box-orient: vertical:和1结合使用 ,设置或检索伸缩盒对象的子元素的排列方式
- overflow: hidden:文本溢出限定的宽度就隐藏内容
- text-overflow: ellipsis:多行文本的情况下,用省略号“…”隐藏溢出范围的文本
<style>p {width: 400px;border-radius: 1px solid red;-webkit-line-clamp: 2;display: -webkit-box;-webkit-box-orient: vertical;overflow: hidden;text-overflow: ellipsis;}
</style>
<p>这是一些文本这是一些文本这是一些文本这是一些文本这是一些文本这是一些文本这是一些文本这是一些文本这是一些文本这是一些文本
</p >
css如何画一个三角形?
css">.box {width: 0;height: 0;border: 2px solid transparent;border-bottom-color: pink;
/* 虽然视觉上是实现了三角形,但实际上,隐藏的部分任然占据部分高度,需要将上方的宽度去掉 */border-top-width: 0;
}
直角三角形
5.让Chrome支持小于12px 的文字方式有哪些?
Zoom
zoom 的字面意思是“变焦”,可以改变页面上元素的尺寸,属于真实尺寸
其支持的值类型有:
- zoom:50%,表示缩小到原来的一半
- zoom:0.5,表示缩小到原来的一半
使用 zoom 来”支持“ 12px 以下的字体
代码如下:
<style type="text/css">.span1{font-size: 12px;display: inline-block;zoom: 0.8;}.span2{display: inline-block;font-size: 12px;}
</style>
<body><span class="span1">测试10px</span><span class="span2">测试12px</span>
</body>
效果如下:
需要注意的是,Zoom 并不是标准属性,需要考虑其兼容性
-webkit-transform:scale()
针对chrome浏览器,加webkit前缀,用transform:scale()这个属性进行放缩
注意的是,使用scale属性只对可以定义宽高的元素生效,所以,下面代码中将span元素转为行内块元素
实现代码如下:
<style type="text/css">.span1{font-size: 12px;display: inline-block;-webkit-transform:scale(0.8);}.span2{display: inline-block;font-size: 12px;}
</style>
<body><span class="span1">测试10px</span><span class="span2">测试12px</span>
</body>
6.如何使用css完成视差滚动效果?
实现方式
使用css形式实现视觉差滚动效果的方式有:
- background-attachment
- transform:translate3D
background-attachment
作用是设置背景图像是否固定或者随着页面的其余部分滚动
值分别有如下:
- scroll:默认值,背景图像会随着页面其余部分的滚动而移动
- fixed:当页面的其余部分滚动时,背景图像不会移动
- inherit:继承父元素background-attachment属性的值
完成滚动视觉差就需要将background-attachment属性设置为fixed,让背景相对于视口固定。及时一个元素有滚动机制,背景也不会随着元素的内容而滚动
也就是说,背景一开始就已经被固定在初始的位置
transform:translate3D
同样,让我们先来看一下两个概念transform和perspective:
- transform: css3 属性,可以对元素进行变换(2d/3d),包括平移 translate,旋转 rotate,缩放 scale,等等
- perspective: css3 属性,当元素涉及 3d 变换时,perspective 可以定义我们眼睛看到的 3d 立体效果,即空间感
7.CSS选择器
选择器
它是元素和其他部分组合起来告诉告诉浏览器哪个HTML元素应当是被选为应用规则中的css属性值的方式
关于css属性选择器常用的有:
- id选择器(#box),选择id为box的元素
- 类选择器(.one),选择类名为one的所有元素
- 标签选择器(div),选择标签为div的所有元素
- 后代选择器(#box div),选择id为box元素内部所有的div元素
- 子选择器(.one>one_1),选择父元素为.one的所有.one_1的元素
- 相邻同胞选择器(.one+.two),选择紧接在.one之后的所有.two元素
- 群组选择器(div,p),选择div、p的所有元素
还有一些使用频率相对没那么多的选择器:
:link :选择未被访问的链接
:visited:选取已被访问的链接
:active:选择活动链接
:hover :鼠标指针浮动在上面的元素
:focus :选择具有焦点的
:first-child:父元素的首个子元素
- 伪元素选择器
:first-letter :用于选取指定选择器的首字母
:first-line :选取指定选择器的首行
:before : 选择器在被选元素的内容前面插入内容
:after : 选择器在被选元素的内容后面插入内容
- 属性选择器
[attribute] 选择带有attribute属性的元素
[attribute=value] 选择所有使用attribute=value的元素
[attribute~=value] 选择attribute属性包含value的元素
[attribute|=value]:选择attribute属性以value开头的元素
在CSS3中新增的选择器有如下:
- 层次选择器(p~ul),选择前面有p元素的每个ul元素
- 伪类选择器
:first-of-type 表示一组同级元素中其类型的第一个元素
:last-of-type 表示一组同级元素中其类型的最后一个元素
:only-of-type 表示没有同类型兄弟元素的元素
:only-child 表示没有任何兄弟的元素
:nth-child(n) 根据元素在一组同级中的位置匹配元素
:nth-last-of-type(n) 匹配给定类型的元素,基于它们在一组兄弟元素中的位置,从末尾开始计数
:last-child 表示一组兄弟元素中的最后一个元素
:root 设置HTML文档
:empty 指定空的元素
:enabled 选择可用元素
:disabled 选择被禁用元素
:checked 选择选中的元素
:not(selector) 选择与 <selector> 不匹配的所有元素
- 属性选择器
[attribute*=value]:选择attribute属性值包含value的所有元素
[attribute^=value]:选择attribute属性开头为value的所有元素
[attribute$=value]:选择attribute属性结尾为value的所有元素
优先级
内联 > ID选择器 > 类选择器 > 标签选择器
权重: 内联:1000,ID:100,类:10,伪类:10,伪元素:1,标签:1
如果外部样式需要覆盖内联样式,就需要使用!important
继承属性
在css中,继承是指的是给父元素设置一些属性,后代元素会自动拥有这些属性
关于继承属性,可以分成:
- 字体系列属性
font:组合字体
font-family:规定元素的字体系列
font-weight:设置字体的粗细
font-size:设置字体的尺寸
font-style:定义字体的风格
font-variant:偏大或偏小的字体
- 文本系列属性
text-indent:文本缩进
text-align:文本水平对刘
line-height:行高
word-spacing:增加或减少单词间的空白
letter-spacing:增加或减少字符间的空白
text-transform:控制文本大小写
direction:规定文本的书写方向
color:文本颜色
- 元素可见性
visibility
inherit | 继承 |
visible | 可见的(默认的) |
hidden | 隐藏元素后,占用原来的位置 |
注意:visibility隐藏元素后,继续占有原来位置。
如果隐藏元素想要原来位置,就用visibility:hidden
如果隐藏元素不想要原来位置,就用display:none
- 表格布局属性
caption-side:定位表格标题位置
border-collapse:合并表格边框
border-spacing:设置相邻单元格的边框间的距离
empty-cells:单元格的边框的出现与消失
table-layout:表格的宽度由什么决定
- 列表属性
list-style-type:文字前面的小点点样式
list-style-position:小点点位置
list-style:以上的属性可通过这属性集合
- 引用
quotes:设置嵌套引用的引号类型
- 光标属性
cursor:箭头可以变成需要的形状
继承中比较特殊的几点:
- a 标签的字体颜色不能被继承
- h1-h6标签字体的大下也是不能被继承的
- border和outline的区别是
- border会在页面中占有位置
- outline在页面中不占有位置
无继承的属性
- display
- 文本属性:vertical-align、text-decoration
- 盒子模型的属性:宽度、高度、内外边距、边框等
- 背景属性:背景图片、颜色、位置等
- 定位属性:浮动、清除浮动、定位position等
- 生成内容属性:content、counter-reset、counter-increment
- 轮廓样式属性:outline-style、outline-width、outline-color、outline
- 页面样式属性:size、page-break-before、page-break-after
8.css换行问题
- 强制不换行
div{
white-space:nowrap;
}
- 自动换行
div{word-wrap: break-word;word-break: normal;
}
- 强制英文单词断行
div{word-break:break-all;
}
9.行内元素padding问题
如果一个行内元素没有设置固定的宽度和高度,是可以使用padding内边距,将盒子撑开
注意:行内元素不能设置上下的外边距
10.说说对Css预编语言的理解?有哪些区别?
一、是什么
Css 作为一门标记性语言,语法相对简单,对使用者的要求较低,但同时也带来一些问题
需要书写大量看似没有逻辑的代码,不方便维护及扩展,不利于复用,尤其对于非前端开发工程师来讲,往往会因为缺少 Css 编写经验而很难写出组织良好且易于维护的 Css 代码
Css预处理器便是针对上述问题的解决方案
预处理语言
扩充了 Css 语言,增加了诸如变量、混合(mixin)、函数等功能,让 Css 更易维护、方便
本质上,预处理是Css的超集
包含一套自定义的语法及一个解析器,根据这些语法定义自己的样式规则,这些规则最终会通过解析器,编译生成对应的 Css 文件
二、有哪些
Css预编译语言在前端里面有三大优秀的预编处理器,分别是:
- sass
- less
- stylus
三、区别
虽然各种预处理器功能强大,但使用最多的,还是以下特性:
- 变量(variables)
- 作用域(scope)
- 代码混合( mixins)
- 嵌套(nested rules)
- 代码模块化(Modules)
因此,下面就展开这些方面的区别
基本使用
less和scss
.box {display: block;
}
sass
.boxdisplay: block
stylus
.boxdisplay: block
嵌套
三者的嵌套语法都是一致的,甚至连引用父级选择器的标记 & 也相同
区别只是 Sass 和 Stylus 可以用没有大括号的方式书写
less
.a {&.b {color: red;}
}
变量
变量无疑为 Css 增加了一种有效的复用方式,减少了原来在 Css 中无法避免的重复「硬编码」
less声明的变量必须以@开头,后面紧跟变量名和变量值,而且变量名和变量值需要使用冒号:分隔开
@red: #c00;strong {color: @red;
}
sass声明的变量跟less十分的相似,只是变量名前面使用$开头
$red: #c00;strong {color: $red;
}
stylus声明的变量没有任何的限定,可以使用$开头,结尾的分号;可有可无,但变量与变量值之间需要使用=
在stylus中我们不建议使用@符号开头声明变量
red = #c00strongcolor: red
作用域
Css 预编译器把变量赋予作用域,也就是存在生命周期。就像 js一样,它会先从局部作用域查找变量,依次向上级作用域查找
sass中不存在全局变量
$color: black;
.scoped {$bg: blue;$color: white;color: $color;background-color:$bg;
}
.unscoped {color:$color;
}
编译后
.scoped {color:white;/*是白色*/background-color:blue;
}
.unscoped {color:white;/*白色(无全局变量概念)*/
}
所以,在sass中最好不要定义相同的变量名
less与stylus的作用域跟javascript十分的相似,首先会查找局部定义的变量,如果没有找到,会像冒泡一样,一级一级往下查找,直到根为止
@color: black;
.scoped {@bg: blue;@color: white;color: @color;background-color:@bg;
}
.unscoped {color:@color;
}
编译后:
.scoped {color:white;/*白色(调用了局部变量)*/background-color:blue;
}
.unscoped {color:black;/*黑色(调用了全局变量)*/
}
混入
混入(mixin)应该说是预处理器最精髓的功能之一了,简单点来说,Mixins可以将一部分样式抽出,作为单独定义的模块,被很多选择器重复使用
可以在Mixins中定义变量或者默认参数
在less中,混合的用法是指将定义好的ClassA中引入另一个已经定义的Class,也能使用够传递参数,参数变量为@声明
.alert {font-weight: 700;
}.highlight(@color: red) {font-size: 1.2em;color: @color;
}.heads-up {.alert;.highlight(red);
}
编译后
.alert {font-weight: 700;
}
.heads-up {font-weight: 700;font-size: 1.2em;color: red;
}
Sass声明mixins时需要使用@mixinn,后面紧跟mixin的名,也可以设置参数,参数名为变量$声明的形式
@mixin large-text {font: {family: Arial;size: 20px;weight: bold;}color: #ff0000;
}.page-title {@include large-text;padding: 4px;margin-top: 10px;
}
stylus中的混合和前两款Css预处理器语言的混合略有不同,他可以不使用任何符号,就是直接声明Mixins名,然后在定义参数和默认值之间用等号(=)来连接
error(borderWidth= 2px) {border: borderWidth solid #F00;color: #F00;
}
.generic-error {padding: 20px;margin: 4px;error(); /* 调用error mixins */
}
.login-error {left: 12px;position: absolute;top: 20px;error(5px); /* 调用error mixins,并将参数$borderWidth的值指定为5px */
}
代码模块化
模块化就是将Css代码分成一个个模块
scss、less、stylus三者的使用方法都如下所示
@import './common';
@import './github-markdown';
@import './mixin';
@import './variables';
11.什么是响应式设计?响应式设计的基本原理是什么?如何做?
一、是什么
一套代码,搞定pc端和移动端,根据不同的屏幕尺寸,应用不同的样式
响应式网站设计(Responsive Web design)是一种网络页面设计布局,页面的设计与开发应当根据用户行为以及设备环境(系统平台、屏幕尺寸、屏幕定向等)进行相应的响应和调整
描述响应式界面最著名的一句话就是“Content is like water”
大白话便是“如果将屏幕看作容器,那么内容就像水一样”
响应式网站常见特点:
- 同时适配PC + 平板 + 手机等
- 标签导航在接近手持终端设备时改变为经典的抽屉式导航
- 网站的布局会根据视口来调整模块的大小和位置
二、实现方式
响应式设计的基本原理是通过媒体查询检测不同的设备屏幕尺寸做处理,为了处理移动端,页面头部必须有meta声明viewport
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no”>
属性对应如下:
- width=device-width: 是自适应手机屏幕的尺寸宽度
- maximum-scale:是缩放比例的最大值
- inital-scale:是缩放的初始化
- user-scalable:是用户的可以缩放的操作
实现响应式布局的方式有如下:
- 媒体查询
- 百分比
- vw/vh
- rem
媒体查询
CSS3中的增加了更多的媒体查询,就像if条件表达式一样,我们可以设置不同类型的媒体条件,并根据对应的条件,给相应符合条件的媒体调用相对应的样式表
使用@Media查询,可以针对不同的媒体类型定义不同的样式,如:
@media screen and (max-width: 1920px) { ... }
当视口在375px - 600px之间,设置特定字体大小18px
@media screen (min-width: 375px) and (max-width: 600px) {body {font-size: 18px;}
}
通过媒体查询,可以通过给不同分辨率的设备编写不同的样式来实现响应式的布局,比如我们为不同分辨率的屏幕,设置不同的背景图片
比如给小屏幕手机设置@2x图,为大屏幕手机设置@3x图,通过媒体查询就能很方便的实现
百分比
通过百分比单位 " % " 来实现响应式的效果
比如当浏览器的宽度或者高度发生变化时,通过百分比单位,可以使得浏览器中的组件的宽和高随着浏览器的变化而变化,从而实现响应式的效果
height、width属性的百分比依托于父标签的宽高,但是其他盒子属性则不完全依赖父元素:
- 子元素的top/left和bottom/right如果设置百分比,则相对于直接非static定位(默认定位)的父元素的高度/宽度
- 子元素的padding如果设置百分比,不论是垂直方向或者是水平方向,都相对于直接父亲元素的width,而与父元素的height无关。
- 子元素的margin如果设置成百分比,不论是垂直方向还是水平方向,都相对于直接父元素的width
- border-radius不一样,如果设置border-radius为百分比,则是相对于自身的宽度
可以看到每个属性都使用百分比,会照成布局的复杂度,所以不建议使用百分比来实现响应式
vw/vh
vw表示相对于视图窗口的宽度,vh表示相对于视图窗口高度。 任意层级元素,在使用vw单位的情况下,1vw都等于视图宽度的百分之一
与百分比布局很相似,在以前文章提过与%的区别,这里就不再展开述说
rem
在以前也讲到,rem是相对于根元素html的font-size属性,默认情况下浏览器字体大小为16px,此时1rem = 16px
可以利用前面提到的媒体查询,针对不同设备分辨率改变font-size的值,如下:
@media screen and (max-width: 414px) {html {font-size: 18px}
}@media screen and (max-width: 375px) {html {font-size: 16px}
}@media screen and (max-width: 320px) {html {font-size: 12px}
}
为了更准确监听设备可视窗口变化,我们可以在css之前插入script标签,内容如下:
//动态为根元素设置字体大小
function init () {// 获取屏幕宽度var width = document.documentElement.clientWidth// 设置根元素字体大小。此时为宽的10等分document.documentElement.style.fontSize = width / 10 + 'px'
}//首次加载应用,设置一次
init()
// 监听手机旋转的事件的时机,重新设置
window.addEventListener('orientationchange', init)
// 监听手机窗口变化,重新设置
window.addEventListener('resize', init)
无论设备可视窗口如何变化,始终设置rem为width的1/10,实现了百分比布局
除此之外,我们还可以利用主流UI框架,如:element ui、antd提供的栅格布局实现响应式
小结
响应式设计实现通常会从以下几方面思考:
- 弹性盒子(包括图片、表格、视频)和媒体查询等技术
- 使用百分比布局创建流式布局的弹性UI,同时使用媒体查询限制元素的尺寸和内容变更范围
- 使用相对单位使得内容自适应调节
- 选择断点,针对不同断点实现不同布局和内容展示
12.说说em/px/rem/vh/vw区别?
一、介绍
传统的项目开发中,我们只会用到px、%、em这几个单位,它可以适用于大部分的项目开发,且拥有比较良好的兼容性
从CSS3开始,浏览器对计量单位的支持又提升到了另外一个境界,新增了rem、vh、vw、vm等一些新的计量单位
利用这些新的单位开发出比较良好的响应式页面,适应多种不同分辨率的终端,包括移动设备等
二、单位
在css单位中,可以分为长度单位、绝对单位,如下表所指示
CSS单位 | |
相对长度单位 | em、ex、ch、rem、vw、vh、vmin、vmax、% |
绝对长度单位 | cm、mm、in、px、pt、pc |
这里我们主要讲述px、em、rem、vh、vw
px
px,表示像素,所谓像素就是呈现在我们显示器上的一个个小点,每个像素点都是大小等同的,所以像素为计量单位被分在了绝对长度单位中
有些人会把px认为是相对长度,原因在于在移动端中存在设备像素比,px实际显示的大小是不确定的
这里之所以认为px为绝对单位,在于px的大小和元素的其他属性无关
em
em是相对长度单位。相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸(1em = 16px)
为了简化 font-size 的换算,我们需要在css中的 body 选择器中声明font-size= 62.5%,这就使 em 值变为 16px*62.5% = 10px
这样 12px = 1.2em, 10px = 1em, 也就是说只需要将你的原来的px 数值除以 10,然后换上 em作为单位就行了
特点:
- em 的值并不是固定的
- em 会继承父级元素的字体大小
- em 是相对长度单位。相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸
- 任意浏览器的默认字体高都是 16px
CSS单位 | |
相对长度单位 | em、ex、ch、rem、vw、vh、vmin、vmax、% |
绝对长度单位 | cm、mm、in、px、pt、pc |
这里我们主要讲述px、em、rem、vh、vw
rem
rem,相对单位,相对的只是HTML根元素font-size的值
同理,如果想要简化font-size的转化,我们可以在根元素html中加入font-size: 62.5%
html {font-size: 62.5%; } /* 公式16px*62.5%=10px */
这样页面中1rem=10px、1.2rem=12px、1.4rem=14px、1.6rem=16px;使得视觉、使用、书写都得到z极大的帮助
特点:
- rem单位可谓集相对大小和绝对大小的优点于一身
- 和em不同的是rem总是相对于根元素,而不像em一样使用级联的方式来计s算尺寸
vh、vw
vw ,就是根据窗口的宽度,分成100等份,100vw就表示满宽,50vw就表示一半宽。(vw 始终是针对窗口的宽),同理,vh则为窗口的高度
这里的窗口分成几种情况:
- 在桌面端,指的是浏览器的可视区域
- 移动端指的就是布局视口
像vw、vh,比较容易混淆的一个单位是%,不过百分比宽泛的讲是相对于父元素:
- 对于普通定位元素就是我们理解的父元素
- 对于position: absolute;的元素是相对于已定位的父元素
- 对于position: fixed;的元素是相对于 ViewPort(可视窗口)
三、总结
px:绝对单位,页面按精确像素展示
em:相对单位,基准点为父节点字体的大小,如果自身定义了font-size按自身来计算,整个页面内1em不是一个固定的值
rem:相对单位,可理解为root em, 相对根节点html的字体大小来计算
vh、vw:主要用于页面视口大小布局,在页面布局上更加方便简单
13.css中,有哪些方式可以隐藏页面元素?区别?
一、前言
在平常的样式排版中,我们经常遇到将某个模块隐藏的场景
通过css隐藏元素的方法有很多种,它们看起来实现的效果是一致的
但实际上每一种方法都有一丝轻微的不同,这些不同决定了在一些特定场合下使用哪一种方法
二、实现方式
通过css实现隐藏元素方法有如下:
- display:none
- visibility:hidden 隐藏了还是占据位置
- opacity:0 透明度
- 设置height、width模型属性为0
- position:absolute
- clip-path
display:none
设置元素的display为none是最常用的隐藏元素的方法
.hide {display:none;
}
将元素设置为display:none后,元素在页面上将彻底消失
元素本身占有的空间就会被其他元素占有,也就是说它会导致浏览器的重排和重绘
消失后,自身绑定的事件不会触发,也不会有过渡效果
特点:元素不可见,不占据空间,无法响应点击事件
visibility:hidden
设置元素的visibility为hidden也是一种常用的隐藏元素的方法
从页面上仅仅是隐藏该元素,DOM结果均会存在,只是当时在一个不可见的状态,不会触发重排,但是会触发重绘
.hidden{visibility:hidden
}
给人的效果是隐藏了,所以他自身的事件不会触发
特点:元素不可见,占据页面空间,无法响应点击事件
opacity:0
opacity属性表示元素的透明度,将元素的透明度设置为0后,在我们用户眼中,元素也是隐藏的
不会引发重排,一般情况下也会引发重绘
如果利用 animation 动画,对 opacity 做变化(animation会默认触发GPU加速),则只会触发 GPU 层面的 composite,不会触发重绘
需要注意的是:其子元素不能设置opacity来达到显示的效果
特点:改变元素透明度,元素不可见,占据页面空间,可以响应点击事件
设置height、width属性为0
将元素的margin,border,padding,height和width等影响元素盒模型的属性设置成0,如果元素内有子元素或内容,还应该设置其overflow:hidden来隐藏其子元素
.hiddenBox {margin:0; border:0;padding:0;height:0;width:0;overflow:hidden;
}
特点:元素不可见,不占据页面空间,无法响应点击事件
position:absolute
将元素移出可视区域
.hide {position: absolute;top: -9999px;left: -9999px;
}
特点:元素不可见,不影响页面布局
clip-path
通过裁剪的形式
.hide {clip-path: polygon(0px 0px,0px 0px,0px 0px,0px 0px);
}
特点:元素不可见,占据页面空间,无法响应点击事件
小结
最常用的还是display:none和visibility:hidden,其他的方式只能认为是奇招,它们的真正用途并不是用于隐藏元素,所以并不推荐使用它们
三、区别
关于display: none、visibility: hidden、opacity: 0的区别,如下表所示:
display: none | visibility: hidden | opacity: 0 | |
页面中 | 不存在 | 存在 | 存在 |
重排 | 会 | 不会 | 不会 |
重绘 | 会 | 会 | 不一定 |
自身绑定事件 | 不触发 | 不触发 | 可触发 |
transition | 不支持 | 支持 | 支持 |
子元素可复原 | 不能 | 能 | 不能 |
被遮挡的元素可触发事件 | 能 | 能 | 不能 |
14.DOM常见的操作有哪些?
一、DOM
文档对象模型 (DOM) 是 HTML 和 XML 文档的编程接口
它提供了对文档的结构化的表述,并定义了一种方式可以使从程序中对该结构进行访问,从而改变文档的结构,样式和内容
任何 HTML或XML文档都可以用 DOM表示为一个由节点构成的层级结构
节点分很多类型,每种类型对应着文档中不同的信息和(或)标记,也都有自己不同的特性、数据和方法,而且与其他类型有某种关系,如下所示:
<html><head><title>Page</title></head><body><p>Hello World!</p ></body>
</html>
DOM像原子包含着亚原子微粒那样,也有很多类型的DOM节点包含着其他类型的节点。接下来我们先看看其中的三种:
<div><p title="title">content</p >
</div>
上述结构中,div、p就是元素节点,content就是文本节点,title就是属性节点
二、操作
日常前端开发,我们都离不开DOM操作
在以前,我们使用Jquery,zepto等库来操作DOM,之后在vue,Angular,React等框架出现后,我们通过操作数据来控制DOM(绝大多数时候),越来越少的去直接操作DOM
但这并不代表原生操作不重要。相反,DOM操作才能有助于我们理解框架深层的内容
下面就来分析DOM常见的操作,主要分为:
- 创建节点
- 查询节点
- 更新节点
- 添加节点
- 删除节点
创建节点
createElement
创建新元素,接受一个参数,即要创建元素的标签名1
const divEl = document.createElement("div");
createTextNode
创建一个文本节点
const textEl = document.createTextNode("content");
createDocumentFragment
用来创建一个文档碎片,它表示一种轻量级的文档,主要是用来存储临时节点,然后把文档碎片的内容一次性添加到DOM中
const fragment = document.createDocumentFragment();
当请求把一个DocumentFragment 节点插入文档树时,插入的不是 DocumentFragment自身,而是它的所有子孙节点
createAttribute
创建属性节点,可以是自定义属性
const dataAttribute = document.createAttribute('custom');
consle.log(dataAttribute);
获取节点
querySelector
传入任何有效的css 选择器,即可选中单个 DOM元素(首个):
document.querySelector('.element')
document.querySelector('#element')
document.querySelector('div')
document.querySelector('[name="username"]')
document.querySelector('div + p > span')
如果页面上没有指定的元素时,返回 null
querySelectorAll
返回一个包含节点子树内所有与之相匹配的Element节点列表,如果没有相匹配的,则返回一个空节点列表
const notLive = document.querySelectorAll("p");
需要注意的是,该方法返回的是一个 NodeList的静态实例,它是一个静态的“快照”,而非“实时”的查询
关于获取DOM元素的方法还有如下,就不一一述说
document.getElementById('id属性值');返回拥有指定id的对象的引用
document.getElementsByClassName('class属性值');返回拥有指定class的对象集合
document.getElementsByTagName('标签名');返回拥有指定标签名的对象集合
document.getElementsByName('name属性值'); 返回拥有指定名称的对象结合
document/element.querySelector('CSS选择器'); 仅返回第一个匹配的元素
document/element.querySelectorAll('CSS选择器'); 返回所有匹配的元素
document.documentElement; 获取页面中的HTML标签
document.body; 获取页面中的BODY标签
document.all['']; 获取页面中的所有元素节点的对象集合型
除此之外,每个DOM元素还有parentNode、childNodes、firstChild、lastChild、nextSibling、previousSibling属性,关系图如下图所示
更新节点
innerHTML
不但可以修改一个DOM节点的文本内容,还可以直接通过HTML片段修改DOM节点内部的子树
// 获取<p id="p">...</p >
var p = document.getElementById('p');
// 设置文本为abc:
p.innerHTML = 'ABC'; // <p id="p">ABC</p >
// 设置HTML:
p.innerHTML = 'ABC <span style="color:red">RED</span> XYZ';
// <p>...</p >的内部结构已修改
innerText、textContent
自动对字符串进行HTML编码,保证无法设置任何HTML标签
// 获取<p id="p-id">...</p >
var p = document.getElementById('p-id');
// 设置文本:
p.innerText = '<script>alert("Hi")</script>';
// HTML被自动编码,无法设置一个<script>节点:
// <p id="p-id"><script>alert("Hi")</script></p >
两者的区别在于读取属性时,innerText不返回隐藏元素的文本,而textContent返回所有文本
style
DOM节点的style属性对应所有的CSS,可以直接获取或设置。遇到-需要转化为驼峰命名
// 获取<p id="p-id">...</p >
const p = document.getElementById('p-id');
// 设置CSS:
p.style.color = '#ff0000';
p.style.fontSize = '20px'; // 驼峰命名
p.style.paddingTop = '2em';
添加节点
innerHTML
如果这个DOM节点是空的,例如,<div></div>,那么,直接使用innerHTML = '<span>child</span>'就可以修改DOM节点的内容,相当于添加了新的DOM节点
如果这个DOM节点不是空的,那就不能这么做,因为innerHTML会直接替换掉原来的所有子节点
appendChild
把一个子节点添加到父节点的最后一个子节点
举个例子
<!-- HTML结构 -->
<p id="js">JavaScript</p >
<div id="list"><p id="java">Java</p ><p id="python">Python</p ><p id="scheme">Scheme</p >
</div>
添加一个p元素
const js = document.getElementById('js')
js.innerHTML = "JavaScript"
const list = document.getElementById('list');
list.appendChild(js);
现在HTML结构变成了下面
<!-- HTML结构 -->
<div id="list"><p id="java">Java</p ><p id="python">Python</p ><p id="scheme">Scheme</p ><p id="js">JavaScript</p > <!-- 添加元素 -->
</div>
上述代码中,我们是获取DOM元素后再进行添加操作,这个js节点是已经存在当前文档树中,因此这个节点首先会从原先的位置删除,再插入到新的位置
如果动态添加新的节点,则先创建一个新的节点,然后插入到指定的位置
const list = document.getElementById('list'),
const haskell = document.createElement('p');
haskell.id = 'haskell';
haskell.innerText = 'Haskell';
list.appendChild(haskell);
insertBefore
把子节点插入到指定的位置,使用方法如下:
parentElement.insertBefore(newElement, referenceElement)
子节点会插入到referenceElement之前
setAttribute
在指定元素中添加一个属性节点,如果元素中已有该属性改变属性值
const div = document.getElementById('id')
div.setAttribute('class', 'white');//第一个参数属性名,第二个参数属性值。
删除节点
删除一个节点,首先要获得该节点本身以及它的父节点,然后,调用父节点的removeChild把自己删掉
// 拿到待删除节点:
const self = document.getElementById('to-be-removed');
// 拿到父节点:
const parent = self.parentElement;
// 删除:
const removed = parent.removeChild(self);
removed === self; // true
15.什么是重绘,什么是回流?如何减少回流?
重绘(Repaint):
重绘是指当元素样式发生改变,但不影响布局的情况下,浏览器重新绘制元素的过程。例如,修改元素的背景颜色、字体颜色等。
回流(Reflow):
回流是指当元素的布局属性发生改变,需要重新计算元素在页面中的布局位置时,浏览器重新进行布局的过程。例如,修改元素的宽度和高度,定位等
回流的成本比重绘高得多,因为回流涉及重新计算元素的几何属性和页面布局。而重绘只需要重新绘制已经计算好元素的样式。
如何减少:
- 使用visibility:hidden替代display:none:visibility:hidden不会触发回流,因为元素隐藏之后,还占据页面空间。而使用display:none元素隐藏之后,不占用页面空间,会将元素从渲染树中移除,从而引起回流
- 避免频繁操作元素的布局样式属性:当需要对元素进行多次样式修改时,可以考虑将这些修改合并为一次操作。
- 让元素脱离文档流:position:absolute/position:fixed/float:left(只是减少回流,不是避免回流)
16.三栏布局的实现方式(圣杯模型)
三栏布局是一种常见的网页布局方式,通常包括一个固定宽度的左侧栏,一个固定宽度的右侧栏以及一个自适应宽度的主要内容区域
Flex布局
浮动布局
绝对定位布局
17.calc()方法
calc() 是CSS中的一个函数,用于动态计算样式属性的值。calc() 主要解决以下问题:
响应式布局:calc() 可以根据不同的屏幕尺寸和视口大小,动态调整元素的尺寸或间距,以实现响应式布局。
动态尺寸调整:calc()可以用于根据其他元素的尺寸或动态内容的大小来计算元素的尺寸。这在构建复杂的布局时非常有用。
优化代码:calc()可减少不必要的CSS代码和样式属性的编码,以实现更灵活,可维护和自适应的布局。