Tiny'Wo | 小窝

网络中的一小块自留地

面试官:说说flexbox(弹性盒布局模型�?以及适用场景�?

一、是什�?

Flexible Box 简�?flex,意为”弹性布局”,可以简便、完整、响应式地实现各种页面布局

采用Flex布局的元素,称为flex容器container

它的所有子元素自动成为容器成员,称为flex项目item

容器中默认存在两条轴,主轴和交叉轴,�?0度关系。项目默认沿主轴排列,通过flex-direction来决定主轴的方向

每根轴都有起点和终点,这对于元素的对齐非常重�?

二、属�?

关于flex常用的属性,我们可以划分为容器属性和容器成员属�?
容器属性有�?

  • flex-direction
  • flex-wrap
  • flex-flow
  • justify-content
  • align-items
  • align-content

flex-direction

决定主轴的方�?即项目的排列方向)

1
2
3
.container {   
flex-direction: row | row-reverse | column | column-reverse;
}

属性对应如下:

  • row(默认值):主轴为水平方向,起点在左端
  • row-reverse:主轴为水平方向,起点在右端
  • column:主轴为垂直方向,起点在上沿�?- column-reverse:主轴为垂直方向,起点在下沿

如下图所示:

flex-wrap

弹性元素永远沿主轴排列,那么如果主轴排不下,通过flex-wrap决定容器内项目是否可换行

1
2
3
.container {  
flex-wrap: nowrap | wrap | wrap-reverse;
}

属性对应如下:

  • nowrap(默认值):不换行
  • wrap:换行,第一行在下方
  • wrap-reverse:换行,第一行在上方

默认情况是不换行,但这里也不会任由元素直接溢出容器,会涉及到元素的弹性伸�?

flex-flow

flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap

1
2
3
.box {
flex-flow: <flex-direction> || <flex-wrap>;
}

justify-content

定义了项目在主轴上的对齐方式

1
2
3
.box {
justify-content: flex-start | flex-end | center | space-between | space-around;
}

属性对应如下:

  • flex-start(默认值):左对齐
  • flex-end:右对齐
  • center:居�?- space-between:两端对齐,项目之间的间隔都相等
  • space-around:两个项目两侧间隔相�?
    效果图如下:

align-items

定义项目在交叉轴上如何对�?

1
2
3
.box {
align-items: flex-start | flex-end | center | baseline | stretch;
}

属性对应如下:

  • flex-start:交叉轴的起点对�?- flex-end:交叉轴的终点对�?- center:交叉轴的中点对�?- baseline: 项目的第一行文字的基线对齐
  • stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高�?

align-content

定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作�?

1
2
3
.box {
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}

属性对应如吓:

  • flex-start:与交叉轴的起点对齐
  • flex-end:与交叉轴的终点对齐
  • center:与交叉轴的中点对齐
  • space-between:与交叉轴两端对齐,轴线之间的间隔平均分�?- space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一�?- stretch(默认值):轴线占满整个交叉轴

效果图如下:

容器成员属性如下:

  • order
  • flex-grow
  • flex-shrink
  • flex-basis
  • flex
  • align-self

order

定义项目的排列顺序。数值越小,排列越靠前,默认�?

1
2
3
.item {
order: <integer>;
}

flex-grow

上面讲到当容器设为flex-wrap: nowrap;不换行的时候,容器宽度有不够分的情况,弹性元素会根据flex-grow来决�?
定义项目的放大比例(容器宽度>元素总宽度时如何伸展�?
默认为0,即如果存在剩余空间,也不放�?

1
2
3
.item {
flex-grow: <number>;
}

如果所有项目的flex-grow属性都�?,则它们将等分剩余空间(如果有的话)

如果一个项目的flex-grow属性为2,其他项目都�?,则前者占据的剩余空间将比其他项多一�?

弹性容器的宽度正好等于元素宽度总和,无多余宽度,此时无论flex-grow是什么值都不会生效

flex-shrink

定义了项目的缩小比例(容器宽�?元素总宽度时如何收缩),默认�?,即如果空间不足,该项目将缩�?

1
2
3
.item {
flex-shrink: <number>; /* default 1 */
}

如果所有项目的flex-shrink属性都�?,当空间不足时,都将等比例缩�?
如果一个项目的flex-shrink属性为0,其他项目都�?,则空间不足时,前者不缩小

在容器宽度有剩余时,flex-shrink也是不会生效�?

flex-basis

设置的是元素在主轴上的初始尺寸,所谓的初始尺寸就是元素在flex-growflex-shrink生效前的尺寸

浏览器根据这个属性,计算主轴是否有多余空间,默认值为auto,即项目的本来大小,如设置了width则元素尺寸由width/height决定(主轴方向),没有设置则由内容决�?

1
2
3
.item {
flex-basis: <length> | auto; /* default auto */
}

当设置为0的是,会根据内容撑开

它可以设为跟widthheight属性一样的值(比如350px),则项目将占据固定空间

flex

flex属性是flex-grow, flex-shrink �?flex-basis的简写,默认值为0 1 auto,也是比较难懂的一个复合属�?

1
2
3
.item {
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}

一些属性有�?

  • flex: 1 = flex: 1 1 0%
  • flex: 2 = flex: 2 1 0%
  • flex: auto = flex: 1 1 auto
  • flex: none = flex: 0 0 auto,常用于固定尺寸不伸�?

flex:1 �?flex:auto 的区别,可以归结于flex-basis:0flex-basis:auto的区�?
当设置为0时(绝对弹性元素),此时相当于告诉flex-growflex-shrink在伸缩的时候不需要考虑我的尺寸

当设置为auto时(相对弹性元素),此时则需要在伸缩时将元素尺寸纳入考虑

注意:建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关�?

align-self

允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属�?
默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch

1
2
3
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}

效果图如下:

三、应用场�?

在以前的文章中,我们能够通过flex简单粗暴的实现元素水平垂直方向的居中,以及在两栏三栏自适应布局中通过flex完成,这里就不再展开代码的演�?
包括现在在移动端、小程序这边的开发,都建议使用flex进行布局

参考文�?- https://developer.mozilla.org/zh-CN/docs/Web/CSS/flex

面试官:介绍一下grid网格布局

一、是什�?

Grid 布局即网格布局,是一个二维的布局方式,由纵横相交的两组网格线形成的框架性布局结构,能够同时处理行与列

擅长将一个页面划分为几个主要区域,以及定义这些区域的大小、位置、层次等关系

这与之前讲到的flex一维布局不相�?
设置display:grid/inline-grid的元素就是网格布局容器,这样就能出发浏览器渲染引擎的网格布局算法

1
2
3
4
5
6
7
<div class="container">
<div class="item item-1">
<p class="sub-item"></p >
</div>
<div class="item item-2"></div>
<div class="item item-3"></div>
</div>

上述代码实例中,.container元素就是网格布局容器,.item元素就是网格的项目,由于网格元素只能是容器的顶层子元素,所以p元素并不是网格元�?
这里提一下,网格线概念,有助于下面对grid-column系列属性的理解

网格线,即划分网格的线,如下图所示:

上图是一�?2 x 3 的网格,共有3根水平网格线�?根垂直网格线

二、属�?

同样,Grid 布局属性可以分为两大类�?

  • 容器属性,
  • 项目属�?

关于容器属性有如下�?

display 属�?

文章开头讲到,在元素上设置display:grid �?display:inline-grid 来创建一个网格容�?

  • display:grid 则该容器是一个块级元�?
  • display: inline-grid 则容器元素为行内元素

grid-template-columns 属性,grid-template-rows 属�?

grid-template-columns 属性设置列宽,grid-template-rows 属性设置行�?

1
2
3
4
5
6
7
8
.wrapper {
display: grid;
/* 声明了三列,宽度分别�?200px 200px 200px */
grid-template-columns: 200px 200px 200px;
grid-gap: 5px;
/* 声明了两行,行高分别�?50px 50px */
grid-template-rows: 50px 50px;
}

以上表示固定列宽�?200px 200px 200px,行高为 50px 50px

上述代码可以看到重复写单元格宽高,通过使用repeat()函数,可以简写重复的�?

  • 第一个参数是重复的次�?- 第二个参数是重复的�?
    所以上述代码可以简写成
1
2
3
4
5
6
.wrapper {
display: grid;
grid-template-columns: repeat(3,200px);
grid-gap: 5px;
grid-template-rows:repeat(2,50px);
}

除了上述的repeact关键字,还有�?

  • auto-fill:示自动填充,让一行(或者一列)中尽可能的容纳更多的单元�?

    grid-template-columns: repeat(auto-fill, 200px) 表示列宽�?200 px,但列的数量是不固定的,只要浏览器能够容纳得下,就可以放置元�?

  • fr:片段,为了方便表示比例关系

grid-template-columns: 200px 1fr 2fr 表示第一个列宽设置为 200px,后面剩余的宽度分为两部分,宽度分别为剩余宽度的 1/3 �?2/3

  • minmax:产生一个长度范围,表示长度就在这个范围之中都可以应用到网格项目中。第一个参数就是最小值,第二个参数就是最大�?

    minmax(100px, 1fr)表示列宽不小于100px,不大于1fr

  • auto:由浏览器自己决定长�?

    grid-template-columns: 100px auto 100px 表示第一第三列为 100px,中间由浏览器决定长�?

grid-row-gap 属性, grid-column-gap 属性, grid-gap 属�?

grid-row-gap 属性、grid-column-gap 属性分别设置行间距和列间距。grid-gap 属性是两者的简写形�?
grid-row-gap: 10px 表示行间距是 10px

grid-column-gap: 20px 表示列间距是 20px

grid-gap: 10px 20px 等同上述两个属�?

grid-template-areas 属�?

用于定义区域,一个区域由一个或者多个单元格组成

1
2
3
4
5
6
7
8
.container {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
grid-template-areas: 'a b c'
'd e f'
'g h i';
}

上面代码先划分出9个单元格,然后将其定名为ai的九个区域,分别对应这九个单元格�?
多个单元格合并成一个区域的写法如下

1
2
3
grid-template-areas: 'a a a'
'b b b'
'c c c';

上面代码�?个单元格分成abc三个区域

如果某些区域不需要利用,则使�?�?(.)表�?

grid-auto-flow 属�?

划分网格以后,容器的子元素会按照顺序,自动放置在每一个网格�?
顺序就是由grid-auto-flow决定,默认为行,代表”先行后列”,即先填满第一行,再开始放入第二行

当修改成column后,放置变为如下�?

justify-items 属性, align-items 属性, place-items 属�?

justify-items 属性设置单元格内容的水平位置(左中右),align-items 属性设置单元格的垂直位置(上中下)

两者属性的值完成相�?

1
2
3
4
.container {
justify-items: start | end | center | stretch;
align-items: start | end | center | stretch;
}

属性对应如下:

  • start:对齐单元格的起始边�?- end:对齐单元格的结束边�?- center:单元格内部居中
  • stretch:拉伸,占满单元格的整个宽度(默认值)

place-items属性是align-items属性和justify-items属性的合并简写形�?

justify-content 属性, align-content 属性, place-content 属�?

justify-content属性是整个内容区域在容器里面的水平位置(左中右),align-content属性是整个内容区域的垂直位置(上中下)

1
2
3
4
.container {
justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
align-content: start | end | center | stretch | space-around | space-between | space-evenly;
}

两个属性的写法完全相同,都可以取下面这些值:

  • start - 对齐容器的起始边�?- end - 对齐容器的结束边�?- center - 容器内部居中

  • space-around - 每个项目两侧的间隔相等。所以,项目之间的间隔比项目与容器边框的间隔大一�?

  • space-between - 项目与项目的间隔相等,项目与容器边框之间没有间隔

  • space-evenly - 项目与项目的间隔相等,项目与容器边框之间也是同样长度的间�?

  • stretch - 项目大小没有指定时,拉伸占据整个网格容器

grid-auto-columns 属性和 grid-auto-rows 属�?

有时候,一些项目的指定位置,在现有网格的外部,就会产生显示网格和隐式网�?
比如网格只有3列,但是某一个项目指定在�?行。这时,浏览器会自动生成多余的网格,以便放置项目。超出的部分就是隐式网格

grid-auto-rowsgrid-auto-columns就是专门用于指定隐式网格的宽�?

关于项目属性,有如下:

grid-column-start 属性、grid-column-end 属性、grid-row-start 属性以及grid-row-end 属�?

指定网格项目所在的四个边框,分别定位在哪根网格线,从而指定项目的位置

  • grid-column-start 属性:左边框所在的垂直网格�?- grid-column-end 属性:右边框所在的垂直网格�?- grid-row-start 属性:上边框所在的水平网格�?- grid-row-end 属性:下边框所在的水平网格�?
    举个例子�?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <style>
    #container{
    display: grid;
    grid-template-columns: 100px 100px 100px;
    grid-template-rows: 100px 100px 100px;
    }
    .item-1 {
    grid-column-start: 2;
    grid-column-end: 4;
    }
    </style>

    <div id="container">
    <div class="item item-1">1</div>
    <div class="item item-2">2</div>
    <div class="item item-3">3</div>
    </div>

通过设置grid-column属性,指定1号项目的左边框是第二根垂直网格线,右边框是第四根垂直网格�?

grid-area 属�?

grid-area 属性指定项目放在哪一个区�?

1
2
3
.item-1 {
grid-area: e;
}

意思为�?号项目位于e区域

与上述讲到的grid-template-areas搭配使用

justify-self 属性、align-self 属性以�?place-self 属�?

justify-self属性设置单元格内容的水平位置(左中右),跟justify-items属性的用法完全一致,但只作用于单个项目�?
align-self属性设置单元格内容的垂直位置(上中下),跟align-items属性的用法完全一致,也是只作用于单个项目

1
2
3
4
.item {
justify-self: start | end | center | stretch;
align-self: start | end | center | stretch;
}

这两个属性都可以取下面四个值�?

  • start:对齐单元格的起始边缘�? - end:对齐单元格的结束边缘�? - center:单元格内部居中�? - stretch:拉伸,占满单元格的整个宽度(默认值)

三、应用场�?

文章开头就讲到,Grid是一个强大的布局,如一些常见的 CSS 布局,如居中,两列布局,三列布局等等是很容易实现的,在以前的文章中,也有使用Grid布局完成对应的功�?
关于兼容性问题,结果如下�?

总体兼容性还不错,但�?IE 10 以下不支�?
目前,Grid布局在手机端支持还不算太友好

参考文�?

面试官:css中,有哪些方式可以隐藏页面元素?区别?

一、前言

在平常的样式排版中,我们经常遇到将某个模块隐藏的场景

通过css隐藏元素的方法有很多种,它们看起来实现的效果是一致的

但实际上每一种方法都有一丝轻微的不同,这些不同决定了在一些特定场合下使用哪一种方�?

二、实现方�?

通过css实现隐藏元素方法有如下:

  • display:none
  • visibility:hidden
  • opacity:0
  • 设置height、width模型属性为0
  • position:absolute
  • clip-path

display:none

设置元素的displaynone是最常用的隐藏元素的方法

1
2
3
.hide {
display:none;
}

将元素设置为display:none后,元素在页面上将彻底消�?
元素本身占有的空间就会被其他元素占有,也就是说它会导致浏览器的重排和重绘

消失后,自身绑定的事件不会触发,也不会有过渡效果

特点:元素不可见,不占据空间,无法响应点击事�?

visibility:hidden

设置元素的visibilityhidden也是一种常用的隐藏元素的方�?
从页面上仅仅是隐藏该元素,DOM结果均会存在,只是当时在一个不可见的状态,不会触发重排,但是会触发重绘

1
2
3
.hidden{
visibility:hidden
}

给人的效果是隐藏了,所以他自身的事件不会触�?
特点:元素不可见,占据页面空间,无法响应点击事件

opacity:0

opacity属性表示元素的透明度,将元素的透明度设置为0后,在我们用户眼中,元素也是隐藏�?
不会引发重排,一般情况下也会引发重绘

如果利用 animation 动画,对 opacity 做变化(animation会默认触发GPU加速),则只会触发 GPU 层面�?composite,不会触发重�?

1
2
3
.transparent {
opacity:0;
}

由于其仍然是存在于页面上的,所以他自身的的事件仍然是可以触发的,但被他遮挡的元素是不能触发其事件的

需要注意的是:其子元素不能设置opacity来达到显示的效果

特点:改变元素透明度,元素不可见,占据页面空间,可以响应点击事�?

设置height、width属性为0

将元素的marginborderpaddingheightwidth等影响元素盒模型的属性设置成0,如果元素内有子元素或内容,还应该设置其overflow:hidden来隐藏其子元�?

1
2
3
4
5
6
7
8
.hiddenBox {
margin:0;
border:0;
padding:0;
height:0;
width:0;
overflow:hidden;
}

特点:元素不可见,不占据页面空间,无法响应点击事�?

position:absolute

将元素移出可视区�?

1
2
3
4
5
.hide {
position: absolute;
top: -9999px;
left: -9999px;
}

特点:元素不可见,不影响页面布局

clip-path

通过裁剪的形�?

1
2
3
.hide {
clip-path: polygon(0px 0px,0px 0px,0px 0px,0px 0px);
}

特点:元素不可见,占据页面空间,无法响应点击事件

小结

最常用的还是display:nonevisibility:hidden,其他的方式只能认为是奇招,它们的真正用途并不是用于隐藏元素,所以并不推荐使用它�?

三、区�?

关于display: none visibility: hiddenopacity: 0的区别,如下表所示:

display: none visibility: hidden opacity: 0
页面�? 不存�? 存在 存在
重排 �? 不会 不会
重绘 �? �? 不一�?
自身绑定事件 不触�? 不触�? 可触�?
transition 不支�? 支持 支持
子元素可复原 不能 �? 不能
被遮挡的元素可触发事�? �? �? 不能

参考文�?

面试官:怎么理解回流跟重绘?什么场景下会触发?

一、是什�?

HTML中,每个元素都可以理解成一个盒子,在浏览器解析过程中,会涉及到回流与重绘:

  • 回流:布局引擎会根据各种样式计算每个盒子在页面上的大小与位�?
  • 重绘:当计算好盒模型的位置、大小及其他属性后,浏览器根据每个盒子特性进行绘�?
    具体的浏览器解析渲染机制如下所示:

  • 解析HTML,生成DOM树,解析CSS,生成CSSOM�?
  • 将DOM树和CSSOM树结合,生成渲染�?Render Tree)
  • Layout(回流):根据生成的渲染树,进行回�?Layout),得到节点的几何信息(位置,大小�?- Painting(重绘):根据渲染树以及回流得到的几何信息,得到节点的绝对像素
  • Display:将像素发送给GPU,展示在页面�?

在页面初始渲染阶段,回流不可避免的触发,可以理解成页面一开始是空白的元素,后面添加了新的元素使页面布局发生改变

当我们对 DOM 的修改引发了 DOM 几何尺寸的变化(比如修改元素的宽、高或隐藏元素等)时,浏览器需要重新计算元素的几何属性,然后再将计算的结果绘制出�?
当我们对 DOM 的修改导致了样式的变化(colorbackground-color),却并未影响其几何属性时,浏览器不需重新计算元素的几何属性、直接为该元素绘制新的样式,这里就仅仅触发了重绘

二、如何触�?

要想减少回流和重绘的次数,首先要了解回流和重绘是如何触发�?

回流触发时机

回流这一阶段主要是计算节点的位置和几何信息,那么当页面布局和几何信息发生变化的时候,就需要回流,如下面情况:

  • 添加或删除可见的DOM元素
  • 元素的位置发生变�?- 元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
  • 内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代
  • 页面一开始渲染的时候(这避免不了)
  • 浏览器的窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的)

还有一些容易被忽略的操作:获取一些特定属性的�?

offsetTop、offsetLeft�?offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight

这些属性有一个共性,就是需要通过即时计算得到。因此浏览器为了获取这些值,也会进行回流

除此还包括getComputedStyle 方法,原理是一样的

重绘触发时机

触发回流一定会触发重绘

可以把页面理解为一个黑板,黑板上有一朵画好的小花。现在我们要把这朵从左边移到了右边,那我们要先确定好右边的具体位置,画好形状(回流),再画上它原有的颜色(重绘)

除此之外还有一些其他引起重绘行为:

  • 颜色的修�?
  • 文本方向的修�?- 阴影的修�?

浏览器优化机�?

由于每次重排都会造成额外的计算消耗,因此大多数浏览器都会通过队列化修改并批量执行来优化重排过程。浏览器会将修改操作放入到队列里,直到过了一段时间或者操作达到了一个阈值,才清空队�?
当你获取布局信息的操作的时候,会强制队列刷新,包括前面讲到的offsetTop等方法都会返回最新的数据

因此浏览器不得不清空队列,触发回流重绘来返回正确的�?

三、如何减�?

我们了解了如何触发回流和重绘的场景,下面给出避免回流的经验:

  • 如果想设定元素的样式,通过改变元素�?class 类名 (尽可能在 DOM 树的最里层)
  • 避免设置多项内联样式
  • 应用元素的动画,使用 position 属性的 fixed 值或 absolute �?如前文示例所�?
  • 避免使用 table 布局,table 中每个元素的大小以及内容的改动,都会导致整个 table 的重新计�?- 对于那些复杂的动画,对其设置 position: fixed/absolute,尽可能地使元素脱离文档流,从而减少对其他元素的影�?- 使用css3硬件加速,可以让transformopacityfilters这些动画不会引起回流重绘
  • 避免使用 CSS �?JavaScript 表达�?
    在使�?JavaScript 动态插入多个节点时, 可以使用DocumentFragment. 创建后一次插�? 就能避免多次的渲染性能

但有时候,我们会无可避免地进行回流或者重绘,我们可以更好使用它们

例如,多次修改一个把元素布局的时候,我们很可能会如下操作

1
2
3
4
5
const el = document.getElementById('el')
for(let i=0;i<10;i++) {
el.style.top = el.offsetTop + 10 + "px";
el.style.left = el.offsetLeft + 10 + "px";
}

每次循环都需要获取多次offset属性,比较糟糕,可以使用变量的形式缓存起来,待计算完毕再提交给浏览器发出重计算请求

1
2
3
4
5
6
7
8
9
10
11
// 缓存offsetLeft与offsetTop的�?const el = document.getElementById('el')
let offLeft = el.offsetLeft, offTop = el.offsetTop

// 在JS层面进行计算
for(let i=0;i<10;i++) {
offLeft += 10
offTop += 10
}

// 一次性将计算结果应用到DOM�?el.style.left = offLeft + "px"
el.style.top = offTop + "px"

我们还可避免改变样式,使用类名去合并样式

1
2
3
4
5
const container = document.getElementById('container')
container.style.width = '100px'
container.style.height = '200px'
container.style.border = '10px solid red'
container.style.color = 'red'

使用类名去合并样�?

1
2
3
4
5
6
7
8
9
10
11
12
<style>
.basic_style {
width: 100px;
height: 200px;
border: 10px solid red;
color: red;
}
</style>
<script>
const container = document.getElementById('container')
container.classList.add('basic_style')
</script>

前者每次单独操作,都去触发一次渲染树更改(新浏览器不会)�?
都去触发一次渲染树更改,从而导致相应的回流与重绘过�?
合并之后,等于我们将所有的更改一次性发�?
我们还可以通过通过设置元素属性display: none,将其从页面上去掉,然后再进行后续操作,这些后续操作也不会触发回流与重绘,这个过程称为离线操�?

1
2
3
4
5
const container = document.getElementById('container')
container.style.width = '100px'
container.style.height = '200px'
container.style.border = '10px solid red'
container.style.color = 'red'

离线操作�?

1
2
3
4
5
6
7
8
let container = document.getElementById('container')
container.style.display = 'none'
container.style.width = '100px'
container.style.height = '200px'
container.style.border = '10px solid red'
container.style.color = 'red'
...(省略了许多类似的后续操作)
container.style.display = 'block'

参考文�?

面试官:让Chrome支持小于12px 的文字方式有哪些?区别?

一、背�?

Chrome 中文版浏览器会默认设定页面的最小字号是12px,英文版没有限制

原由 Chrome 团队认为汉字小于12px就会增加识别难度

  • 中文版浏览器

与网页语言无关,取决于用户在Chrome的设置里(chrome://settings/languages)把哪种语言设置为默认显示语言

  • 系统级最小字�?
    浏览器默认设定页面的最小字号,用户可以前往 chrome://settings/fonts 根据需求更�?
    而我们在实际项目中,不能奢求用户更改浏览器设�?
    对于文本需要以更小的字号来显示,就需要用到一些小技�?

二、解决方�?

常见的解决方案有�?

  • zoom
  • -webkit-transform:scale()
  • -webkit-text-size-adjust:none

Zoom

zoom 的字面意思是“变焦”,可以改变页面上元素的尺寸,属于真实尺�?
其支持的值类型有�?

  • zoom:50%,表示缩小到原来的一�?- zoom:0.5,表示缩小到原来的一�?
    使用 zoom 来”支持�?12px 以下的字�?
    代码如下�?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <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 并不是标准属性,需要考虑其兼容�?
image.png

-webkit-transform:scale()

针对chrome浏览�?加webkit前缀,用transform:scale()这个属性进行放�?
注意的是,使用scale属性只对可以定义宽高的元素生效,所以,下面代码中将span元素转为行内块元�?
实现代码如下�?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<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>

效果如下�?

-webkit-text-size-adjust:none

该属性用来设定文字大小是否根据设�?浏览�?来自动调整显示大�?
属性值:

  • percentage:字体显示的大小�?- auto:默认,字体大小会根据设�?浏览器来自动调整�?- none:字体大小不会自动调整
1
html { -webkit-text-size-adjust: none; }

这样设置之后会有一个问题,就是当你放大网页时,一般情况下字体也会随着变大,而设置了以上代码后,字体只会显示你当前设置的字体大小,不会随着网页放大而变大了

所以,我们不建议全局应用该属性,而是单独对某一属性使�?

需要注意的是,自从chrome 27之后,就取消了对这个属性的支持。同时,该属性只对英文、数字生效,对中文不生效

三、总结

Zoom 非标属性,有兼容问题,缩放会改变了元素占据的空间大小,触发重排

-webkit-transform:scale() 大部分现代浏览器支持,并且对英文、数字、中文也能够生效,缩放不会改变了元素占据的空间大小,页面布局不会发生变化

-webkit-text-size-adjust对谷歌浏览器有版本要求,�?7之后,就取消了该属性的支持,并且只对英文、数字生�?

参考文�?

面试官:什么是响应式设计?响应式设计的基本原理是什么?如何做?

一、是什�?

响应式网站设计(Responsive Web design)是一种网络页面设计布局,页面的设计与开发应当根据用户行为以及设备环�?系统平台、屏幕尺寸、屏幕定向等)进行相应的响应和调整

描述响应式界面最著名的一句话就是“Content is like water�?
大白话便是“如果将屏幕看作容器,那么内容就像水一样�?
响应式网站常见特点:

  • 同时适配PC + 平板 + 手机�?
  • 标签导航在接近手持终端设备时改变为经典的抽屉式导�?
  • 网站的布局会根据视口来调整模块的大小和位置

二、实现方�?

响应式设计的基本原理是通过媒体查询检测不同的设备屏幕尺寸做处理,为了处理移动端,页面头部必须有meta声明viewport

1
<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查询,可以针对不同的媒体类型定义不同的样式,如:

1
@media screen and (max-width: 1920px) { ... }

当视口在375px - 600px之间,设置特定字体大�?8px

1
2
3
4
5
@media screen (min-width: 375px) and (max-width: 600px) {
body {
font-size: 18px;
}
}

通过媒体查询,可以通过给不同分辨率的设备编写不同的样式来实现响应式的布局,比如我们为不同分辨率的屏幕,设置不同的背景图片

比如给小屏幕手机设置@2x图,为大屏幕手机设置@3x图,通过媒体查询就能很方便的实现

百分�?

通过百分比单�?” % “ 来实现响应式的效�?
比如当浏览器的宽度或者高度发生变化时,通过百分比单位,可以使得浏览器中的组件的宽和高随着浏览器的变化而变化,从而实现响应式的效�?
heightwidth属性的百分比依托于父标签的宽高,但是其他盒子属性则不完全依赖父元素�?

  • 子元素的top/left和bottom/right如果设置百分比,则相对于直接非static定位(默认定位)的父元素的高�?宽度

  • 子元素的padding如果设置百分比,不论是垂直方向或者是水平方向,都相对于直接父亲元素的width,而与父元素的height无关�?

  • 子元素的margin如果设置成百分比,不论是垂直方向还是水平方向,都相对于直接父元素的width

  • border-radius不一样,如果设置border-radius为百分比,则是相对于自身的宽�?
    可以看到每个属性都使用百分比,会照成布局的复杂度,所以不建议使用百分比来实现响应�?

vw/vh

vw表示相对于视图窗口的宽度,vh表示相对于视图窗口高度�?任意层级元素,在使用vw单位的情况下,1vw都等于视图宽度的百分之一

与百分比布局很相似,在以前文章提过与%的区别,这里就不再展开述说

rem

在以前也讲到,rem是相对于根元素htmlfont-size属性,默认情况下浏览器字体大小为16px,此时1rem = 16px

可以利用前面提到的媒体查询,针对不同设备分辨率改变font-size的值,如下�?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@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标签,内容如下:

1
2
3
4
5
6
7
8
9
10
//动态为根元素设置字体大�?function init () {
// 获取屏幕宽度
var width = document.documentElement.clientWidth
// 设置根元素字体大小。此时为宽的10等分
document.documentElement.style.fontSize = width / 10 + 'px'
}

//首次加载应用,设置一�?init()
// 监听手机旋转的事件的时机,重新设�?window.addEventListener('orientationchange', init)
// 监听手机窗口变化,重新设�?window.addEventListener('resize', init)

无论设备可视窗口如何变化,始终设置remwidth�?/10,实现了百分比布局

除此之外,我们还可以利用主流UI框架,如:element uiantd提供的栅格布局实现响应�?

小结

响应式设计实现通常会从以下几方面思考:

  • 弹性盒子(包括图片、表格、视频)和媒体查询等技�?- 使用百分比布局创建流式布局的弹性UI,同时使用媒体查询限制元素的尺寸和内容变更范�?- 使用相对单位使得内容自适应调节
  • 选择断点,针对不同断点实现不同布局和内容展�?

三、总结

响应式布局优点可以看到�?

  • 面对不同分辨率设备灵活性强
  • 能够快捷解决多设备显示适应问题

缺点�?

  • 仅适用布局、信息、框架并不复杂的部门类型网站
  • 兼容各种设备工作量大,效率低�?- 代码累赘,会出现隐藏无用的元素,加载时间加长
  • 其实这是一种折中性质的设计解决方案,多方面因素影响而达不到最佳效�?- 一定程度上改变了网站原有的布局结构,会出现用户混淆的情�?

参考文�?- https://baike.baidu.com/item/%E5%93%8D%E5%BA%94%E5%BC%8F%E7%BD%91%E9%A1%B5%E8%AE%BE%E8%AE%A1

面试官:说说对Css预编语言的理解?有哪些区�?

一、是什�?

Css 作为一门标记性语言,语法相对简单,对使用者的要求较低,但同时也带来一些问�?
需要书写大量看似没有逻辑的代码,不方便维护及扩展,不利于复用,尤其对于非前端开发工程师来讲,往往会因为缺�?Css 编写经验而很难写出组织良好且易于维护�?Css 代码

Css预处理器便是针对上述问题的解决方�?

预处理语言

扩充�?Css 语言,增加了诸如变量、混合(mixin)、函数等功能,让 Css 更易维护、方�?
本质上,预处理是Css的超�?
包含一套自定义的语法及一个解析器,根据这些语法定义自己的样式规则,这些规则最终会通过解析器,编译生成对应�?Css 文件

二、有哪些

Css预编译语言在前端里面有三大优秀的预编处理器,分别是�?

  • sass
  • less
  • stylus

sass

2007 年诞生,最早也是最成熟�?Css 预处理器,拥�?Ruby 社区的支持和 Compass 这一最强大�?Css 框架,目前受 LESS 影响,已经进化到了全面兼�?Css �?Scss

文件后缀名为.sassscss,可以严格按�?sass 的缩进方式省去大括号和分�?

less

2009年出现,受SASS的影响较大,但又使用 Css 的语法,让大部分开发者和设计师更容易上手,在 Ruby 社区之外支持者远超过 SASS

其缺点是比起 SASS 来,可编程功能不够,不过优点是简单和兼容 Css,反过来也影响了 SASS 演变到了 Scss 的时�?

stylus

Stylus 是一个Css的预处理框架�?010 年产生,来自 Node.js 社区,主要用来给 Node 项目进行 Css 预处理支�?
所以 Stylus 是一种新型语言,可以创建健壮的、动态的、富有表现力的 Css。比较年轻,其本质上做的事情与SASS/LESS等类�?

三、区�?

虽然各种预处理器功能强大,但使用最多的,还是以下特性:

  • 变量(variables�?- 作用域(scope�?- 代码混合�?mixins�?- 嵌套(nested rules�?- 代码模块化(Modules�?
    因此,下面就展开这些方面的区�?

基本使用

less和scss

1
2
3
.box {
display: block;
}

sass

1
2
.box
display: block

stylus

1
2
.box
display: block

嵌套

三者的嵌套语法都是一致的,甚至连引用父级选择器的标记 & 也相�?
区别只是 Sass �?Stylus 可以用没有大括号的方式书�?
less

1
2
3
4
5
.a {
&.b {
color: red;
}
}

变量

变量无疑�?Css 增加了一种有效的复用方式,减少了原来�?Css 中无法避免的重复「硬编码�?
less声明的变量必须以@开头,后面紧跟变量名和变量值,而且变量名和变量值需要使用冒号:分隔开

1
2
3
4
5
@red: #c00;

strong {
color: @red;
}

sass声明的变量跟less十分的相似,只是变量名前面使用@开�?

1
2
3
4
5
$red: #c00;

strong {
color: $red;
}

stylus声明的变量没有任何的限定,可以使用$开头,结尾的分号;可有可无,但变量与变量值之间需要使用=

stylus中我们不建议使用@符号开头声明变�?

1
2
3
4
red = #c00

strong
color: red

作用�?

Css 预编译器把变量赋予作用域,也就是存在生命周期。就�?js 一样,它会先从局部作用域查找变量,依次向上级作用域查�?
sass中不存在全局变量

1
2
3
4
5
6
7
8
9
10
$color: black;
.scoped {
$bg: blue;
$color: white;
color: $color;
background-color:$bg;
}
.unscoped {
color:$color;
}

编译�?

1
2
3
4
5
6
7
.scoped {
color:white;/*是白�?/
background-color:blue;
}
.unscoped {
color:white;/*白色(无全局变量概念�?/
}

所以,在sass中最好不要定义相同的变量�?

lessstylus的作用域跟javascript十分的相似,首先会查找局部定义的变量,如果没有找到,会像冒泡一样,一级一级往下查找,直到根为�?

1
2
3
4
5
6
7
8
9
10
@color: black;
.scoped {
@bg: blue;
@color: white;
color: @color;
background-color:@bg;
}
.unscoped {
color:@color;
}

编译后:

1
2
3
4
5
6
7
.scoped {
color:white;/*白色(调用了局部变量)*/
background-color:blue;
}
.unscoped {
color:black;/*黑色(调用了全局变量�?/
}

混入

混入(mixin)应该说是预处理器最精髓的功能之一了,简单点来说,Mixins可以将一部分样式抽出,作为单独定义的模块,被很多选择器重复使�?
可以在Mixins中定义变量或者默认参�?
less中,混合的用法是指将定义好的ClassA中引入另一个已经定义的Class,也能使用够传递参数,参数变量为@声明

1
2
3
4
5
6
7
8
9
10
11
12
13
.alert {
font-weight: 700;
}

.highlight(@color: red) {
font-size: 1.2em;
color: @color;
}

.heads-up {
.alert;
.highlight(red);
}

编译�?

1
2
3
4
5
6
7
8
.alert {
font-weight: 700;
}
.heads-up {
font-weight: 700;
font-size: 1.2em;
color: red;
}

Sass声明mixins时需要使用@mixinn,后面紧跟mixin的名,也可以设置参数,参数名为变量$声明的形�?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@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名,然后在定义参数和默认值之间用等号�?)来连接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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代码分成一个个模块

scsslessstylus三者的使用方法都如下所�?

1
2
3
4
@import './common';
@import './github-markdown';
@import './mixin';
@import './variables';

参考文�?

面试官:css选择器有哪些?优先级?哪些属性可以继承?

一、选择�?CSS选择器是CSS规则的第一部分

它是元素和其他部分组合起来告诉浏览器哪个HTML元素应当是被选为应用规则中的CSS属性值的方式

选择器所选择的元素,叫做“选择器的对象�?
我们从一个Html结构开�?

1
2
3
4
5
6
7
8
9
10
11
<div id="box">
<div class="one">
<p class="one_1">
</p >
<p class="one_1">
</p >
</div>
<div class="two"></div>
<div class="two"></div>
<div class="two"></div>
</div>

关于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的所有元�?

还有一些使用频率相对没那么多的选择器:

  • 伪类选择�?

    1
    2
    :link :选择未被访问的链�?:visited:选取已被访问的链�?:active:选择活动链接
    :hover :鼠标指针浮动在上面的元�?:focus :选择具有焦点�?:first-child:父元素的首个子元素
  • 伪元素选择�?

    1
    2
    3
    :first-letter :用于选取指定选择器的首字�?:first-line :选取指定选择器的首行
    :before : 选择器在被选元素的内容前面插入内容
    :after : 选择器在被选元素的内容后面插入内容
  • 属性选择�?

    1
    2
    [attribute] 选择带有attribute属性的元素
    [attribute=value] 选择所有使用attribute=value的元�?[attribute~=value] 选择attribute属性包含value的元�?[attribute|=value]:选择attribute属性以value开头的元素

CSS3中新增的选择器有如下�?

  • 层次选择器(p~ul),选择前面有p元素的每个ul元素
  • 伪类选择�?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    :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> 不匹配的所有元�?```

    - 属性选择�?
    ```css
    [attribute*=value]:选择attribute属性值包含value的所有元�?[attribute^=value]:选择attribute属性开头为value的所有元�?[attribute$=value]:选择attribute属性结尾为value的所有元�?```



    ## 二、优先级

    相信大家对`CSS`选择器的优先级都不陌生:

    > 内联 > ID选择�?> 类选择�?> 标签选择�?
    到具体的计算层⾯,优先级是由 AB、C、D 的值来决定的,其中它们的值计算规则如下:

    - 如果存在内联样式,那�?A = 1, 否则 A = 0

    - B的值等�?ID选择器出现的次数

    - C的值等�?类选择�?�?属性选择�?�?伪类 出现的总次�?
    - D 的值等�?标签选择�?�?伪元�?出现的总次�?
    这里举个例子�?
    ```css
    #nav-global > ul > li > a.nav-link

套用上面的算法,依次求出 A B C D 的值:

  • 因为没有内联样式 ,所�?A = 0

  • ID选择器总共出现�?次, B = 1

  • 类选择器出现了1次, 属性选择器出现了0次,伪类选择器出�?次,所�?C = (1 + 0 + 0) = 1

  • 标签选择器出现了3次, 伪元素出现了0次,所�?D = (3 + 0) = 3

上面算出的A �?BCD 可以简记作:(0, 1, 1, 3)

知道了优先级是如何计算之后,就来看看比较规则�?

  • 从左往右依次进行比�?,较大者优先级更高
  • 如果相等,则继续往右移动一位进行比�?- 如果4位全部相等,则后面的会覆盖前面的

经过上面的优先级计算规则,我们知道内联样式的优先级最高,如果外部样式需要覆盖内联样式,就需要使用!important

三、继承属�?

css中,继承是指的是给父元素设置一些属性,后代元素会自动拥有这些属�?
关于继承属性,可以分成�?

  • 字体系列属�?

    1
    2
    font:组合字体
    font-family:规定元素的字体系�?font-weight:设置字体的粗�?font-size:设置字体的尺�?font-style:定义字体的风�?font-variant:偏大或偏小的字体
  • 文本系列属�?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    text-indent:文本缩�?text-align:文本水平对�?line-height:行�?word-spacing:增加或减少单词间的空白
    letter-spacing:增加或减少字符间的空白
    text-transform:控制文本大小写
    direction:规定文本的书写方向
    color:文本颜�?```

    - 元素可见�?
    ```css
    visibility
  • 表格布局属�?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    caption-side:定位表格标题位�?border-collapse:合并表格边�?border-spacing:设置相邻单元格的边框间的距�?empty-cells:单元格的边框的出现与消�?table-layout:表格的宽度由什么决�?```

    - 列表属�?
    ```css
    list-style-type:文字前面的小点点样�?list-style-position:小点点位置
    list-style:以上的属性可通过这属性集�?```

    - 引用

    ```css
    quotes:设置嵌套引用的引号类型
  • 光标属�?

    1
    cursor:箭头可以变成需要的形状

继承中比较特殊的几点�?

  • a 标签的字体颜色不能被继承

  • h1-h6标签字体的大下也是不能被继承�?

无继承的属�?

  • 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

参考文�?

面试官:如何实现单行/多行文本溢出的省略样式�?

一、前言

在日常开发展示页面,如果一段文本的数量过长,受制于元素宽度的因素,有可能不能完全显示,为了提高用户的使用体验,这个时候就需要我们把溢出的文本显示成省略�?
对于文本的溢出,我们可以分成两种形式�?

  • 单行文本溢出
  • 多行文本溢出

二、实现方�?

单行文本溢出省略

理解也很简单,即文本在一行内显示,超出部分以省略号的形式展现

实现方式也很简单,涉及的css属性有�?

  • text-overflow:规定当文本溢出时,显示省略符号来代表被修剪的文�?- white-space:设置文字在一行显示,不能换行
  • overflow:文字长度超出限定宽度,则隐藏超出的内容

overflow设为hidden,普通情况用在块级元素的外层隐藏内部溢出元素,或者配合下面两个属性实现文本溢出省�?
white-space:nowrap,作用是设置文本不换行,是overflow:hiddentext-overflow:ellipsis生效的基础

text-overflow属性值有如下�?

  • clip:当对象内文本溢出部分裁切掉
  • ellipsis:当对象内文本溢出时显示省略标记�?..�?
    text-overflow只有在设置了overflow:hiddenwhite-space:nowrap才能够生效的

举个例子

1
2
3
4
5
6
7
8
9
10
11
12
<style>
p{
overflow: hidden;
line-height: 40px;
width:400px;
height:40px;
border:1px solid red;
text-overflow: ellipsis;
white-space: nowrap;
}
</style>
<p 这是一些文本这是一些文本这是一些文本这是一些文本这是一些文本这是一些文本这是一些文本这是一些文本这是一些文本这是一些文�?/p >

效果如下�?

可以看到,设置单行文本溢出较为简单,并且省略号显示的位置较好

多行文本溢出省略

多行文本溢出的时候,我们可以分为两种情况�?

  • 基于高度截断
  • 基于行数截断

基于高度截断

伪元�?+ 定位

核心的css代码结构如下�?

  • position: relative:为伪元素绝对定�?- overflow: hidden:文本溢出限定的宽度就隐藏内容)
  • position: absolute:给省略号绝对定�?- line-height: 20px:结合元素高�?高度固定的情况下,设定行高, 控制显示行数
  • height: 40px:设定当前元素高�?- ::after {} :设置省略号样式

代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<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使一个单词能够在换行时进行拆�?

基于行数截断

css实现也非常简单,核心的css代码如下�?

  • -webkit-line-clamp: 2:用来限制在一个块元素显示的文本的行数,为了实现该效果,它需要组合其他的WebKit属性)
  • display: -webkit-box:和1结合使用,将对象作为弹性伸缩盒子模型显�?
  • -webkit-box-orient: vertical:和1结合使用 ,设置或检索伸缩盒对象的子元素的排列方�?
  • overflow: hidden:文本溢出限定的宽度就隐藏内�?- text-overflow: ellipsis:多行文本的情况下,用省略号“…”隐藏溢出范围的文本
1
2
3
4
5
6
7
8
9
10
11
12
13
<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 >

可以看到,上述使用了webkitCSS属性扩展,所以兼容浏览器范围是PC端的webkit内核的浏览器,由于移动端大多数是使用webkit,所以移动端常用该形�?
需要注意的是,如果文本为一段很长的英文或者数字,则需要添加word-wrap: break-word属�?
还能通过使用javascript实现配合css,实现代码如下所示:

css结构如下�?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
p {
position: relative;
width: 400px;
line-height: 20px;
overflow: hidden;

}
.p-after:after{
content: "...";
position: absolute;
bottom: 0;
right: 0;
padding-left: 40px;
background: -webkit-linear-gradient(left, transparent, #fff 55%);
background: -moz-linear-gradient(left, transparent, #fff 55%);
background: -o-linear-gradient(left, transparent, #fff 55%);
background: linear-gradient(to right, transparent, #fff 55%);
}

javascript代码如下�?

1
2
3
4
5
6
7
8
9
10
11
12
$(function(){
//获取文本的行高,并获取文本的高度,假设我们规定的行数是五行,那么对超过行数的部分进行限制高度,并加上省略�? $('p').each(function(i, obj){
var lineHeight = parseInt($(this).css("line-height"));
var height = parseInt($(this).height());
if((height / lineHeight) >3 ){
$(this).addClass("p-after")
$(this).css("height","60px");
}else{
$(this).removeClass("p-after");
}
});
})

参考文�?

面试官:CSS如何画一个三角形?原理是什么?

一、前言

在前端开发的时候,我们有时候会需要用到一个三角形的形状,比如地址选择或者播放器里面播放按钮

通常情况下,我们会使用图片或者svg去完成三角形效果图,但如果单纯使用css如何完成一个三角形呢?

实现过程似乎也并不困难,通过边框就可完成

二、实现过�?

在以前也讲过盒子模型,默认情况下是一个矩形,实现也很简�?

1
2
3
4
5
6
7
8
9
<style>
.border {
width: 50px;
height: 50px;
border: 2px solid;
border-color: #96ceb4 #ffeead #d9534f #ffad60;
}
</style>
<div class="border"></div>

效果如下图所示:

border设置50px,效果图如下所示:

白色区域则为widthheight,这时候只需要你将白色区域部分宽高逐渐变小,最终变�?,则变成如下图所示:

这时候就已经能够看到4个不同颜色的三角形,如果需要下方三角形,只需要将上、左、右边框设置�?就可以得到下方的红色三角�?

但这种方式,虽然视觉上是实现了三角形,但实际上,隐藏的部分任然占据部分高度,需要将上方的宽度去�?
最终实现代码如下:

1
2
3
4
5
6
7
.border {
width: 0;
height: 0;
border-style:solid;
border-width: 0 50px 50px;
border-color: transparent transparent #d9534f;
}

如果想要实现一个只有边框是空心的三角形,由于这里不能再使用border属性,所以最直接的方法是利用伪类新建一个小一点的三角形定位上�?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.border {
width: 0;
height: 0;
border-style:solid;
border-width: 0 50px 50px;
border-color: transparent transparent #d9534f;
position: relative;
}
.border:after{
content: '';
border-style:solid;
border-width: 0 40px 40px;
border-color: transparent transparent #96ceb4;
position: absolute;
top: 0;
left: 0;
}

效果图如下所示:

i

伪类元素定位参照对象的内容区域宽高都�?,则内容区域即可以理解成中心一点,所以伪元素相对中心这点定位

将元素定位进行微调以及改变颜色,就能够完成下方效果图�?

最终代码如下:

1
2
3
4
5
6
7
8
9
.border:after {
content: '';
border-style: solid;
border-width: 0 40px 40px;
border-color: transparent transparent #96ceb4;
position: absolute;
top: 6px;
left: -40px;
}

三、原理分�?

可以看到,边框是实现三角形的部分,边框实际上并不是一个直线,如果我们将四条边设置不同的颜色,将边框逐渐放大,可以得到每条边框都是一个梯�?

当分别取消边框的时候,发现下面几种情况�?

  • 取消一条边的时候,与这条边相邻的两条边的接触部分会变成直的
  • 当仅有邻边时�?两个边会变成对分的三�?- 当保留边没有其他接触时,极限情况所有东西都会消�?

通过上图的变化规则,利用旋转、隐藏,以及设置内容宽高等属性,就能够实现其他类型的三角�?
如设置直角三角形,如上图倒数第三行实现过程,我们就能知道整个实现原理

实现代码如下�?

1
2
3
4
5
6
7
8
9
10
11
.box {
/* 内部大小 */
width: 0px;
height: 0px;
/* 边框大小 只设置两条边*/
border-top: #4285f4 solid;
border-right: transparent solid;
border-width: 85px;
/* 其他设置 */
margin: 50px;
}

参考文�?

0%