考验你css功底的10道css面试题

847 阅读8分钟

css是每一名前端工程师的基本功,熟练掌握是基本要求,然而css看似简单,却并不代表能轻而易举就能掌握的好,没有长时间的积累,是很难精通的。下面列举一些考验功底的面试题

一、css三角形原理

实现起来看似很简单,毕竟就算新手,网上一搜代码就出来了,哈哈,但面试官一问其中的原理,估计很多人就答不上来了

html代码:
<div class="triangle"></div>

css代码:
. triangle{
    width:0;
    height: 0;
    border-width: 50px;
    border-color: red transparent transparent transparent;
    border-style: solid;
    margin: 10px auto;
}

这只是展示了顶部方向的三角形,因为其它方向的颜色都设为transparent透明了,如果每个方向的颜色都存在,就有意思了:

把上面的css代码改为:
. triangle{
    width:0;
    height: 0;
    border-width: 50px;
    border-color: red blue  yellow green; 
    border-style: solid;
    margin: 10px auto;
}

进一步,如果我们把上面的宽和高都加上,会是怎样的呢?

. triangle{
    width:100px;
    height: 100px;
    border-width: 50px;
    border-color: red blue  yellow green;
    border-style: solid;
    margin: 100px auto;
}

border的呈现是不是很有意思,哈哈。

原理:css的border并不是矩形的,而是一个等腰梯形,所以width和height都设为0时,border就成了等腰三角形了,如果想要得到某个方向的三角形,那么把其它边的border-color设为transparent透明即可

二、position定位的原理

position的取值有relative、absolute、fixed、static,sticky(css3的粘性布局)

relative:相对于自身位置进行定位;
absolute: 相对于非static定位的父元素进行定位;
fixed:相对于html根元素进行定位;
static:(默认)不进行定位;
sticky:粘性定位;

三、flex布局和传统的布局有什么不同,为什么要确定主轴、侧轴?

传统布局:基于盒模型,依赖 display属性 、position属性 、float属性

flex布局:flex 是 flexible Box 的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性。

1. 设为display:flex的元素称为"容器",它的子元素称为"项目"。需要注意的是,容器设为 flex 布局以后,子元素的float、clear和vertical-align属性将失效

2. 主轴和侧轴是通过flex-direction确定的(默认是row) 之所以要确定主轴,是因为要确定项目的对齐方向:
如果flex-direction是row或者row-reverse,那么主轴就是justify-content;
如果flex-direction是column或者column-reverse,那么主轴就是align-items.

主轴上比较好理解,重点是交叉轴上。因为交叉轴上存在单行和多行两种情况。 align-items:默认值是stretch,当元素没有设置具体尺寸时会将容器在交叉轴方向撑满。当align-items不为stretch时,此时除了对齐方式会改变之外,元素在交叉轴方向上的尺寸将由内容或自身尺寸(宽高)决定。

更多有关flex布局的知识,可以看阮一峰大神的有关文章 www.ruanyifeng.com/blog/2015/0…

四、实现一个div,垂直居中于body,并且高恒等于宽的一半,距离body左右两侧各10px

垂直居中的方法很多,大家可以去网上查看相关文章,这里重点说下高恒等于宽的一半的实现。 calc() 函数用于动态计算长度值,是css3新增的支持四则运算的属性

css代码

  html,body{
	 height: 100%;
	}
	.wrap{
	    width: 100%;
	    height: 100%;
	    display: flex;
	    align-items: center;
	}
	.box{
	    width: 100vw;
	    height: calc((100vw - 20px) / 2);
	    background: red;
	    text-align: center;
	    margin-left: 10px;
	    margin-right: 10px;
	}

html代码:

  <div class="wrap">
    	<div class="box">A</div>
    </div>

效果:

五、padding和margin设值为百分比时的依据是什么?

当一个div padding和margin设置为百分比时,实际上是根据这个div的最近的块级父元素width的值为基准值计算的,这一点一定要注意

.child-box{
            width: 100px;
            height: 100px;
            border: 1px solid #ccc;
            padding: 5%;
            background-color: blue;
            margin: 5%;
}
        }
        .parent-box{
            width: 200px;
            height: 200px;
            border: 1px #f00 solid;
            background-color: #f00;
        }
        
        <div class="parent-box">
            <div class="my-box"> </div>
         </div>

蓝色盒子的宽=100 + 5% * 200 *2 = 120px,即蓝色盒子的宽 = 自身width + 自身padding的5% * 红色父盒子的宽 * 2

六、line-heigt和font-size的关系是什么?

line-heigt和font-size是经常用到的属性,但很少有人注意他们的关系

行高是指两行文字的baseline之间的垂直距离 ,行距是上行底线与下行顶线之间的垂直距离,字体大小是一行文字的顶线与其底线之间的垂直距离;

由上图的关系可以看出,行高(line-heigt) = 字体大小(font-size) + 行距(即2 * 半行距)

七、vertical-align什么情况下才能生效?

.vertical-box{
            width: 200px;
            height: 200px;
            border: 1px solid #ccc;
            text-align: center;
        }
        .vertical-box span{
            vertical-align: middle;
            background-color: brown;
        }
        
         <div class="vertical-box"><span>vertical-align元素</span></div>

为什么上面的span元素没有垂直居中?

其实要用这个属性实现垂直居中,其实核心就在于这个需要一个满行高的行内元素来作为参考。在设置了vertical-align: middle的元素的同级元素内添加一个行高为父元素满高度的行内元素(如em)

如果我们加上:

.vertical-box em{
     line-height: 200px;
}
 <div class="vertical-box"><span>vertical-align元素</span><em></em></div>

这时候span就能垂直居中了!不过这样就增加了一个无用的em元素,其实还有一个办法,给父元素添加一个伪元素,设置其高为100%作为span的参考基准即可,这个做法对盒子中只有一个元素需要垂直居中时就很有用了。

八、ul标签里有4个li标签,设置li为inline-block,宽度为25%,为什么不能在一行显示?

.list{
     border: 1px #f60 solid;
}
.list li{
    display: inline-block;
    width: 25%;
    background-color: cornflowerblue;
}
<ul class="list">
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
</ul>

实际上4个li标签并没有在一排显示,为什么呢? 因为包含空格和换行!!如果我们把4个li标签放在一行看情况会怎样?

<ul class="list"><li>1</li><li>2</li><li>3</li><li>4</li></ul>

结果:

看到了吧,可以在一行显示了! 不过我们实际开发中内容多时不可能把所有的li标签放一行吧?那怎么办?有一个属性可以拯救:white-space: nowrap;

.list{
     border: 1px #f60 solid;
     white-space: nowrap;
}
.list li{
    display: inline-block;
    width: 25%;
    background-color: cornflowerblue;
}

这时li标签就能在一行显示了:

九、css伪元素和伪类有什么区别?

其实很简单,这两个东西都带一个“伪”字,但一个本质是"元素" ,一个本质是"类",CSS3对伪类的定义:伪类存在的意义是为了通过选择器找到那些不存在与DOM树中的信息以及不能被常规CSS选择器获取到的信息。伪类由一个冒号:开头,冒号后面是伪类的名称,CSS3中伪元素的定义:伪元素在DOM树中创建了一些抽象元素,这些抽象元素是不存在于文档语言里的(可以理解为html源码)。比如:document接口不提供访问元素内容的第一个字或者第一行的机制,而伪元素可以使开发者可以提取到这些信息。并且,一些伪元素可以使开发者获取到不存在于源文档中的内容(比如常见的::before,::after)。

其实可以这么区分:伪类的操作对象是文档树中已有的元素,而伪元素则创建了一个文档额外的元素。

十、px、rem、em、vh,vw这些单位的区别?

px:就是像素,也是我们现在经常使用的基本单位,比如常常听到的电脑像素是1024x768的,表示的是水平方向是1024个像素点,垂直方向是768个像素;

em:参考物是父元素的font-size,默认字体大小是16px,所以1em不是固定值,因为它会继承父元素的字体大小;

rem:参考物是相对于根元素,我们在使用时可以在根元素设置一个参考值即可,相对于em使用,减少很大运算工作量,例:设置根元素html的font-size:12px,1rem就是12px

vw:css3新单位,viewpoint's width的缩写,视窗宽度,1vw等于window.innerWidth的1%。

vh:css3新单位,viewpoint's height的缩写,视窗高度,1vh等window.innerHeight的1%。

vmax:vmin的值是当前vw和vh中较大的值。

vmin:vmin的值是当前vw和vh中较小的值。

好了,今天就写到这里了,欢迎补充~