CSS相关面试点-2021

284 阅读8分钟

我看大家都在找工作,分享点相关知识,为大家省点时间。

flex布局介绍

Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。 任何一个容器都可以指定为 Flex 布局。

.box{
  display: flex;
}

行内元素也可以使用 Flex 布局。

.box{
  display: inline-flex;
}

Webkit 内核的浏览器,必须加上-webkit前缀。

.box{
  display: -webkit-flex; /* Safari */
  display: flex;
}

注意,设为 Flex 布局以后,子元素的floatclearvertical-align属性将失效。

flex:1代表什么意思

利用 flex: 1; 实现了不同内容的 div 平分空间

那么 flex: 1; === flex: 1 1 auto; 吗?

第一个参数表示: flex-grow 定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大

第二个参数表示: flex-shrink 定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小

第三个参数表示: flex-basis给上面两个属性分配多余空间之前, 计算项目是否有多余空间, 默认值为 auto, 即项目本身的大小

所以得出结论:flex: 1 !== flex: 1 1 auto;

flex: 1; === flex: 1 1 0;

如若让你用flex布局完成左边宽度200px固定,右边自适应,该如何做?

<div class="div">
            <style>
                .div {
                    display: flex;
                    background-color: pink;
                }

                .zuo {
                    width: 200;
                    background-color: yellow;
                }

                .you {
                    flex: 1;
                    background-color: blue;
                }
            </style>
            <div class="zuo">zuo</div>
            <div class="you">you</div>
        </div>

更多布局知识参见 前端基础6/1-页面布局

给span加高度,怎么做?有几种方法

1:display设置为inline-block

display: inline-block;
height: 500px;

2:display设置为block

不确定宽高的div如何设置垂直水平居中?

1:flex弹性布局

<style>
            .one {
                width: 100%;
                height: 500px;
                background-color: royalblue;
                /* 弹性布局 */
                display: flex;
                /* 水平居中 */
                justify-content: space-around;
                align-items: center;
            }

            .two {
                background-color: yellowgreen;
            }
        </style>
        <div class="one">
            <div class="two">wo </div>
        </div>

2:利用css3和定位的方法

<style>
    
 .one {
position: relative;
width: 200px;
height: 200px;
background-color: rebeccapurple;
}

.two {
position: absolute;
top: 50%;
left: 50%;
transform: translate( -50%, -50%);
}
</style>

< div class= "one" >
< div class= "two" >wo </ div >
</ div >

3:利用table-cell

<style>
    
.one {
display: table-cell;
text-align: center;
vertical-align: middle;
width: 100px;
height: 100px;
background-color: red;
}

.two {
vertical-align: middle;
display: inline-block;
}
</style>
< div class= "one" >
< div class= "two" >wo </ div >
</ div >

:nth-child和:nth-of-type的区别

<!DOCTYdivE html>
    <html lang="en">

    <head>
        <meta charset="UTF-8">
        <meta httdiv-equiv="X-UA-Comdivatible" content="IE=edge">
        <meta name="viewdivort" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            :nth-child(5) {
                color: red;
            }

            :nth-of-type(5) {
                color: blue;
            }
        </style>

    </head>

    <body>
        <ul>

            <li>1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
            <span>sb</span>
            <li>5</li>
            <li>6</li>
        </ul>
    </body>

    </html>

image.png :nth-of-type(n)选择器是匹配属于父元素的特定类型的第N个子元素,元素类型是有限制的;

:nth-child(n)选择器是匹配属于其父元素的第N个子元素,元素类型是没有限制的。

标准盒模型和怪异盒模型的区别

具体详参 前端基础6/2-盒模型

标准盒模型(W3C的标准盒子模型)

标准盒模型就是W3C的标准盒子模型 内盒尺寸(大小)=width+padding+border 外盒尺寸(空间尺寸)= width+padding+border+margin

怪异盒模型(IE盒模型)

怪异盒模型就是IE盒模型 内盒尺寸(大小)=width 外盒尺寸(空间尺寸)= width+ margin

image.png

实现动态换肤功能,如何实现?

1. 利用class 命名空间

根据主题设置不同的类名,在类名下设置不同样式。

  • 优点
    • 实现简单,易理解
    • 兼容性好
  • 缺点
    • 易产生css优先级问题,造成代码混乱
    • 代码冗余
    • 不适用于用户自定义主题的场景

2. 准备多套CSS主题

生成多套主题css文件,根据需要切换css文件href

  • 优点
    • 易实现
  • 缺点
    • 代码冗余
    • 下载css需要额外时间,用户体验不佳

3. css变量

利用css变量设置颜色,需要切换主题时,用js动态改变css变量的值。易理解易实现,兼容大部分浏览器(除了IE),并且支持动态换肤。

在根标签下声明变量

// global.less 
:root { --background-color: #000;
--text-color: #fff;
}

定义不同主题下的变量值

// theme.js
module.exports = {
  DARK: {
    '--background-color': '#000',
    '--text-color': '#fff',
  },
  LIGHT: {
    '--background-color': '#fff',
    '--text-color': '#000',
  },
}

在需要换肤的样式中使用变量(第二参数是默认值,为了兼容性考虑)

// app.less
#app { 
background: var(--background-color, #000);
color: var(--text-color, #fff);
}

根据需求场景更改css变量

// app.vue
...
created() {
    .getTheme()
        .then(({theme}) => {
          if (appTheme === 'LIGHT') {
            Object.keys(THEME.DARK).forEach((key) => {
              document.documentElement.style.setProperty(key, THEME.LIGHT[key])
            })
          }
        })
  },

less了解过吗?使用过其中哪些?

Less 的出现是为了解决 CSS 中过于呆板的写法。 Less 官方文档 中对 Less 的使用有详细的介绍,总结一下为:Less = 变量 + 混合 + 函数。如果你对 js 和 css 有所了解,那么就可以很快的掌握并在你的项目中使用 Less。

变量

在前面介绍的案例中已经使用了“变量”的概念,是不是感觉和 js 很像,事实上 less 就是用 js 的写法来写 css。

官网在介绍变量的时候会给出很多应用场景,总结一下就是使用 @ 符号定义变量,使用 @ 符号获取变量,仅仅将 @变量名 看成是一个字符串。

@classname: main;
@color: red;

.@classname{
    background-color: @color;
}

从上面例子中可以看到,变量不仅仅可以作为样式属性值:background-color: @color;,还可以作为类名:.@classname 表示的就是 .main。这也就是为什么说仅仅将 @变量名 看成是一个字符串。

混合

  • 混合也是减少代码书写量的一个方法;

  • 混合的类名在定义的时候加上小括弧 (),那么在转译成 css 文件时就不会出现;

  • 混合的类名在被调用的时候加上小括弧 ()和不加上小括弧 ()是一样的效果,看个人习惯,

函数

曾几何时,在书写呆板的 css 时有没有想过让类名动态化,根据不同的参数生成不同的样式。看下面的示例:

// func.less
.border-radius(@radius) {
  -webkit-border-radius: @radius;
     -moz-border-radius: @radius;
          border-radius: @radius;
}

#header {
  .border-radius(4px);
}
.button {
  .border-radius(6px);
}

使用 $ lessc func.less 进行转译 func.css 文件内容如下:

#header {
  -webkit-border-radius: 4px;
  -moz-border-radius: 4px;
  border-radius: 4px;
}
.button {
  -webkit-border-radius: 6px;
  -moz-border-radius: 6px;
  border-radius: 6px;
}

可以看到,这里就用到了函数的概念,在 #header.button 中分别传入不同的参数,结果也就生成不同的代码。

父子元素的写法

在 css 中父子元素的写法通常如下:

.container {
    padding: 0;
}
.container .article {
    background-color: red;
}

在 Less 写法如下,父子嵌套关系一目了然。

.container {
    padding: 0;
    .article {
        background-color: red;
    }
}

当然,父子元素还要一种是伪类的写法,在 css 中写法如下:

#header :after {
  content: " ";
  display: block;
  font-size: 0;
  height: 0;
  clear: both;
  visibility: hidden;
}

在 less 中写法如下,可以看到引入了新的符号 &,以 & 来代替主类 #header

#header {
  &:after {
    content: " ";
    display: block;
    font-size: 0;
    height: 0;
    clear: both;
    visibility: hidden;
  }
}

@import

在传统 css 文件中,每个文件都是独立的。在 less 中可以像 js 的模块那样在一个 less 文件中引入另一个 less 文件。

创建 one.less 文件:

.container {
  width: 100px;
  height: 200px;
}

创建 two.less 文件:

@import "one";

使用 $ lessc two.less 转译成 two.css 文件,可以看到内容如下:

.container {
  width: 100px;
  height: 200px;
}

@import 的作用可以看成是将 one.less 的内容复制一份到当前 .less 文件中。

移动端屏幕适配怎么做?

1. rem 布局

rem 是CSS3新增的一个相对单位,它以 HTML 元素的 font-size 为比例:

修改HTML元素的字体大小可以成比例的调整以 rem 为单位的属性,通过这一个特性,我们可以实现将视窗按一定比例划分为一份一份的,当页面内元素刚好分完所有的份数,页面内容即充满整个视窗且无横向滚动条。

以宽度750像素的设计稿为例,有两个元素,一个元素占 550 个像素,另一个占 750 个像素:

2. vw/vh 布局

vw/vh 方案与 rem 方案类似,都是将页面分成一份一份的,只不过 vw/vh 是将页面分为 100 份,1vw = device-width/100

优点:

  • vw、vh布局能良好的实现在不同尺寸的屏幕横向填满屏幕,使用 postcss-px-to-viewport 能很好的帮我们进行单位转换

缺点:

  • 无法修改 vw/vh 的值,在大屏设备(Pad)中元素会放大,且无法通过 js 干预
  • 兼容性- 大多数浏览器都支持、ie11不支持 少数低版本手机系统 ios8、android4.4以下不支持

3. 百分比布局

在 css 中,我们可以使用百分比来实现布局,但是需要特定宽度时,这个百分比的计算对开发者来说并不友好,且元素百分比参考的对象为父元素,元素嵌套较深时会有问题。

扩展: 子元素的 widthheight 百分比参考对象是父元素的 widthheightmarginpadding 的参考对象为父元素的 widthborder-radiusbackground-sizetransform: translate()transform-origin 的参考对象为自身宽高

4. 响应式布局

通过媒体查询,可以针对不同的屏幕进行单独设置,但是针对所有的屏幕尺寸做适配显然是不合理的,但是可以用来处理极端情况(例如 IPad 大屏设备)或做简单的适配(隐藏元素或改变元素位置)

CSS3 @media 查询属性详解

5. px 为主,搭配 vw/vh、媒体查询与 flex 进行布局

我们从页面编写的角度出发,页面中更多的是文本和布局,关于文本,我们应该使用 px 作为单位,来实现在大屏设备显示更多的内容,而不是更大的文本;关于布局,我们可以使用 flex 实现弹性布局,当实现特定宽高元素时,可以适当的使用 vw/vh,当特定的值使用 vw/vh 计算复杂或存在误差时,也可以使用rem

适配流程

  1. 编写 <meta> 标签设置 viewport 的内容 width=device-width,让网页宽度等于视窗宽度
  2. 在 css 中使用 px
  3. 在适当的场景使用flex布局,或者配合vw进行自适应
  4. 在跨设备类型的时候(pc <-> 手机 <-> 平板)使用媒体查询
  5. 在跨设备类型如果交互差异太大的情况,考虑分开项目开发

总结

上文简单总结了 5 种移动端适配方案

当前最流行的依然是第一种 rem 布局,能很好的按照设计稿进行开发,搭配媒体查询能让很好的解决大屏问题,比如:腾讯网荔枝FM

关于第二种 vw/vh 布局方案,我看到蛮多文章在推荐,由于还没有在项目中真正实践过,因为我们无法干预 vw/vh 的值,在大屏的体验应该不是很良好,所以不能做判断

关于第五种 px 为主,搭配 vw/vh、媒体查询与 flex 进行布局,个人认为部分地方可以引入 rem,也能很好的按照设计稿开发,且能解决大屏问题,可以参见:淘宝网百度网易

在我个人看来,第五种方案是很好的,但是暂时还没找到一套方法论来进行论证