janessasmith / frontend-interview-questions Goto Github PK
View Code? Open in Web Editor NEW前端面试相关汇总
前端面试相关汇总
解决办法:var mx = event.x ? event.x : event.pageX;
1. CSS处理:
p {
width: 300px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
方法一:WebKit浏览器或移动端的页面
在WebKit浏览器或移动端(绝大部分是WebKit内核的浏览器)的页面实现比较简单,可直接使用WebKit的CSS扩展属性(WebKit是私有属性)-webkit-line-clamp ;
注意:这是一个 不规范的属性(unsupported WebKit property),它没有出现在 CSS 规范草案中。
-webkit-line-clamp用来限制在一个块元素显示的文本的行数。 为了实现该效果,它需要组合其他的WebKit属性。常见结合属性:
p {
overflow: hidden;
display: -webkit-box;
text-overflow:ellipsis;
-webkit-line-clamp:2;
-webkit-box-orient: vertical
}
方案二:跨浏览器兼容的方案
比较靠谱简单的做法就是设置相对定位的容器高度,用包含省略号(…)的元素模拟实现。
p {
position: relative;
line-height: 1.4em;
height: 4.2em;
overflow: hidden;
}
p::after {
content:"...";
position: absolute;
right:0;
bottom: 0;
background: url(....)repeat-y;
}
这里注意几点:
2. JS处理:
方法一:自己写
<p>这是一段测试文字,this is some test text,测试文字,测试文字测 </p>
const p = document.querySelector('p')
let words = p.innerHTML.split(/(?<=[\u4e00-\u9fa5])|(?<=\w*?\b)/g)
while (p.scrollHeight > p.clientHeight) {
words.pop()
p.innerHTML = words.join('') + '...'
}
方法二:使用第三方插件
var module = document.getElementById('clamp-this-module');
$clamp(module,{clamp:3});
$(document).ready(function(){
$('#wrapper').dotdotdot({
......
});
});
typeof 是否能正确判断类型?instanceof 能正确判断对象的原理是什么?
JS中会使用typeof 和 instanceof来判断一个变量是否为空或者是什么类型的。
typeof 对于原始类型来说,除了 null 都可以显示正确的类型
typeof 1 // "number"
typeof NaN // "number"
typeof '1' // "string"
typeof undefined // "undefined"
typeof true // "boolean"
typeof Symbol() // "symbol"
typeof 对于对象来说,除了函数都会显示 object,所以说 typeof 并不能准确判断变量到底是什么类型
typeof [] // "object"
typeof {} // "object"
typeof console.log // "function"
typeof Math.abs // "function"
如上所示,引用类型的数据,都返回了object,我们无法做到精确判断。我们总结一下:
我们可以使用 typeof 来获取一个变量是否存在,如
if(typeof a === 'undefined') {
console.log('error'); // error
}
if(!a) {
console.log('error'); // 控制台报错:Uncaught ReferenceError: a is not defined
}
而不要去使用 if(a) 因为如果 a 不存在(undefined)则会出错。具体可看如何判断Javascript对象是否存在。
说明:
总结:
如果我们想判断一个对象的正确类型,这时候可以考虑使用 instanceof,因为内部机制是通过原型链来判断的。并且instanceof 也可以用来判断一个变量是否是某个对象的实例。(包含检测是否具有继承关系父类子类关系之类的),具体可看instanceof。
表达式为:A instanceof B,如果 A 是 B 的实例,则返回 true,否则返回 false。
例1:
const Person = function() {};
const p1 = new Person();
p1 instanceof Person; // true
var str = 'hello world';
str instanceof String; // false
var str1 = new String('hello world');
str1 instanceof String; // true
例2:
var a=new Array();
a instanceof Array; // true
a instanceof Object; // true,也会返回true,因为 Array 是 object 的子类
例3:
function test(){};
var a=new test();
a instanceof test; //true
a instanceof Function; //false
例4:
var a = function test(){};
a instanceof Function; //true
这跟声明的对象是是什么对象有关系,在例3中,a是new出来的一个test实例,说明了test创建了一个包装对象a,而包装对象实例化出来的是对象类型(这里是test对象),而不是Function类型,而例4则是通过function声明的一个对象,并不是包装对象,因此它自然就继承了Function,是Function类型的实例。
说明:
还有一个不错的判断类型的方法,就是Object.prototype.toString,我们可以利用这个方法来对一个变量的类型来进行比较准确的判断。
Object.prototype.toString.call(1) // "[object Number]"
Object.prototype.toString.call('hi') // "[object String]"
Object.prototype.toString.call({a:'hi'}) // "[object Object]"
Object.prototype.toString.call([1,'a']) // "[object Array]"
Object.prototype.toString.call(true) // "[object Boolean]"
Object.prototype.toString.call(() => {}) // "[object Function]"
Object.prototype.toString.call(null) // "[object Null]"
Object.prototype.toString.call(undefined) // "[object Undefined]"
Object.prototype.toString.call(Symbol(1)) // "[object Symbol]"
var arr = [1, 2];
arr.toString(); // "1,2"
Object.prototype.toString.call(arr); // "[object Array]"
"foo".toString(); // "foo"
1.toString(); // Uncaught SyntaxError: Invalid or unexpected token
true.toString(); // "true"
undefined.toString(); // Uncaught TypeError: Cannot read property 'toString' of undefined
null.toString(); // Uncaught TypeError: Cannot read property 'toString' of null
String.toString(); // "function String() { [native code] }"
Number.toString(); // "function Number() { [native code] }"
Boolean.toString(); // "function Boolean() { [native code] }"
Array.toString(); // "function Array() { [native code] }"
Function.toString(); // "function Function() { [native code] }"
Date.toString(); // "function Date() { [native code] }"
RegExp.toString(); // "function RegExp() { [native code] }"
Error.toString(); // "function Error() { [native code] }"
Promise.toString(); // "function Promise() { [native code] }"
Object.toString(); // "function Object() { [native code] }"
Math.toString(); // "[object Math]"
toString()是能将某一个值转化为字符串的方法。
例1:将boolean类型的值转化为string类型
true.toString(); // "true"
false.toString(); // "false"
例2:将string类型按其字面量形式输出
var str = "abc";
str.toString(); // "abc"
例3:将Object类型转化成string类型(JavaScript原生的Array类型、Date类型、RegExp类型以及Number、Boolean、String这些包装类型都是Object的子类型)
没有重新定义toString()方法:
例1:Object类型
var obj = {name: "test", age: 18};
obj.toString(); // "[object Object]" 此时调用的是从Object继承来的原始的toString()方法
重新定义toString()方法:
例1:Array类型
var arr = ["test", 12, "hello", 18];
arr.toString(); // "test,12,hello,18"
例2:RegExp类型
var patten = new RegExp("\\[hbc\\]at", "gi");
patten.toString(); // "/\[hbc\]at/gi"
例3:Date类型
var date = new Date(2014,02,26);//注意这种格式创建的日期,其月份是3月
date.toString(); // "Wed Mar 26 2014 00:00:00 GMT+0800 (**标准时间)" 输出格式因浏览器不同而不同,此为chrome的输出格式;
例3:Number类型
var num = 16;
num.toString(); // "16" 参数不填默认就是十进制,和 num.toString(10);一样
num.toString(2); // "10000" 二进制
num.toString(8); // "20" 八进制
num.toString(16); // "10" 十六进制
num.toString(5); // "31" 虽然没有五进制,但是这样传参是可以被toString()方法接受的
说明:
typeof和instanceof的目的都是检测变量的类型,两个的区别在于typeof一般是检测的是基本数据类型,instanceof主要检测的是引用类型。
例1:
var a=new Array();
if (a instanceof Object) {
alert('Y'); // 结果是:Y
} else {
alert('N');
}
例2:
if (window instanceof Object) {
alert('Y');
} else {
alert('N'); // 结果是:N
}
这里的 instanceof 测试的 object 是指 js 语法中的 object,不是指 dom 模型对象。
总结
判断类型主要有4个方法:
1. 水平居中
只需要把行内元素包裹在一个属性 display 为 block 的父层元素中,并且把父层元素添加如下属性即可。
<div class="parent">
<span>这是一个被父元素parent包裹的行内元素span标签</span>
</div>
.parent {
text-align: center;
}
只需给需要居中的块级元素加margin: 0 auto; 即可,但这里需要注意的是,这里块状元素的宽度width值一定要有。
.item {
/* 这里可以设置顶端外边距 */
margin: 0 auto;
}
不定宽,即块级元素宽度不固定。
方法一:display: table
通过给要居中显示的元素,设置display: table;,然后设置margin:0 auto;来实现。
.item {
display: table;
margin: 0 auto;
}
方法二:display: inline-block(多个块状元素)
将元素的 display 属性设置为 inline-block,并且把父元素的 text-align 属性设置为 center 即可。
<div class="parent">
<div class="item">这是一个被父元素parent包裹的块状元素1</div>
<div class="item">这是一个被父元素parent包裹的块状元素2</div>
</div>
.parent {
text-align: center;
}
.item {
display: inline-block;
}
方法三:flex布局(多个块状元素)
只需把要处理的块状元素的父元素设置display: flex, justify-content:center。
<div class="parent">
<div class="item">这是一个被父元素parent包裹的块状元素1</div>
<div class="item">这是一个被父元素parent包裹的块状元素2</div>
</div>
.parent {
display: flex;
justify-content: center;
}
方法四:position + 负margin
方法五:position + margin: auto
方法六:position + transform
注:这里方法四、五、六同下面垂直居中一样的道理,只不过需要把top/bottom改为left/right,在垂直居中部分会详细讲述。
2. 垂直居中
解决方案一:适用于单行文本
解决方案二:适用于多行文本
通过设置父元素display: table,子元素display: table-cell和vertical-align: middle。
<div class="parent">
<div class="item">这是一个被父元素parent包裹的块状元素</div>
</div>
.parent {
display: table;
width: 300px;
height: 300px;
}
.item {
display: table-cell;
vertical-align: middle;
}
方法一: flex布局
在需要垂直居中的父元素上,设置display: flex 和 align-items: center。
要求:父元素必须显示设置 height 值。
.parent {
display: flex;
align-items: center;
width: 300px;
height: 300px;
}
方法二: 利用position和top和负margin(需知宽高)
.parent {
position: relative;
width: 300px;
height: 300px;
}
.item {
position: absolute;
top: 50%;
margin-top: -50px; /* 设置margin-top 为自身高度的一半 */
width: 100px;
height: 100px;
}
方法三: 利用position和top/bottom和margin:auto(注意不是margin:0 auto)(需知宽高)
.parent {
position: relative;
width: 300px;
height: 300px;
}
.item {
position: absolute;
top: 0;
bottom: 0;
margin: auto;
width: 100px;
height: 100px;
}
方法四: 利用position和top和transform(不需知宽高)
transform中translate偏移的百分比就是相对于元素自身的尺寸而言的。
.parent {
position: relative;
width: 300px;
height: 300px;
}
.item {
position: absolute;
top: 50%;
transform: translate(0, -50%);
}
2. 垂直水平居中
这是一种不常见的居中方法,可自适应,比方案二更智能。
.parent {
position: relative;
width: 300px;
height: 300px;
}
.item {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
width: 100px;
height: 100px;
}
.parent {
position: relative;
width: 300px;
height: 300px;
}
.item {
position: absolute;
top: 50%;
left: 50%;
margin-top: -50px; /* 设置margin-left / margin-top 为自身高度的一半 */
margin-left: -50px;
width: 100px;
height: 100px;
}
.parent {
position: relative;
width: 300px;
height: 300px;
}
.item {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.parent {
display: flex;
justify-content: center;
align-items: center;
/* 注意这里需要设置宽度和高度来查看垂直水平居中效果 */
width: 300px;
height: 300px;
}
其实这个是很常见的一道考题,两栏布局方案。
当然可以延伸出很多考题,譬如左侧宽度自适应,右侧宽度固定?三栏布局(左右宽度固定,中间宽度自适应)等问题。
总结一下左侧宽度固定,右侧宽度自适应的两栏布局的八种方法。其中有老生常谈的float方法,BFC方法,也有CSS3 的 flex 布局与 grid 布局。
就两栏布局,举个栗子:
<div class="container">
<div class="left">
<p>这是左边的盒子</p>
</div>
<div class="right">
<p>这是右边的盒子</p>
</div>
</div>
.container {
border: 1px solid yellow;
}
.left {
width: 120px; /* 左侧宽度固定为120px */
border: 1px solid red;
}
.right {
border: 1px solid blue;
}
.container {
box-sizing: content-box;
font-size: 0; /*消除空格的影响*/
}
.left, .right {
display: inline-block;
vertical-align: top; /*顶端对齐*/
font-size: 14px;
box-sizing: border-box;
}
.right {
width: calc(100% - 120px);
}
这种方法是通过width: calc(100% - 120px)来动态计算右侧盒子的宽度。需要知道右侧盒子距离左边的距离,以及左侧盒子具体的宽度(content+padding+border),以此计算父容器宽度的100%需要减去的数值。同时,还需要知道右侧盒子的宽度是否包含border的宽度。 在这里,为了简单的计算右侧盒子准确的宽度,设置了子元素的box-sizing:border-box;以及父元素的box-sizing: content-box;。 同时,作为两个inline-block的盒子,必须设置vertical-align来使其顶端对齐。 另外,为了准确地应用计算出来的宽度,需要消除div之间的空格,需要通过设置父容器的font-size: 0;,或者用注释消除html中的空格等方法。
缺点:
1. 需要知道左侧盒子的宽度,两个盒子的距离,还要设置各个元素的box-sizing;
2. 需要消除空格字符的影响;
3. 需要设置vertical-align: top满足顶端对齐。
.container {
overflow: auto; /*清除浮动*/
box-sizing: content-box;
}
.left, .right {
float: left;
box-sizing: border-box;
}
.right {
width: calc(100% - 120px);
}
本方案和双inline-block方案原理相同,都是通过动态计算宽度来实现自适应。但是,由于浮动的block元素在有空间的情况下会依次紧贴,排列在一行,所以无需设置display: inline-block;,自然也就少了顶端对齐,空格字符占空间等问题。不过由于应用了浮动,父元素需要清除浮动。
缺点:
1. 需要知道左侧盒子的宽度,两个盒子的距离,还要设置各个元素的box-sizing;
2. 父元素需要清除浮动。
.container {
overflow: hidden;
}
.left {
float: left;
width: 120px;
}
.right {
margin-left: 120px; /*margin的值 = 固定宽度*/
}
上面两种方案都是利用了CSS的calc()函数来计算宽度值。下面两种利用了block级别的元素盒子的宽度具有填满父容器,并随着父容器的宽度自适应的流动特性。 但是block级别的元素都是独占一行的,所以要想办法让两个block排列到一起。 我们知道,block级别的元素会认为浮动的元素不存在,但是inline级别的元素能识别到浮动的元素。这样,block级别的元素就可以和浮动的元素同处一行了。 为了让右侧盒子和左侧盒子保持距离,需要为左侧盒子留出足够的距离。这个距离的大小为左侧盒子的宽度以及两个盒子之间的距离之和。然后将该值设置为右侧盒子的margin-left。
缺点:
1. 需要清除浮动;
2. 需要计算右侧盒子的margin-left;
3. html 中 left 必须在 right 之前(其实就是浮动的元素必须在前)。
.container {
position: relative;
}
.left {
position: absolute;
top: 0;
left: 0;
width: 120px;
}
.right {
margin-left: 120px; /*margin的值 = 固定宽度*/
}
缺点:
1. 使用了绝对定位,若是用在某个div中,需要更改父容器的position;
2. 没有清除浮动的方法,若左侧盒子高于右侧盒子,就会超出父容器的高度。因此只能通过设置父容器的min-height来放置这种情况。
上面的方法都需要通过左侧盒子的宽度,计算某个值,下面四种方法都是不需要计算的。只需要设置两个盒子之间的间隔。
.container {
}
.left {
float: left
width: 120px;
}
.right {
overflow: hidden;
}
这个方案同样是利用了左侧浮动,但是右侧盒子通过overflow: auto;形成了BFC,因此右侧盒子不会与浮动的元素重叠。
这种情况下,只需要为左侧的浮动盒子设置margin-right,就可以实现两个盒子的距离了。而右侧盒子是block级别的,所以宽度能实现自适应。
缺点:
父元素需要清除浮动。
方案六:table
.container {
display: table;
width: 100%;
}
.left {
display: table-cell;
width: 120px;
}
.right {
display: table-cell;
}
缺点:
IE7 及以下都无效的方法。
.container {
display: flex;
align-items: flex-start;
}
.left {
flex: 0 0 auto;
width: 120px;
}
.right {
flex: 1 1 auto;
}
flex可以说是最好的方案了,代码少,使用简单。有朝一日,大家都改用现代浏览器,就可以使用了。
注意:flex容器的一个默认属性值:align-items: stretch;。这个属性导致了列等高的效果。 为了让两个盒子高度自动,需要设置: align-items: flex-start;。
又一个新型的布局方式。可以满足需求,但这并不是它发挥用处的真正地方。
.container {
display: grid;
grid-template-columns: 120px 1fr;
align-items: start;
}
.left, .right {
box-sizing: border-box;
}
.left {
grid-column: 1;
}
.right {
grid-column: 2;
}
注意:
1. grid布局也有列等高的默认效果。需要设置: align-items: start;;
2. grid布局还有一个值得注意的小地方和flex不同:在使用margin-left的时候,grid布局默认是box-sizing设置的盒宽度之间的位置。而flex则是使用两个div的border或者padding外侧之间的距离。
position
具体可查看:sticky你了解多少
position: relative 和 position: absolute 区别:
float
什么叫替换元素 ?根据元素本身的特点定义的, (X)HTML中的 img、input、textarea、select、object 都是替换元素,这些元素都没有实际的内容。 (X)HTML 的大多数元素是不可替换元素,他们将内容直接告诉浏览器,将其显示出来。
display
表现出来的区别就是 block 独占一行,在浏览器中通常垂直布局,可以用 margin 来控制块级元素之间的间距(存在 margin 合并的问题,只有普通文档流中块框的垂直外边距才会发生外边距合并。行内框、浮动框或绝对定位之间的外边距不会合并。),而 inline 以水平方式布局,垂直方向的 margin 和 padding 都是无效的,大小跟内容一样,且无法设置宽高。
inline 就像塑料袋,内容怎么样,就长得怎么样;block 就像盒子,有固定的宽和高。
定位机制
上面三个属性都属于 CSS 定位属性。CSS 三种基本的定位机制:普通流、浮动、绝对定位。
因为浏览器的兼容问题,不同浏览器对有些标签的默认值是不同的,如果没对 CSS 初始化往往会出现浏览器之间的页面显示差异。
初始化样式会对 SEO 有一定的影响,但鱼和熊掌不可兼得,但力求影响最小的情况下初始化。
初始化 CSS 样式例子:
html, body { padding: 0; margin: 0; } ...
transform: rotate(9deg) scale(0.85,0.90) translate(0px,-30px) skew(-9deg,0deg);
一个块级元素如果没有设置 height,那么其高度就是由里面的子元素撑开,如果子元素使用浮动,脱离了标准的文档流,那么父元素的高度会将其忽略,如果不清除浮动,父元素会出现高度不够,那样如果设置 border 或者 background 都得不到正确的解析。
正是因为浮动的这种特性,导致本属于普通流中的元素浮动之后,包含框内部由于不存在其他普通流元素了,也就表现出高度为 0(高度塌陷)。在实际布局中,往往这并不是我们所希望的,所以需要闭合浮动元素,使其包含框表现出正常的高度。
清除浮动的方式
总结:比较好的是倒数第 2 种方式,简洁方便。
最新的 ECMAScript 标准定义了 8 种数据类型:
7 种原始类型:
1 种对象类型
BigInt 和 Symbol,具体可看从ES6到ES10的新特性万字大总结。
原始类型和对象类型的说明:
原始值:是除 Object 以外的所有类型都是不可变的(值本身无法被改变)。例如,与 C 语言不同,JavaScript 中字符串是不可变的(译注:如,JavaScript 中对字符串的操作一定返回了一个新字符串,原始字符串并没有被改变)。我们称这些类型的值为“原始值”。
原始类型存储的都是值,是没有函数可以调用的,比如 undefined.toString()。
此时你肯定会有疑问,这不对呀,明明 '1'.toString() 是可以使用的。其实在这种情况下,'1' 已经不是原始类型了,而是被强制转换成了 String 类型也就是对象类型,所以可以调用 toString 函数。
除了会在必要的情况下强转类型以外,原始类型还有一些坑。
其中 JS 的 number 类型是浮点类型的,在使用中会遇到某些 Bug,比如 0.1 + 0.2 !== 0.3,但是这一块的内容会在进阶部分讲到。string 类型是不可变的,无论你在 string 类型上调用何种方法,都不会对值有改变。
另外对于 null 来说,很多人会认为他是个对象类型,其实这是错误的。虽然 typeof null 会输出 object,但是这只是 JS 存在的一个悠久 Bug。在 JS 的最初版本中使用的是 32 位系统,为了性能考虑使用低位存储变量的类型信息,000 开头代表是对象,然而 null 表示为全零,所以将它错误的判断为 object 。虽然现在的内部类型判断代码已经改变了,但是对于这个 Bug 却是一直流传下来。
对象类型:在 JS 中,除了原始类型那么其他的都是对象类型了。对象类型和原始类型不同的是,原始类型存储的是值,对象类型存储的是地址(指针)。当你创建了一个对象类型的时候,计算机会在内存中帮我们开辟一个空间来存放值,但是我们需要找到这个空间,这个空间会拥有一个地址(指针)。
考题1:
function test(person) {
person.age = 26;
person = {
name: 'janessa',
age: 30
}
return person;
}
const p1 = {
name: 'smith',
age: 25
}
const p2 = test(p1);
console.log(p1); // -> ?
console.log(p2); // -> ?
考题2:
function test(person) {
person = {
name: 'janessa',
age: 30
}
person.age = 26;
return person;
}
const p1 = {
name: 'smith',
age: 25
}
const p2 = test(p1);
console.log(p1); // -> ?
console.log(p2); // -> ?
BFC 就是块级格式上下文,是页面盒模型布局中的一种 CSS 渲染模式,相当于一个独立的容器,里面的元素和外部的元素相互不影响。
创建 BFC 的方式有:
BFC 主要的作用是:
BFC 特性:
CSS 盒子模型具有内容 (content)、填充 (padding)、边框 (border)、边界 (margin)这些属性。
我们所说的 width,height 指的是内容 (content) 的宽高。
一个盒子模型的中:
可详看:CSS盒模型完整介绍
这三者的区别(不同点)是:
1. 空间占据
2. 株连性
3. 回流与重绘
4. 过渡动画 transition 支持度
空间占据:
株连性:
回流与重绘:
过渡动画 transition 支持度
扩展问题:用 CSS 隐藏页面上的一个元素有哪几种方法?
这道题绝大多数人的答案都是 display: none; visibility: hiden; opacity: 0; 这三种,但如果还能说出下面三种我觉得也是加分的:
行内元素:
其中 a, img, button, input, label, select, textarea, b, i标签使用最多。
块级元素:
空元素:area, base, br, col, colgroup, command, embed, hr, img, input, keygen, link, meta, param, source, track, wbr。
解释:
CSS规范规定,每个元素都有display属性,确定该元素的类型,每个元素都有默认的display值,如div的display默认值为“block”,则为“块级”元素;span默认display属性值为“inline”,是“行内”元素。
行内元素的margin、padding可设置吗?
CSS 选择符:
可继承的样式:
不可继承的样式:
事实上,宽度也不是继承的,而是如果你不指定宽度,那么它就是 100%。由于你子 DIV 并没有指定宽度,那它就是 100%,也就是与父 DIV 同宽,但这与继承无关,高度自然也没有继承一说。
优先级算法:
CSS3新增伪类:
元素;
元素;
元素;
元素;
元素;
何时应当使用 margin
如 15px + 20px 的 margin,将得到 20px 的空白。
何时应当时用 padding
如 15px + 20px 的 padding,将得到 35px 的空白。
个人认为:margin 是用来隔开元素与元素的间距;padding 是用来隔开元素与内容的间隔,让内容(文字)与(包裹)元素之间有一段 呼吸距离。
rem
这个单位可谓集相对大小和绝对大小的优点于一身,通过它既可以做到只修改根元素就成比例地调整所有字体大小,又可以避免字体大小逐层复合的连锁反应。
目前,除了 IE8 及更早版本外,所有浏览器均已支持 rem。对于不支持它的浏览器,应对方法也很简单,就是多写一个绝对单位的声明。这些浏览器会忽略用 rem 设定的字体大小。
em
所有未经调整的浏览器一般都符合: 1em = 16px。那么 12px = 0.75em,10px = 0.625em。
为了简化 font-size 的换算,需要在 css 中的 body 选择器中声明 Fontsize = 62.5%,这就使 em 值变为 16px*62.5% = 10px, 这样 12px = 1.2em, 10px = 1em, 也就是说只需要将你的原来的 px 数值除以 10,然后换上 em 作为单位就行了。
px
px 像素(Pixel)。相对长度单位。像素 px 是相对于显示器屏幕分辨率而言的。
vh 与 vw
视口
vh / vw 与 %介绍
比如:浏览器视口尺寸为 370px,那么 1vw = 370px * 1% = 6.5px (浏览器会四舍五入向下取 7)。
vh / vw 与 % 区别
不过由于 vw 和 vh 是 css3 才支持的长度单位,所以在不支持 css3 的浏览器中是无效的。
开发中可能会遇到:一连串的inline-block元素(块状元素设置了display: inline-block; 或 本身是行内元素)在格式化HTML 之后会出现间隔。
举个栗子:
<ul>
<li><a href="#">导航1</a></li>
<li><a href="#">导航2</a></li>
<li><a href="#">导航3</a></li>
</ul>
ul li {
display: inline-block;
}
最后会发现 li 之间 总会有间隙,当然这不是个bug,解决方法如下:
解决方案一:移除空格(不推荐)
之所以显示时看到空格是因为本来就有空格在两个元素之间(换行和一些tabs都会视为空格,它们仅仅是让结构更加清晰)。从HTML结构入手可以解决这问题,下面是一些处理的技巧:
<ul>
<li><a href="#">导航1</a></li><li>
<a href="#">导航2</a></li><li>
<a href="#">导航3</a></li>
</ul>
或者
<ul>
<li><a href="#">导航1</a></li
><li><a href="#">导航2</a></li
><li><a href="#">导航3</a></li>
</ul>
又或者添是加注释的方式
<ul>
<li><a href="#">导航1</a></li><!--
--><li><a href="#">导航2</a></li><!--
--><li><a href="#">导航3</a></li>
</ul>
移除空格方法虽然简单,但也不是很推荐,会让html没有那么易读,而且复杂布局不太实用。
解决方案二:跳过闭合标签(不推荐)
在HTML5 下跳过闭合标签依然能正常工作。虽然可以这么做,但低版本浏览器还是需要考虑一下,不推荐这么做。
<ul>
<li><a href="#">导航1</a>
<li><a href="#">导航2</a>
<li><a href="#">导航3</a>
</ul>
解决方案三:设置margin值为负值
可以通过设置负值的margin让元素回退将空格位置占满(具体数值需要根据父元素的字体大小来调整)。不过这种方式在比较老的IE浏览器(6 & 7)中会有些问题,如果你不需要考虑那些浏览器,就可以用这种方法避免显示的空格,又能保持清晰的HTML结构。
ul li {
display: inline-block;
margin-left: -6px;
}
说明:margin负值的大小与上下文的字体和文字大小相关。
解决方案四:使用font size: 0
ul {
font-size: 0;
}
ul li {
font-size: 14px;
}
这个方法,基本上可以解决大部分浏览器下inline-block元素之间的间距(IE7等浏览器有时候会有1像素的间距)。不过有个浏览器,就是Chrome, 其默认有最小字体大小限制,因为,考虑到兼容性,我们还需要添加:
ul {
font-size: 0;
-webkit-text-size-adjust: none;
}
解决方案五:使用letter-spacing
ul {
letter-spacing: -6px;
}
ul li {
letter-spacing: 0;
}
解决方案六:使用word-spacing
ul {
word-spacing: -6px;
}
ul li {
word-spacing: 0;
}
解决方案七:使用float
将display: inline-block; 改为 display: block; 同时让元素左浮动 float: left;。
ul li {
display: block;
float: left;
}
最佳方案:推荐使用方案七。
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.