lennonover


  • 首页

  • 归档

  • 标签

JS类型检测

发表于 2017-02-20

数据类型

JavaScript中常见的几种数据类型:

基本类型:string,number,boolean,undefined,null

引用类型:Object,Function,Function,Array,Date等

typeof

typeof 返回一个表示数据类型的字符串,返回结果包括:number、boolean、string、object、undefined、function等6种数据类型。
typeof 可以对JS基础数据类型做出准确的判断。

Value Class Type
“foo” String string
new String(“foo”) String object
1.2 Number number
new Number(1.2) Number object
true Boolean boolean
new Boolean(true) Boolean object
new Date() Date object
new Error() Error object
[1,2,3] Array object
new Array(1, 2, 3) Array object
new Function(“”) Function function
/abc/g RegExp object (function in Nitro/V8)
new RegExp(“meow”) RegExp object (function in Nitro/V8)
{} Object object
new Object() Object object

Type 一列表示 typeof 操作符的运算结果。可以看到,这个值在大多数情况下都返回 “object”。

Class 一列表示对象的内部属性 [[Class]] 的值。

typeof foo !== ‘undefined’

上面代码会检测 foo 是否已经定义;如果没有定义而直接使用会导致 ReferenceError 的异常。 这是 typeof 唯一有用的地方。除非为了检测一个变量是否已经定义,我们应尽量避免使用 typeof 操作符。

Object.prototype.toString

公认靠谱的方法。
JavaScript 标准文档只给出了一种获取 上表 [[Class]] 值的方法,那就是使用 Object.prototype.toString,
该方法默认返回其调用者的具体类型。

1
2
3
4
5
6
7
function is(type, obj) {
var clas = Object.prototype.toString.call(obj).slice(8, -1);
return obj !== undefined && obj !== null && clas === type;
}

is('String', 'test'); // true
is('String', new String('test')); // true

更严格的讲,是 toString运行时this指向的对象类型, 返回的类型格式为[object,xxx],xxx是具体的数据类型。

1
2
3
4
5
6
7
8
9
10
11
12
Object.prototype.toString.call('') ;   // [object String]
Object.prototype.toString.call(1) ; // [object Number]
Object.prototype.toString.call(true) ; // [object Boolean]
Object.prototype.toString.call(undefined) ; // [object Undefined]
Object.prototype.toString.call(null) ; // [object Null]
Object.prototype.toString.call(new Function()) ; // [object Function]
Object.prototype.toString.call(new Date()) ; // [object Date]
Object.prototype.toString.call([]) ; // [object Array]
Object.prototype.toString.call(new RegExp()) ; // [object RegExp]
Object.prototype.toString.call(new Error()) ; // [object Error]
Object.prototype.toString.call(document) ; // [object HTMLDocument]
Object.prototype.toString.call(window) ; //[object global] window是全局对象global的引用

必须通过Object.prototype.toString.call来获取,而不能直接 new Date().toString(),因为大部分的对象都实现了自身的toString方法,这样就可能会导致Object的toString被终止查找,因此要用call来强制执行Object的toString方法。

instanceof

instanceof 操作符用来比较两个操作数的构造函数例如来判断 A 是否为 B 的实例。只有在比较自定义的对象时才有意义。

[] instanceof Array // true
[] instanceof Object; // true

instanceof检测的是原型。

JS 原型链

发表于 2017-01-21

名词解释

函数对象

由Function创造出来的函数 eg:

1
2
function a(){};
var b=function(){};

系统内置的函数对象

1
Function,Object,Array,String,Number

只有函数对象才有 prototype 属性

引用类型值:指的是那些保存在堆内存中的对象,意思是,变量中保存的实际上只是一个指针,这个指针执行内存中的另一个位置,由该位置保存对象,那么数组,普通对象,函数对象都算是引用数据类型,引用数据类型范围包含函数对象的范围

普通对象

函数对象之外的对象都是普通对象

基本类型值:指的是保存在栈内存中的简单数据段;除开函数对象之外的对象都是普通对象,那么普通对象范围是包含基本数据类型的

原型对象

prototype属性

1
function a(){};

对象 a 是由Function创造出来,是函数对象,a 就有了prototype属性.那么这个原型对象是怎么创造出来的呢?
来看下面这个例子:

1
2
var temp = new a();
a.prototype = temp;

a的prototype属性就是这样创造出来的

指针proto

所有的对象obj都具有proto属性(null和undefined除外),而且指向创造obj对象的函数对象的prototype属性 eg:

1
2
3
function a(){};
console.log(a.prototype.__proto__===Object.prototype); //true
console.log(a.__proto__===Function.prototype); //true 指向创造obj对象的函数对象的prototype属性

eg :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 在JavaScript的世界中,所有的函数都能作为构造函数,构造出一个对象
// 下面我给自己构造一个女神做对象
function NvShen () {
this.name = "Alice";
}
// 现在我设置NvShen这个函数的prototype属性
// 一般来说直接用匿名的对象就行,我这里是为了方便理解,
// 先定义一个hand对象再把hand赋值给NvShen的prototype
var hand = {
whichOne: "right hand",
someFunction: function(){
console.log("not safe for work.");
}
};
NvShen.prototype = hand;

// 这个时候,我们可以用NvShen作为构造函数,构造出myObject对象
var myObject = new NvShen();
console.log(myObject.__proto__ === NvShen.prototype) //true

我们构建了一个对象myObject,而myObject的原型是hand对象,而刚好myObject的构造函数NvShen()的prototype属性也指向hand对象。现在我们知道,prototype与proto的关系就是:你的proto来自你构造函数的prototype
hand.proto 指向的是Object.prototype

思考:var obj={}; obj.prototype.proto指向谁__?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
这里分步思考:
1, obj是是一个普通对象
2, 什么类型的对象是由prototype属性的?当然是函数对象
3, 所以obj是没有prototype属性的
4, 所以obj.prototype===undefined
5, 所以此题的最终问题是:undefined.proto指向什么
6, 所有的对象obj都具有proto属性(null和undefined除外)!所以答案是 js报错
```



## 构造器constructor

constructor 属性返回对创建此对象的函数对象的引用。

```javascript
function a(){};
console.log(a.constructor===Function); //true
console.log(a.prototype.constructor===a); //true

函数a是由Function创造出来,那么它的constructor指向的Function,
a.prototype是由new a()方式创造出来,那么a.prototype.constructor理应指向a

思考:a.prototype.proto.constructor指向谁__?

1
2
3
4
5
6
这里继续分解题目:
1, a.prototype指向a的一个实例,我们已经多次强调了,而且属于普通对象
2, __proto__定义为:指向创造obj对象的函数对象的prototype属性,所以看下谁创造了a.prototype,因为a.prototype是普通对象,类型为object,那么是Object创造了它,
3, 那么显而易见a.prototype.__proto__指向了Object.prototype
4, 那么题目简化为Object.prototype.constructor指向谁
5, 继续分解题目,Object.prototype为基本对象,那么就是Object创造了它,那么它的constructor就指向了Object
1
2
Object.prototype.constructor===Object //true
Object.prototype.__proto__===null //true

原型链

JS在创建对象(不论是普通对象还是函数对象)的时候,都有一个proto的内置属性,用于指向创建它的函数对象的原型对象prototype。

1
console.log(a.__proto__ === person.prototype) //true

同样,person.prototype对象也有proto属性,它指向创建它的函数对象(Object)的prototype

1
console.log(person.prototype.__proto__ === Object.prototype) //true

继续,Object.prototype对象也有proto属性,但它比较特殊,为null

1
console.log(Object.prototype.__proto__) //null

我们把这个有proto串起来的直到Object.prototype.proto为null的链叫做原型链。

CSS之absolute

发表于 2017-01-07

关于absolute

来自张鑫旭老师

  • 脱离文档流
  • 去浮动
  • 超越overflow

绝对定位和浮动有相似性,同样具有浮动的包裹性和破坏性。一旦给元素加上absolute或float就相当于给元素加上了display:block。

设置为绝对定位的元素框从文档流完全删除并去浮动也不瘦overflow控制,并相对于其包含块定位,包含块可能是文档中的另一个元素或者是初始包含块。
绝对定位使元素的位置与文档流无关,因此不占据空间。

如何确定定位点

  • 第一种情况

用户只给元素指定了absolute,未指定left/top/right/bottom。此时absolute元素的左上角定位点位置就是该元素正常文档流里的位置(也就是位置跟随)。

  • 第二种情况

用户给absolute元素指定了left/right,top/bottom。位置是absolute元素没有position:static以外的父元素。
设置值得是相对没有position:static以外的父元素定位,没有设置值得还是在正常文档流中。

无依赖的绝对定位实战

优点对父级无依赖,自适应好

  • 图片图表定位

利用跟随性实现

  • 边缘定位
1
2
3
4
5
6
7
<div class="course-fixed-x">
&nbsp;<div class="course-fixed">
<a href="http://www.imooc.com/activity/diaocha" class="goto_top_diaocha"></a>
<a href="http://www.imooc.com/mobile/app" class="goto_top_app"></a>
<a href="http://www.imooc.com/user/feedback" class="goto_top_feed"></a>
</div>
</div>
1
2
.course-fixed-x { height: 0;  text-align:right; overflow: hidden; }
.course-fixed { display: inline; position: fixed; margin-left: 20px; bottom: 100px; }

CSS之float

发表于 2017-01-01

浮动的原始作用

来自张鑫旭老师

实现文字环绕图片

特性

本质定义为包裹与破坏。

  • 包裹性

例如按钮宽度自适应,按钮要自动包裹在文字的外面。我们用什么方法实现呢?一就是display:inline-block;二就是float。

  • 破坏性

文字之所以会环绕含有float属性的图片时因为浮动破坏了正常的line boxes。
脱离文档流,父元素感受不到子元素,也就没了高度。

清除浮动

  • clear


  • BFC


兼容性

应用

CSS之vertical-align

发表于 2016-12-30

关于vertical-align

来自张鑫旭老师

vertical-align 属性设置元素的垂直对齐方式。
vertical-align属性的值有baseline、sub、super、top、text-top、middle、bottom、text-bottom等,其中初始值为baseline。

支持四大类

注:vertical-align的数值百分比是根据line-height计算的

  • baseline(基线)——将子元素的基线与父元素的基线相对齐。对于没有基线的元素,如图像或对象,则使它的底部与父元素的基线对齐。ppps:内联元素是基线对齐,文本的基线一般是X的下边缘。

  • top(顶部)——使元素的顶部与行中最高事物的顶部相对齐。

  • middle(中间)——使元素垂直居中。

  • bottom(底部)——使元素的底部与行中最低事物的底部相对齐。

  • text-top(文本顶部)——使元素的顶部与其父元素最高字母的顶部相对齐。

  • text-bottom(文本底部)——使元素的底部与其父元素字体的底部相对齐。

  • sub(下面)——把元素置于下方(下标),确切地说是使元素的基线对齐它的父元素首选的下标位置。

  • super(上面)——把元素置于上方(上标),确切地说是使元素的基线对齐它的父元素首选的上标位置。

vertical-align起作用的前提条件

符合以下条件


table-call只作用于自身

  • 直接display设置
    display

  • css声明更改元素显示水平
    float、position

应用

兼容性

CSS之line-height

发表于 2016-12-29

关于行高

来自张鑫旭老师

语法: line-height : normal |<实数> | <长度> | <百分比> | inherit
说明:设置元素中行的高度。
值: normal:默认行高,一般为1到1.2;
normal
normal
实数:实数值,缩放因子;
长度:合法的长度值,可为负数;
length

百分比:百分比取值基于元素的字体尺寸。
%
初始值: normal
继承性:继承
适用于:所有元素

行内框盒子模型

所有内敛元素的表现都和行内框盒子模型

  • 内容区域(content area)

是一种围绕文字看不见的的盒子,大小和字体大小有关。

内容区域

  • 内联盒子(inline boxes)

让内容排成一排显示,包含inline属性的都是,如果只是文字属于匿名内联盒子

内联盒子

  • 行框盒子(line boxes)

每一行都是行框盒子,每个行框盒子都是由一个个内联盒子组成

行框盒子

  • 包含盒子(containing box)

由一行行行框盒子组成

包含盒子

包含盒子包含行框盒子,行框盒子包含内联盒子

line-height的机制原理

有一个空的div,如果没有设置至少大于1像素高度height值时,该div的高度就是个0。如果该div里面打入了一个空格或是文字,则此div就会有一个高度。

这是个看上去很简单的问题,是理解line-height非常重要的一个问题。可能有人会跟认为是:文字撑开的!文字占据空间,自然将div撑开。我一开始也是这样理解的,但是事实上根本不是文字撑开了div的高度,而是line-height!

高度的表现不是行高,而是内容区域和行间距之和。

line
line
line
line
line

当行框盒子里有多个不同的行高的内联盒子此时行高?

使用经验

body

移动端的自适应

发表于 2016-12-21

概念

  • 完美视口

    在移动端,低端无定制的需求,都可以用这个完美视口完成。

  • 物理像素(physical pixel)

    一个物理像素是显示器(手机屏幕)上最小的物理显示单元,在操作系统的调度下,每一个设备像素都有自己的颜色值和亮度值。

  • 设备独立像素(density-independent pixel)

    设备独立像素(也叫密度无关像素),可以认为是计算机坐标系统中得一个点,这个点代表一个可以由程序使用的虚拟像素(比如: css像素),然后由相关系统转换为物理像素。同一张图片在各屏幕显示大小不一。
    我们希望不同屏幕显示图片的大小要一致。
    我们要计算图片缩放比例。

    计算公式:

    图片逻辑像素大小px1 / 图片缩放后实际像素大小px2 = 物理像素(设备像素dp) / 设备独立像素dips

    px2 = px1 * (dp / dips)

    px2 = px1 * dpr

  • 设备像素比(device pixel ratio )

    设备像素比(简称dpr)定义了物理像素和设备独立像素的对应关系,它的值可以按如下的公式的得到

    设备像素比 = 物理像素 / 设备独立像素

    在某一方向上,x方向或者y方向,可以通过window.devicePixelRatio获取到当前设备的dpr

    由于苹果retina的产生,使得清晰度提升,主要是因为设备像素提升了一倍,因此可以用更多像素去绘画更清晰的图像

    坊间对于dpr更通俗的说法叫

    • 一倍屏
    • 两倍屏
    • 三倍屏
  • 屏幕拉伸比scale

    也就是视口上的initial-scale , maximum-sacle 等属性

    scale 和 dpr的关系是倒数。

  • 例子

    以iphone6为例:

    设备宽高为375×667,可以理解为设备独立像素(或css像素)。
    dpr为2,根据上面的计算公式,其物理像素就应该×2,为750×1334。

    在不同的屏幕上(普通屏幕 vs retina屏幕),css像素所呈现的大小(物理尺寸)是一致的,不同的是1个css像素所对应的物理像素个数是不一致的。

    在普通屏幕下,1个css像素 对应 1个物理像素(1:1)。 在retina 屏幕下,1个css像素对应 4个物理像素(1:4)。

  • 位图像素

    一个位图像素是栅格图像(如:png, jpg, gif等)最小的数据单元。每一个位图像素都包含着一些自身的显示信息(如:显示位置,颜色值,透明度等)。

    理论上,1个位图像素对应于1个物理像素,图片才能得到完美清晰的展示。

    在普通屏幕下是没有问题的,但是在retina屏幕下就会出现位图像素点不够,从而导致图片模糊的情况。

对于dpr=2的retina屏幕而言,1个位图像素对应于4个物理像素,由于单个位图像素不可以再进一步分割,所以只能就近取色,从而导致图片模糊(注意上述的几个颜色值)。

所以,对于图片高清问题,比较好的方案就是两倍图片(@2x)。

如:200×300(css pixel)img标签,就需要提供400×600的图片。

如此一来,位图像素点个数就是原来的4倍,在retina屏幕下,位图像素点个数就可以跟物理像素点个数形成 1 : 1的比例,图片自然就清晰了(这也解释了之前留下的一个问题,为啥视觉稿的画布大小要×2?)。

在普通屏幕下,200×300(css pixel)img标签,所对应的物理像素个数就是200×300个,而两倍图片的位图像素个数则是200×300*4,所以就出现一个物理像素点对应4个位图像素点,所以它的取色也只能通过一定的算法(显示结果就是一张只有原图像素总数四分之一,我们称这个过程叫做downsampling),肉眼看上去虽然图片不会模糊,但是会觉得图片缺少一些锐利度,或者是有点色差(但还是可以接受的)。

移动端的问题

  • retina屏幕,图片高清问题

    两倍图片(@2x),然后图片容器缩小50%。

1
2
3
4
5
6
7
8
9

img标签
width: 200px;
height: 300px;
背景图片
width: 200px;
height: 300px;
background-image: url(image@2x.jpg);
background-size: 200px 300px;

缺点普通屏幕下:

同样下载了@2x的图片,造成资源浪费。
图片由于downsampling,会失去了一些锐利度(或是色差)。

解决办法是:不同的dpr下,加载不同的尺寸的图片。

这样的话,是不是是要准备两套图片了?

解决;用图片服务器,通过url获取参数,然后可以控制图片质量,也可以将图片裁剪成不同的尺寸。

  • retina下,border: 1px问题

    设计师想要的retina下border: 1px;,其实就是1物理像素宽,对于css而言,可以认为是border: 0.5px;,这是retina下(dpr=2)下能显示的最小单位。

    并不是所有手机浏览器都能识别border: 0.5px;,ios7以下,android等其他系统里,0.5px会被当成为0px处理,那么如何实现这0.5px呢

    最简单的一个做法就是这样(元素scale):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    .scale{
    position: relative;
    }
    .scale:after{
    content:"";
    position: absolute;
    bottom:0px;
    left:0px;
    right:0px;
    border-bottom:1px solid #ddd;
    -webkit-transform:scaleY(.5);
    -webkit-transform-origin:0 0;
    }

但是这样hack实在是不够通用(如:圆角等),写起来也麻烦。

比较推荐的还是页面scale的方案,是比较通用的,几乎满足所有场景。

对于iphone5(dpr=2),添加如下的meta标签,设置viewport(scale 0.5)

1
<meta name="viewport" content="width=640,initial-scale=0.5,maximum-scale=0.5, minimum-scale=0.5,user-scalable=no">
  • 多屏适配布局问题
基于rem的原理,针对不同手机屏幕尺寸和dpr动态的改变根节点html的font-size大小(基准值)。
乘以dpr,是因为页面有可能为了实现1px border页面会缩放(scale) 1/dpr 倍(如果没有,dpr=1),。

除以10,是为了取整,方便计算(理论上可以是任何值)

1
rem = document.documentElement.clientWidth * dpr / 10
- CSS方式更改 通过设备宽度来媒体查询来改变html的font-size: - javascript方式更改 通过上面的公式,计算出基准值rem,然后写入样式
  • 字体大小问题

    设置viewpor页面scale,必然会带来字体大小会被缩放。

    针对不同的分辨率(dpr不同),设置不用的大小。

各大厂解决方案

  • 手机淘宝

    • 获取手机dpr(window.devicePixelRatio),动态生成viewport。
    • 换取手机宽度,分成10份,每一份的宽度即是rem的尺寸。
    • 根据设计稿尺寸(px)通过计算,转换成rem去布局。
  • 天猫

    • 采用scale=1.0 写死viewport。
    • flex布局,笃定认为布局尺寸是375 (iPhone6)
    • rem 确定非flex的元素
  • 手机携程

    • 采用scale=1.0 写死viewport
    • px + 百分比布局
  • 拉钩

    • 关键元素高宽和位置都不变,只有容器元素在做伸缩变换。
    • 文字流式,控件弹性,图片等比缩放

如何与设计协作

  1. 视觉设计阶段,设计师按宽度750px(iPhone 6)做设计稿,除图片外所有设计元素用矢量路径来做。设计定稿后在750px的设计稿上做标注,输出标注图。同时等比放大1.5倍生成宽度1125px的设计稿,在1125px的稿子里切图。

  2. 输出两个交付物给开发工程师:一个是程序用到的@3x切图资源,另一个是宽度750px的设计标注图。

  3. 开发工程师拿到750px标注图和@3x切图资源,完成iPhone 6(375pt)的界面开发。此阶段不能用固定宽度的方式开发界面,得用自动布局(auto layout),方便后续适配到其它尺寸。

  4. 适配调试阶段,基于iPhone 6的界面效果,分别向上向下调试iPhone 6 plus(414pt)和iPhone 5S及以下(320pt)的界面效果。由此完成大中小三屏适配。

鞠躬

CSS解疑

发表于 2016-12-17

1.BFC

Block-level elements are those elements of the source document that are formatted visually as blocks (e.g., paragraphs). The following values of the ‘display’ property make an element block-level: ‘block’, ‘list-item’, and ‘table’

浮动元素和绝对定位元素,非块级盒子的块级容器(例如 inline-blocks, table-cells, 和 table-captions),以及overflow值不为“visiable”的块级盒子,都会为他们的内容创建新的块级格式化上下文。

至少满足下列条件中的任何一个:

  • float的值不为none

  • position的值不为static或者relative

  • display的值为 table-cell, table-caption, inline-block, flex, 或者 inline-flex中的其中一个

  • overflow的值不为visible

规则:

在一个块级格式化上下文里,盒子从包含块的顶端开始垂直地一个接一个地排列,两个盒子之间的垂直的间隙是由他们的margin 值所决定的。毗邻块盒子的垂直外边距折叠只有他们是在同一BFC时才会发生。如果他们属于不同的BFC,他们之间的外边距将不会折叠。所以通过创建一个新的BFC我们可以防止外边距折叠。

在块级格式化上下文中,每一个盒子的左外边缘(margin-left)会触碰到容器的左边缘(border-left)(对于从右到左的格式来说,则触碰到右边缘),即使存在浮动也是如此,除非这个盒子创建一个新的块级格式化上下文。

  • 内部的Box会在垂直方向,一个接一个地放置。

  • Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠

  • 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。

  • BFC的区域不会与float box重叠。

  • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。

  • 计算BFC的高度时,浮动元素也参与计算 // 清除浮动

总结

BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。

因为BFC内部的元素和外部的元素绝对不会互相影响,因此, 当BFC外部存在浮动时,它不应该影响BFC内部Box的布局,BFC会通过变窄,而不与浮动有重叠。同样的,当BFC内部有浮动时,为了不影响外部元素的布局,BFC计算高度时会包括浮动的高度。避免margin重叠也是这样的一个道理。

属性继承

  • 不可继承的:display、margin、border、padding、background、height、min-height、max-height、width、min-width、max-width、overflow、position、left、right、top、bottom、z-index、float、clear、table-layout、vertical-align、page-break-after、page-bread-before和unicode-bidi。

  • 所有元素可继承:visibility和cursor。

  • 内联元素可继承(inline):letter-spacing、word-spacing、white-space、line-height、color、font、font-family、font-size、font-style、font-variant、font-weight、text-decoration、text-transform、direction。

  • 终端块状元素可继承(inline-block):text-indent和text-align。

  • 列表元素可继承(block):list-style、list-style-type、list-style-position、list-style-image。

  • 表格元素可继承:border-collapse。

box

  • W3C的标准Box Model

    /外盒尺寸计算(元素空间尺寸)/
    Element空间高度 = content height + padding + border + margin
    Element 空间宽度 = content width + padding + border + margin
    /内盒尺寸计算(元素大小)/
    Element Height = content height + padding + border (Height为内容高度)
    Element Width = content width + padding + border (Width为内容宽度)

  • IE传统下Box Model

    /外盒尺寸计算(元素空间尺寸)/
    Element空间高度 = content Height + margin (Height包含了元素内容宽度,边框宽度,内距宽度)
    Element空间宽度 = content Width + margin (Width包含了元素内容宽度、边框宽度、内距宽度)
    /内盒尺寸计算(元素大小)/
    Element Height = content Height(Height包含了元素内容宽度,边框宽度,内距宽度)
    Element Width = content Width(Width包含了元素内容宽度、边框宽度、内距宽度)

box-size

box-sizing : content-box || border-box || inherit
  • content-box

此值为其默认值,其让元素维持W3C的标准Box Model,也就是说元素的宽度/高度(width/height)等于元素边框宽度(border)加上元素内边距(padding)加上元素内容宽度/高度(content width/height)即:Element Width/Height = border+padding+content width/height。

  • border-box

此值让元素维持IE传统的Box Model(IE6以下版本),也就是说元素的宽度/高度等于元素内容的宽度/高度。(从上面Box Model介绍可知,我们这里的content width/height包含了元素的border,padding,内容的width/height【此处的内容宽度/高度=width/height-border-padding】)。

border

边框三角

overflow

  • 滚动条高度

  • 解决出现滚动条后水平方向抖动问题

overflow

去除图片和标签之间的空格

编写高效CSS

发表于 2016-12-13

热身

对于CSS的优化,网络上分享的确实找不到什么系统的,整理下平时的积累。
主要从以下几个方面:

1. CSS架构

关于如何处理网站的CSS,各个网站做法都不一样,一般分为reset.css, main.css, content.css,然后每个活动页面一个单独的CSS,也是我最常用的。

  • 关于CSS reset

CSS reset血多基本上是不需要的,反而增加了页面CSS 的overwrite,有些常用标签我也是会简单重置一下的,而且会避免overwrite(样式重写),以保证样式最精简,渲染最高效。

  • CSS通用样式库

CSS通用样式库就是可以在任何网站使用的CSS样式库

  • 网站CSS样式库

根据当前实际的项目内容指定的。例如,文字链接颜色是什么,文字链接经过的样式是什么;一些常用的背景色样式,常用的边框样式等,以及一些高宽等。按照我的经验,网站CSS样式库又可以架构为以下几部分:

网站常见颜色
网站常见padding属性、margin属性
网站常见width属性、height属性
  • 网站公共结构样式

  • 单页面的精细结构

2. css样式分离

样式的精简与重用

eg:

.dib{display:inline-block;}
.bdd border:1px solid #ddd;}
.bgf7{background:#f7f7f7;}
.p20_40{padding:20px 40px;}

字面上很容易理解,就是把这段样式分离成一个一个单独的样式,这样但是,要实现一个复杂的效果,HTML代码量就是非常庞大,一切都是权衡,何时分离,哪些要分离?样式精简与重用仅仅是通过分离吗。

这类样式库可惜细分“通用库”和“当前项目库”等。

样式的独立拆分,使得各种效果可以自由组合,这是有别于一个class类覆盖多个CSS属性的做法的。样式的独立拆分,精简的CSS文件,每个样式的重用性可谓发挥到的最大,同时,页面的后期维护变得异常轻松,样式冲突的可能性也是非常低的。

3. css命名

面向属性的命名方法

也就是上面说的分离,分离为什么可以让样式的重用性放大至最大,就是因为分离后样式的命名就是样式本身,针对自身属性的一种命名方式,只会overwrite,不会冲突。

eg:

.tr{text-align:right;}
.pb8{padding-bottom:8px;}

限制重用

会使用层级(.test .test1),会使用标签(ul.test),这样限制越多,越抑制了CSS的重用性

统一前缀

减小类名的长度,间接影响CSS文件大小

4. 基于状态类名交互

CSS单位EM和REM

发表于 2016-11-05

em 和 rem

em和rem是一个相对的大小,我们可以这样来设置1em,0.5em,1.5em等,而且“em”还可以指定到小数点后三位,比如“1.234em”。“相对”的意思是:

  • 相对的计算必然会一个参考物,那么这里相对所指的是相对于相对于使用em单位的元素的font-size。比如:如果在一个div中设置字体大小为“16px”,此时这个div的后代元素将继承他的字体大小,除非重新在其后代元素中进行过显示的设置。此时,如果你将其子元素的字体大小设置为0.75em,那么其字体大小计算出来后就相当于0.75 X 16px = 12px;

  • 如果用户通过浏览器的UI控件改变了文字的大小,那么我们整个页面也会进行放大(或缩小),不至于用户改变了浏览器的字体后会致使整个页面崩溃。

也就是说em 和 rem都是灵活、 可扩展的单位,由浏览器转换为像素值,具体取决于您的设计中的字体大小设置。 如果你使用值 1em 或 1rem,它可以被浏览器翻译成 从16px到 160px 或其他任意值。

遇到的问题

em 和 rem 单位提供的这种灵活性和工作方式都很相似,所以最大的问题是,我们何时应使用 em 值,何时应使用 rem 值呢

区别

em 和 rem 单位之间的区别是浏览器根据谁来转化成px值。

rem 单位如何转换为像素值

当使用 rem 单位,他们转化为像素大小取决于页根元素的字体大小,即 html 元素的字体大小。 根元素字体大小乘以你 rem 值。
例如,根元素的字体大小 16px,10rem 将等同于 160px,即 10 x 16 = 160。

em 单位如何转换为像素值

当使用em单位时,像素值将是em值乘以使用em单位的元素的字体大小。
例如,如果一个 div 有 18px 字体大小,10em 将等同于 180px,即 10 × 18 = 180。

有一个比较普遍的误解,认为 em 单位是相对于父元素的字体大小。 事实上,根据W3标准 ,它们是相对于使用em单位的元素的字体大小。父元素的字体大小可以影响 em 值,但这种情况的发生,纯粹是因为继承。 让我们看看为什么以及如何起作用。

em 单位的遗传效果

使用 em 单位存在继承的时候,情况会变得比较棘手,因为每个元素将自动继承其父元素的字体大小。 继承效果只能被明确的字体单位覆盖,比如px,vw。

使用 em 单位的元素字体大小根据它们来定。 但该元素可能继承其父元素的字体大小,而父元素又继承其父元素的字体大小,等等。 因此,以 em 为单位的元素字体大小可能会受到其任何父元素的字体大小影响。

em 继承的例子

如果我们的根元素字体大小为 16px (通常是默认值) 一个子元素 div 里面padding值为 1.5em,该 div 将从根元素继承字体大小 16px。 因此padding会翻译成 24px,即 1.5 x 16 = 24。

如果我们加多一个div来包裹原先的div,然后设置其字体大小为 1.25em呢?

我们包裹的 div 继承根元素字体大小 16px ,并乘以它自己的 1.25em 的字体大小。 这将设置包裹 div 字体大小为 20px,即 1.25 x 16 = 20。

现在我们原始的 div 不再直接从根元素继承,而是从其新的父元素继承字体大小为 20px 1.5em 其padding值现在等于 30px,即 1.5 x 20 = 30。

这个继承效应可以更复杂,如果我们向我们原始的 div 添加 em 字体单位,比方说 1.2em。

Div 从其父级继承 20px 字体大小,然后,乘以它自己的 1.2em 设置,给它 24px,即 1.2 × 20 = 24 新字体大小。

div上的1.5em padding 现在将再次改变大小,用新的字体大小,36px,即 1.5 × 24 = 36 。

最后,为了进一步说明那个 em 单位是相对于他们最终获得(不是父元素)的字体大小,让我们来看看设置padding 1.5em 如果我们显式设置 div 使用 14px值,不继承字体大小会发生什么。

现在,我们的padding为 21px,即 1.5 x 14 = 21 已经变小。 它不受父元素的字体大小。

根 html 元素将继承浏览器中设置的字体大小,除非显式设置固定值去覆盖。所以 html 元素的字体大小虽然是直接确定 rem值,但字体大小可能首先来自浏览器设置。因此浏览器的字体大小设置可以影响每个使用 rem 单元以及每个通过 em 单位继承的值。

总结与 rem 差异 em

  • rem 单位翻译为像素值是由 html 元素的字体大小决定的。 此字体大小会被浏览器中字体大小的设置影响,除非显式重写一个具体单位。

  • em 单位转为像素值,取决于他们使用的字体大小。 此字体大小受从父元素继承过来的字体大小,除非显式重写与一个具体单位。

使用rem的目的

确保无论用户如何设置自己的浏览器,我们的布局都能调整到合适大小。

使用em的目的

em 单位取决于一个font-size值而非 html 元素的字体大小。
em 单位的主要目的应该是允许保持在一个特定的设计元素范围内的可扩展性。根据某个元素的字体大小做缩放而不是根元素的字体大小。

总结

  • rem 和 em 单位是由浏览器基于你的设计中的字体大小计算得到的像素值。
  • em 单位基于使用他们的元素的字体大小。
  • rem 单位基于 html 元素的字体大小。
  • em 单位可能受任何继承的父元素字体大小影响
  • rem 单位可以从浏览器字体设置中继承字体大小。
  • 使用 em 单位应根据组件的字体大小而不是根元素的字体大小。
  • 在不需要使用em单位,并且需要根据浏览器的字体大小设置缩放的情况下使用rem。
  • 使用rem单位,除非你确定你需要 em 单位,包括对字体大小。
  • 媒体查询中使用 rem 单位
  • 不要在多列布局中使用 em 或 rem -改用 %。
  • 不要使用 em 或 rem,如果缩放会不可避免地导致要打破布局元素。
1…567
lennonover

lennonover

一丿口石砳磊

70 日志
28 标签
© 2022 lennonover
由 Hexo 强力驱动
主题 - NexT.Muse