九宫格经典面试题
1. 前言
其实面试有时候并不像大家想象的那样问一些很基础的问题,比如:
请谈一下你对CSS盒模型的理解 你对flex布局了解的怎么样 了解过grid布局吗 当元素的外边距为负值时会有什么样的行为 当元素重叠在一起时如何控制上下层级 如何水平垂直居中 什么是事件冒泡 怎么控制特定位置的元素样式(比如偶数位置的样式) 如何判断事件是从哪个元素冒泡过来的 哪个CSS 属性 值可以减少重复定义颜色值
这样问的话效率会比较低,而优秀的面试题只需要一道,就可以考察上述所有的这些问题。
2. 面试题
即使候选者对上面这些问题全部都对答如流,也不一定能够灵活的运用这些知识。
而这道面试题不仅考察了候选人的基础,更考察了候选者对基础知识的灵活运用,来看看这道面试题:
(鼠标点击可以互动)
要求如下:
边框九宫格的每个格子中的数字都要居中 鼠标经过时边框和数字都要变红 格子中的数字居中用flex实现 点击九宫格会弹出对应的数字
具体实现如下:
<!DOCTYPE html> < html lang = " en " > < head > < Meta charset = " UTF-8 " > < Meta name = " viewport " content = " width=device-width, initial-scale=1.0 " > < title > Document </ title > < style > /* 清除 默 认样式 */ * { padding : ; margin : ; } /* 全屏 显示 */ html, body { height : } body { /* 网格布局 */ dis play : grid ; /* 子元素居中 */ place-items : center ; } /* 父元素 */ ul { width : px ; /* 清除 默 认样式 */ list-style : none ; /* 设置为flex布局 */ dis play : flex ; /* 设置换行 */ flex-flow : wrap ; } /* 子元素 */ li { /* 显示 为网格布局 */ dis play : grid ; /* 子元素水平垂直居中 */ place-items : center ; /* 宽高都是100像素 */ width : px ; height : px ; /* 设置盒模型 */ Box -sizing : border- Box ; /* 设置两像素的边框 */ border : px solid black ; /* 负边距 */ margin : -px -px ; } /* 第1、4、7个子元素 */ li :nth-child(3n+1) { /* 取消左负边距 */ margin-left : } /* 前三个子元素 */ li :f irs t-child , li :nth-child(2), li:nth-child(3) { /* 取消上负边距 */ margin-top : } /* 当鼠标经过时 */ li :hover { /* 红色字体 */ color : red ; /* 红色边框 */ border : px solid ; /* 调高层级 */ z-index : ; } </ style > </ head > < body > < ul > < li > 1 </ li > < li > 2 </ li > < li > 3 </ li > < li > 4 </ li > < li > 5 </ li > < li > 6 </ li > < li > 7 </ li > < li > 8 </ li > < li > 9 </ li > </ ul > < script > // 选择ul元素 const ul = document . getElementsByTagName ( 'ul' ) [ ] // 监听ul元素的点击事件 ul . addEventListener ( 'click' , e => alert ( e . target . innerText ) ) </ script > </ body > </ html >
3. 面试题都考察了哪些上述知识呢
负边距:
li { margin : -px -px ; }
利用负边距可以消除边框粗的bug
flex
ul { /* 设置为flex布局 */ dis play : flex ; /* 设置换行 */ flex-flow : wrap ; }
grid布局、水平垂直居中
li { /* 网格布局 */ dis play : grid ; /* 子元素居中 */ place-items : center ; }
减少重复定义颜色值
li :hover { /* 红色字体 */ color : red ; /* 红色边框 */ border : px solid ; }
可以看到定义红色边框的时候并没有写红色( red或#f00 ),那是因为如果你不写的话, 默 认是 currentColor ,这个关键字代表的就是你当前的 color 值。
有些同学可能会觉得纳闷:这单词这么长,还不如直接写个red多方便啊,其实这个单词相当于 一个 变量,指向 color 值,而别忘了 color 是可以继承的!
如果在 一个 外层元素中定义了 一个 颜色,里面的子元素都可以继承,用 JS 来控制的话只需要 获取 外层DOM元素然后 修改 它的 color 样式即可,currentColor能做的事情很多,这里为了不跑题就先不展开讲,有兴趣的同学可以去搜一下。
CSS盒模型
li { /* 设置盒模型 */ Box -sizing : border- Box ; }
如果不写这个 属性 的话,每个格子的边框也会计算在内,最终会超过父元素的三分之一,导致提前换行。
大家可以在案例中去掉这个 属性 ,感受一下没有了它会发生什么样的后果。
上下层级
li :hover { z-index : ; }
如果没有这个 属性 ,在鼠标经过时边框的样式会产生错乱。
特定位置的元素样式
/* 第1、4、7个子元素 */ li :nth-child(3n+1) { xxx : xxx ; } /* 前三个子元素 */ li :f irs t-child , li :nth-child(2), li:nth-child(3) { xxx : xxx ; }
事件冒泡
// 监听ul元素的点击事件 ul . addEventListener ( 'click' , e => alert ( e . target . innerText ) )
4. 小结
怎么样,没想到就这一道九宫格居然能考察出这么多的基础知识吧?
同学们课下一定要好好练习一下这道题,亲 自动 手敲一遍 代码 ,看看能不能在不参照案例 代码 的情况实现这个 功能 。