我明白了,玩转前端面试CSS篇

简介: 前端面试 无非就是 CSS + JS + 框架 + 工具 + 源码 + 算法 + 职业规划 + 实战,这篇文章以及接下来的文章也是围绕这些内容依次展开。说到CSS,它现在已经非常的强大,已经支持了许多PS一般的功能了,但是我并不会去说那些部分东西,还是说说通用的或者基础的部分。首当其冲的是 BFC、弹性布局、垂直居中、移动端/响应式、css预处理、三角和缩放、大屏自适应。

前言

前端面试 无非就是 CSS + JS + 框架 + 工具 + 源码 + 算法 + 职业规划 + 实战,这篇文章以及接下来的文章也是围绕这些内容依次展开。

说到CSS,它现在已经非常的强大,已经支持了许多PS一般的功能了,但是我并不会去说那些部分东西,还是说说通用的或者基础的部分。

首当其冲的是 BFC、弹性布局、垂直居中、移动端/响应式、css预处理、三角和缩放、大屏自适应。

老说长谈的BFC

最开始学习布局的时候,必然会遇到高度塌陷的问题,通过解决这个问题,会慢慢触碰到BFC这个浏览器渲染规则。

高度塌陷

父元素的高度,都是由内部未浮动子元素的高度撑起的。
子元素浮动,还会对父元素造成影响。
如果子元素浮动起来,就不占用普通文档流的位置。父元素高度就会失去支撑,也称为高度坍塌。

处理类似高度塌陷的方式有很多种,比如在已知情况下给父元素设置固定高度。但多数情况下,父元素高度由内容撑起,于是大多数情况下是难以固定父元素的高度。
于是就衍生出以下这几种解决方式。

方式一

父元素设置overflow:hidden属性
CSS中的overflow :hidden属性会强制要求父元素必须包裹住所有内部浮动的元素,以及所有元素的margin范围。
但是如果遇到子元素使用了类似position这样的定位属性,超出父元素范围,就会出现副作用,被隐藏。

方式二

在父元素内的结尾追加一个空子元素(块级元素),并设置空子元素清除浮动影响(clear:both)。
因为clear:both属性和父元素必须包含非浮动的元素。
但是会多出这一个看不见的空元素,有时会影响CSS选择器和查找元素时多余的判断。

方式三

让父元素也浮动。
浮动属性也会强制父元素扩大到包含所有浮动的内部元素,BFC。
但是会产生新的浮动影响,父元素之后平级的标签可能会被埋在它下面。
当然可以通过方式二的套娃解决这个问题,比如给父元素之后的一个平级元素清除浮动(clear:both)。

方式四

给父元素末尾的伪元素after设置clear:both。
不会影响显示隐藏,又不会影响查找元素,又不会产生新的浮动问题。个别浏览器,display:table,可能带默认高度,再加一个属性height:0来作保险。
.father-box::after{ content:""; display:table; clear:both;height:0 }

BFC

bfc是网页的一种渲染机制,就是一个特殊独立的渲染区域,它规定了渲染区域内部的块级元素应该如何布局。
在BFC渲染区域内部如何布局,与区域外部毫不相干。外部元素也不会影响BFC渲染区域内的元素。
类似一个vip特权,自己建立了一个小王国,级别非常高,但也与世隔绝。

一句话概括:BFC就是页面上的一个隔离的独立渲染区域,区域里面的子元素不会影响到外面的元素,外面的元素也不会影响到区域里面的子元素。

形成BFC的四种情况

  1. float的值不是none
  2. position的值不是static或者relative
  3. display的值是inline-block、table-cell、flex、table-caption或者inline-flex
  4. overflow的值不是visible

之所以BFC可以用来解决高度塌陷,因为BFC盒子可以包裹BFC盒子,所以父元素包含内部float浮动元
素,浮动的子元素属于BFC盒子,父元素也属于BFC盒子,那么就能正常进行父元素的高度为子元素的高度计算结果。

overflow:hidden、display:table、float:left 等等其实都可以形成BFC,但是得小心它们随之带来得负面影响,上面有讲到,就不多赘述了。

其实还有IFC,BFC叫做块格式化上下文,IFC是内格式化上下文,都是不同的渲染机制,应该还有弹性格式化上下文FFC和网格格式化上下文GFC,这里只提一嘴噢,可能并不难,日常没有太多涉猎。

垂直margin合并

两个块元素,垂直方向的都有设置margin,此时它们垂直方向的间距等于其中margin值最大的,也就是说并不会累加margin值。
如果想累加垂直方向的外边距,可以把其中一个块元素套一层父盒子,然后给父盒子设置BFC,如此一来,垂直方向的外边距就会取最大而是累加。这也是借助BFC的渲染机制,内部元素不能超出范围影响外部,外部元素也不能进入BFC
范围内,影响内部。

父元素设置 overflow:hidden 或者 父元素设置::before{ content:""; display:table; height: 0;}

垂直方向margin溢出

父元素和子元素都没设置BFC时,子元素的垂直方向上的margin值会超出父元素包裹的范围,也就是margin溢出。
正常来说子元素的margin应该在父元素的范围之内才对。

解决办法也是类似的,给父元素设置BFC。父元素设置 overflow:hidden 或者 父元素设置::before{ content:""; display:table; height: 0;}

其实除了设置BFC,也可以这样解决

  1. 用父元素的padding-top来代替子元素的margin-top,再设置一下box-sizing:border-box,使padding不影响父元素的实际高度。
  2. 给父元素设置border,用border来阻隔子元素的margin-top溢出问题,但边框得设置成透明的,也要设置一下box-sizing:border-box。
  3. 在子元素的前面插入一个自身带有BFC功能的元素,比如 table,它自带display:table的功能。

自适应布局

效果:左定宽,右自适应布局。

左定宽,左浮动。右边自适应,右边设置为overflow:hidden,让右边宽度为百分百。
也许你要问,既然都是创建BFC,为啥右边不用右浮动,因为用了右浮动,那么就要指定合适的宽度,当然你可以使用calc来动态计算宽度。
如果让右边右浮动,不设置宽度,宽度就默认为0,如果设置百分之百,那么就会换行了。
右边元素overflow:hidden后,形成BFC渲染区域。左边的float元素就不能进入右边范围了,然后宽度就会为剩下区域的全部。

如果是左定宽,中间自适应,右定宽。其实也一样的噢。左右浮动并设置固定宽度,中间设置overflow:hidden。或者中间通过calc来动态计算宽度。

<style>
    .left-box {
        width: 300px;
        background-color: pink;
        float: left;
        height: 100vh;
    }

    .right-box {
        background-color: green;
        float: right;
        /* width: 100%; */
        /* overflow: hidden; */
        height: 100vh;
    }
</style>
<div class="f-box">
    <div class="left-box"></div>
    <div class="right-box"></div>
</div>

弹性布局

浮动布局可以解决自适应的问题,但是解决起来不是很优雅,并不能随心所欲通过哪些属性轻易的控制布局。

传统局部需要手动计算来完成自适应。

元素宽度:width+padding*2+border*2+margin*2

弹性布局自动计算元素宽度、间距。

基本概念

弹性盒子:弹性布局的容器
弹性子元素:弹性布局的项目
主轴:默认为x轴反向
交叉轴:默认为y轴方向

主轴和交叉轴是相对的,并不是绝对的,当主轴设置为y轴方向是,交叉轴就会变成x轴方向。

弹性盒子设置为display:felx,则会独占一行。
弹性盒子设置为display:inline-felx,则会占一行中的一部分。

常用的弹性盒子布局属性有以下几种

  • flex-direction属性:指定容器的主轴及其排列方向,默认 row
  • flex-wrap属性:主轴排列不下所有项目时,是否换行显示,默认 nowrap
  • flex-flow属性:以上两个的简写方式,同时设置flex-direction和flex-wrap两个属性,默认 row nowrap
  • justify-content属性:所有弹性子元素在弹性盒子主轴上的对齐方式
  • align-items属性:所有弹性子元素在弹性盒子交叉轴上的对齐方式

常用的弹性子元素属性有以下几种

  • order属性:排列顺序,值越小,越靠近起点,默认 0
  • flex-grow属性:放大比例,弹性盒子有足够的空间,弹性子元素可以放大,默认是 1
  • flex-shrink属性:缩小比例,弹性盒子没有足够的空间,弹性子元素可以缩小,默认是 1,表示空间不足时,则等比缩小。设置为0时,则不缩小。
  • align-self属性:单独定义某一个弹性子元素在交叉轴上的对齐方式,取值和align-items完全一样,多了一个auto值,表示继承父元素的align-items效果。

居中

居中都发生在块元素容器中,分为垂直居中和水平居中。

水平居中

如果子元素是行内元素,要水平居中

水平居中就是text-align:center。

子元素是块级元素,要水平居中

水平居中就是margin: 0 auto。

也可以通过计算的方式,通过设置父元素的padding来让子元素达到居中,或者通过设置子元素的margin来达到居中。
计算方式:父子元素都设置box-sizing:border-box,居中的值为(父宽-子宽)/2。

还可以通过子绝absolute父相relative的方式。
子元素left:50%;margin-left: -(子宽一半);
或者子元素left:50%;transform:translateX(-50%);

也可以使用弹性布局flex。
父元素直接设置display:flex;flex-direction: row;justify-content:center;

垂直居中

如果子元素是行内元素,要垂直居中

垂直居中就是给父元素设置的line-height,值为父元素的高度。但这个只能单行居中,多行会有副作用。

如果是多行子元素要给父元素设置vertical-align:middle,不过父元素还要设置inline-block或者table-cell。display:inline也可以。

也可以使用弹性布局flex。
父元素直接设置display:flex;flex-direction: column;justify-content:center;

子元素是块级元素,要垂直居中

也可以通过计算的方式,通过设置父元素的padding来让子元素达到居中,或者通过设置子元素的margin来达到居中。
计算方式:父子元素都设置box-sizing:border-box,居中的值为(父高-子高)/2。

还可以通过子绝absolute父相relative的方式。
子元素top:50%;margin-top: -(子宽一半);
或者子元素top:50%;transform:translateY(-50%);

也可以使用弹性布局flex。
父元素直接设置display:flex;flex-direction: column;justify-content:center;

重点-单位

css中的单位有很多种,比如pt、rpx、px、em、rem、%、vh、vw。

pt 设备物理像素

屏幕宽/分辨率,其中每一小份就是1pt

px css像素

pc机大屏幕显示器,1px约等于0.76个物理像素

手机小屏幕,以iPhone6为标准,物理像素750,分辨率375,1px=2pt,所以,px也是一个相对单位。

px是为了平衡一个元素在PC上显示的大小与在手机上显示的大小尽量一致而制定的。

但是,因为手机屏幕大小不一,差异较大,所以,反而不希望一个元素在所有手机上显示一样大。而是希望能够自动等比缩放。所以,移动端不要用px。

通常PC端大屏浏览器的网页,使用px单位较多。移动端少用,因为px的长度相对固定,无法根据大小不一的移动端设备自适应改变大小。

rem 根节点自适应

以网页根元素元素上设置的默认字体大小为1rem,默认1rem=16px。

用的多,好处是可以实现响应式布局,响应式布局指的是元素大小能根据屏幕大小随时变化。
因为所有以rem为单位的位置、大小都跟着根元素字体大小而变化。
所以只要在屏幕大小变化的时候改变根元素font-size就行了。

em 以父之大小

继承父元素的字体大小,父元素的字体大小就是1em。用的不多。

rpx 小程序专有

以iPhone6为标准,物理像素750,分辨率375。无论屏幕大小,都将屏幕分成750份,每份就是1rpx。1rpx=0.5px=1pt。

优点是通过 rpx 设置元素和字体的大小,小程序在不同尺寸的屏幕下,可以实现自动适配。

vm/vh 视口划分一百份

CSS3的特性,vh ,无论视口高度多少,都将视口高均分为100份,每1小份就是100vh,所以,也是相对单位,可随视口大小变化而自动变化。
vw ,无论视口宽度多少,都将视口宽均分为100份,每1小份就是100vw,所以,也是相对单位,可随视口大小变化而自动变化。
所以vw和vh,本质就是%,它的百分比是基于页面的可视区域,而视口指的就是浏览器内部的可视区域大小。

% 相对单位

通常认为子元素的百分比完全相对于直接父元素,但是,不总是相对于父元素的对应属性值。
子元素的 top 和 bottom 如果设置百分比,则相对于直接非 static 定位(默认定位)的父元素的高度。
子元素的 left 和 right 如果设置百分比,则相对于直接非 static 定位(默认定位的)父元素的宽度。
子元素的 padding/margin 如果设置百分比,不论是垂直方向或者是水平方向,都相对于直接父亲元素的 padding/margin ,而与父元素的 height 无关。
因为 % 不总是相对于父元素的宽高或屏幕大小,所以有坑,尽量少用。

响应式布局

浏览器meta标签

<meta name="viewport"content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0">中每个属性的含义:

viewport 视口,显示设备内部,真正实际可用于显示网页的区域大小
width 视口宽,device-width表示等于物理设备宽
user-scalable,是否允许用户手工缩放网页
initial-scale=1.0,加载页面时,页面的缩放比例是1,表示不缩放,原网页大小展示
maximum-scale=1.0,minimum-scale=1.0,允许用户缩放网页的最大缩放比例和最小缩放比例,都是1,表示不允许用户使用过程中,中途缩放网页。

5种响应式布局方式

子绝父相、float布局、使用rem作单位进行等比缩放、flex布局、grid布局。

子绝父相,结合使用media可以实现响应式布局。代码写法复杂,布局较繁琐,如果不使用media平分屏幕,宽度小于600的情况下,右侧会覆盖左侧。

float布局,容易被挤压换行。

使用rem作单位,等比缩放。

  1. 给根元素html设置一个字体大小
  2. 其他尺寸单位全部用 rem
  3. 监听屏幕的大小
  4. 根据屏幕的大小按比例改变根节点字体的大小

因为 rem 的特性,其他的尺寸都是根据根节点字体的大小设定的,所以,根节点字体大小一变,其他所有尺寸都会按比例变大、或小。
大部分浏览器的字体有个最小值:12px。也就是缩小到 12px 后,字体不会继续缩小。

flex布局,代码简单,布局方便。如果中间有内容,缩到最小就不会再小,且左右侧的宽度变小了。

grid布局

grid布局文章

Flex布局是轴线布局,只能指定"项目"针对轴线的位置,可以看作是一维布局,Grid 布局则是将容器划分成“行"和“列”,产生单元格,然后指定"项目所在”的单元格,可以看作是二维布局.
Grid布局远比 Flex布局强大。不过存在兼容性问题,知识点比较多, 学习成本相对较高, 目前兼容性还不如flex布局。

容器属性

grid-template-columns 和grid-template-rows 规定共有有几行,几列,每行,每列宽多少。

grid-template-columns:100px 100px 100px; // 显示为三列每一列宽度100px
grid-template-columns:repeat(3,100px); //同上

也可以固定格大小,然后优先占满整个宽度,grid-template-columns: repeat(auto-fill,100px);
auto-fill,有时,单元格的大小是固定的,但是容器的大小不确定,这个属性就会自动填充。

也可以按份数规定列宽
fr,比例关系,fraction ,意为"片段”,表示某一行或列在总宽度和总高度中占的份数
grid-template-columns:repeat(4,1fr); // 宽度平均分成四等份
grid-template-columns:1fr 2fr 3fr; // 列宽这样是分成6份各占 1 2 3 份

还可以设置最小和最大的大小范围
grid-template-columns: 1fr minmax(150px,1fr); // 第一个参数最小值,第二个最大值,表示第二列最小150px,最大1fr。

还可以让浏览器自己决定长度,auto 表示由浏览器自己决定长度,grid-template-columns: 100px auto 100px;

还可以定义网格线,网格线 可以用方括号定义网格线名称,方便以后给盒子定位使用。grid-template-columns: [c1] 100px [c2] 100px [c3] 100px [c4];


column-gap和row-gap 定义格与格之间的间距,如果column-gap和row-gap间距一致,可简写为: gap:xxx

grid-auto-flow 划分网格以后,容器的子元素会按照顺序,自动放置在每一个网格。默认的放置顺序是"先行后列".即先填满第一行,再开始放入第二行(就是子元素的排放顺序)

grid-auto-flow: row; // 先行后列
grid-auto-flow: column; // 先列后行


justify-items(水平方向)/ align-items(垂直方向)
设置单元格内容的水平和垂直的对齐方式,值为: start | end | center | stretch
同时设置两个属性: place-items : start end; 这是两个属性的简写

justify-content (水平方向)/ align-content(垂直方向)
设置整个内容区域(所有的项目的总和)的水平和垂直的对齐方式
取值: start | end | center | stretch | space-around | space-between | space-evenly;

项目属性

grid-column-start / grid-column-end grid-row-start / grid-row-end
一句话解释,用来指定item的具体位置,根据在哪根网格线

grid-column-start:1;
grid-column-end:3;
表示从第一个网格线,跨到第三个网格线之前,也就是横跨1、2两列
grid-column: span 2;
grid-column-end:3;
简写: grid-column: 1 / 3;
grid-column-start:1;
grid-column-end:3;
grid-row-start:1;
grid-row-end:3;
跨两行,跨两列的方形区域。简写: grid-area: 1 / 1 / 3 / 3

justify-self / align-self 当前单元格内容的水平和垂直对齐方向
place-self 同时设置一个单元格内容的水平和垂直方向对齐方式

媒体查询

通过媒体查询来设置样式(Media Queries)是响应式设计的核心。它根据条件告诉浏览器如何为指定视图宽度渲染页面。

媒体类型

  • print(打印机)
  • screen(所有屏幕设备的统称:各种电脑屏幕、各种手机屏幕、各种平板屏幕,主要使用的就是这个)
  • all(所有媒体设备,默认值)
  • speech(应用于屏幕阅读器等发声设备)

style 和 link

在 style 标签中通过 media属性 可以设置样式使用的媒体设备。比如<style media="print">

在 link 标签中通过 media属性 可以设置样式使用的媒体设备。比如<link rel="stylesheet" href="common.css"> <!--common.css 没有指定媒体所以全局应用-->
<link rel="stylesheet" href="screen.css" media="screen"> <!--screen.css 应用在屏幕设备-->
<link rel="stylesheet" href="print.css" media="print"> <!--print.css 应用在打印设备-->

如果一个css文件,可能同时被多个页面通过link引入,所以只要用link,就加media,就繁琐了,可以使用下面import的方式。

@import

使用@import可以引入指定设备的样式规则,文件中引入一个样式文件,在这个文件中再引入其他媒体的样式文件。

<link rel="stylesheet" href="style.css">

/* style.css */
@import url(screen.css) screen;
@import url(print.css) print;

@media

可以使用 @media 做到更细的控制,即在一个样式表中为多个媒体设备定义样式。在 css文件/less文件 里也可以使用。

<style>
    @media screen {
        h1 {
            font-size: 3em;
            color: blue;
        }
    }
    @media print {
        h1 {
            font-size: 8em;
            color: red;
        }
        h2, hr {
            display: none;
        }
    }
</style>

多设备支持(,分隔)

可以用 逗号分隔 同时支持多个媒体设备。

比如:
@import url(screen.css) screen,print;
<link rel="stylesheet" href="screen.css" media="screen,print">
@media screen,print {...}

设备方向(orientation 属性)

使用 orientation 属性可以定义设备的方向
orientation: landscape,横屏,宽度>高度
orientation: portrait,竖屏,高度>宽度

查询条件

可以使用不同条件限制使用的样式,条件表达式需要放在扩号中

比如

横屏显示宽度不能超过600px

 @media screen and (orientation: landscape) and (max-width: 600px) { 
    body {
        background: #8e44ad;
    }
    h1 {
        font-size: 3em;
        color: white;
    }
}

横屏显示或宽度不超过600px

 @media screen and (orientation: landscape), screen and (max-width: 600px) {
    body {
        background: #8e44ad;
    }
    h1 {
        font-size: 3em;
        color: white;
    }
}

既不是横屏,宽度又不效于600时,才使用。not必须写在开头,表示后续条件都不满足,才能应用。

@media not screen and (orientation: landscape) and (max-width:600px) {
    body {
        background: #8e44ad;
    }
    h1 {
        font-size: 3em;
        color: white;
    }
}

引入顺序

永远后一个,因为后一个范围包含前一个范围,而且后一个样式会覆盖前一个的样式。

@import url(big.css)  only screen and (min-width:1200px);
@import url(medium.css)  only screen and (min-width:900px);

设备的划分情况

小于768的为超小屏幕(手机)
768~992之间的为小屏设备(平板)
992~1200的中等屏幕(桌面显示器)
大于1200的宽屏设备(大桌面显示器)

父容器版心的尺寸划分

超小屏幕(手机,小于 768px):设置宽度为 100%
小屏幕(平板,大于等于 768px):设置宽度为 750px
中等屏幕(桌面显示器,大于等于 992px):宽度设置为 970px
大屏幕(大桌面显示器,大于等于 1200px):宽度设置为 1170px

响应式字体

一个响应式的字体应关联它的父容器的宽度,这样才能适应客户端屏幕。

rem是相对于根元素的,不要忘记重置根元素字体大小:html{font-size:100%;}
完成后,你可以定义响应式字体:
@media (min-width:640px){body{font-size:1rem;}}
@media (min-width:960px){body{font-size:1.2rem;}}
@media (min-width:1200px){body{font-size:1.5rem;}}

sass 常用功能

变量

$font-stack: Helvetica, sans-serif;
$primary-color: #333;

body {
  font: 100% $font-stack;
  color: $primary-color;
}

嵌套

简单嵌套

nav {
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
  }

  li { display: inline-block; }

  a {
    display: block;
    padding: 6px 12px;
    text-decoration: none;
  }
}

引用父级选择器&

a {
  font-weight: bold;
  text-decoration: none;
  &:hover { text-decoration: underline; }
  body.firefox & { font-weight: normal; }
}

无论CSS规则嵌套的深度怎样,关键字&都会使用父级选择器级联替换全部其出现的位置:

/*===== SCSS =====*/
#main {
  color: black;
  a {
    font-weight: bold;
    &:hover { color: red; }
  }
}

/*===== CSS =====*/
#main {
  color: black; 
}
#main a {
  font-weight: bold; 
}
#main a:hover {
  color: red; 
}

&必须出现在复合选择器开头的位置,后面再连接自定义的后缀

/*===== SCSS =====*/
#main {
  color: black;
  &-sidebar { border: 1px solid; }
}

/*===== CSS =====*/
#main {
  color: black; 
}
#main-sidebar {
    border: 1px solid; 
}

嵌套属性

/*===== SCSS =====*/
.demo {
  // 命令空间后带有冒号:
  font: {
    family: fantasy;
    size: 30em;
    weight: bold;
  }
}

/*===== CSS =====*/
.demo {
  font-family: fantasy;
  font-size: 30em;
  font-weight: bold; 
}

引入

// _reset.scss
html, body, ul, ol {
  margin:  0;
  padding: 0;
}


// base.scss
@import 'reset';
body {
  font: 100% Helvetica, sans-serif;
  background-color: #efefef;
}

混合

混合(Mixin)用来分组那些需要在页面中复用的CSS声明,开发人员可以通过向Mixin传递变量参数来让代码更加灵活,该特性在添加浏览器兼容性前缀的时候非常有用,SASS目前使用@mixin name指令来进行混合操作。

@mixin border-radius($radius) {
  border-radius: $radius;
  -ms-border-radius: $radius;
  -moz-border-radius: $radius;
  -webkit-border-radius: $radius;
}

.box {
  @include border-radius(10px);
}

继承

// 这段代码不会被输出到最终生成的CSS文件,因为它没有被任何代码所继承。
%other-styles {
  display: flex;
  flex-wrap: wrap;
}

// 下面代码会正常输出到生成的CSS文件,因为它被其接下来的代码所继承。
%message-common {
  border: 1px solid #ccc;
  padding: 10px;
  color: #333;
}

.message {
  @extend %message-common;
}

.success {
  @extend %message-common;
  border-color: green;
}

.error {
  @extend %message-common;
  border-color: red;
}

.warning {
  @extend %message-common;
  border-color: yellow;
}

算术运算符

.container { width: 100%; }

article[role="main"] {
  float: left;
  width: 600px / 960px * 100%;
}

aside[role="complementary"] {
  float: right;
  width: 300px / 960px * 100%;
}

利用css构建三角形(正三角,倒三角,左/右三角)

上三角

    #triangle-up {
    width: 0;
    height: 0;
    border-left: 50px solid transparent;
    border-right: 50px solid transparent;
    border-bottom: 100px solid red;
}

下三角

    #triangle-down {
    width: 0;
    height: 0;
    border-left: 50px solid transparent;
    border-right: 50px solid transparent;
    border-top: 100px solid red;
}

左三角

    #triangle-left {
    width: 0;
    height: 0;
    border-top: 50px solid transparent;
    border-right: 100px solid red;
    border-bottom: 50px solid transparent;
}

右三角

    #triangle-right {
    width: 0;
    height: 0;
    border-top: 50px solid transparent;
    border-left: 100px solid red;
    border-bottom: 50px solid transparent;
}

左上三角

    #triangle-topleft {
    width: 0;
    height: 0;
    border-top: 100px solid red;
    border-right: 100px solid transparent;
}

右上三角

    #triangle-topright {
    width: 0;
    height: 0;
    border-top: 100px solid red;
    border-left: 100px solid transparent; 
}

左下三角

    #triangle-bottomleft {
    width: 0;
    height: 0;
    border-bottom: 100px solid red;
    border-right: 100px solid transparent;
}

右下三角

    #triangle-bottomright {
    width: 0;
    height: 0;
    border-bottom: 100px solid red;
    border-left: 100px solid transparent;
}

缩放

如何实现 < 12px的字

display:inline-block; /*scale只能缩放行内块或块元素*/
-webkit-transform: scale(0.5);  /*定义2D缩放*/
-webkit-transform-origin:left top; /*定义缩放源点为左上角*/

0.5px的线如何实现

0.5px的线,不同设备,不同浏览器差异较大

/* 普通 */
.hr.half-px {
    height: 0.5px;
}

/* 通过css3的方式 */
.hr.scale-half {
    height: 1px;
    transform: scaleY(0.5);
    transform-origin: 50% 100%; /*为了防止线模糊*/
}

更好的解决: svg

可以利用svg画出各种图形的0.5px线条

.hr.svg {
    background: none;
    height: 1px;
    background: url("data:image/svg+xml;utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='100%' height='1px'><line x1='0' y1='0' x2='100%' y2='0' stroke='#000'></line></svg>");
}

其中: svg图片是

使用svg的line元素画线,stroke表示描边颜色,默认描边宽度stroke-width="1",由于svg的描边等属性的1px是物理像素的1px,相当于高清屏的0.5px,另外还可以使用svg的rect等元素进行绘制。

<svg xmlns='http://www.w3.org/2000/svg' width='100%' height='1px'>
    <line x1='0' y1='0' x2='100%' y2='0' stroke='#000'></line>
</svg>

但是在firefox兼容性不太好,可以把svg转为base64

.hr.svg {
    background: url("data:image/svg+xml;utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='100%' height='1px'><line x1='0' y1='0' x2='100%' y2='0' stroke='#000'></line></svg>");
    background: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxMDAlJyBoZWlnaHQ9JzFweCc+PGxpbmUgeDE9JzAnIHkxPScwJyB4Mj0nMTAwJScgeTI9JzAnIHN0cm9rZT0nIzAwMCc+PC9saW5lPjwvc3ZnPg==");
}

总结

面试过程中CSS的问题都会比较简单,当然还有动画、过渡,以及一些类似PS高级功能的样式,以后有时间,会继续更新css部分。

本篇文章说了BFC、弹性布局、布局居中、单位、响应式布局、css预处理器、css三角、字体缩放和0.5px线条。

如果掌握以上CSS的知识,无论是实际工作还是面试过程,都是非常实用的。反之,不明就里的话,无论是工作还是面试都会出现奇奇怪怪的问题,当然有时也会遇到难以解决的问题,最终采用迂回绕弯的方式解决,但是以上的CSS知识肯定是必备基础。

说到响应式自适应,其实就想到了大屏,以前的同事做了一个自适应的大屏效果,思考许久,我尝试把自适应的代码写出来了,最后也在这里分享一下。
那段时间有在研究如何一行代码写一个功能,虽然可读性很差,但是有点乐趣,我也在下方分享出来。

const width = 1920;
const height = 1080;
const targetRate = parseFloat((width/height).toFixed(5))

const currentWidth = window.innerWidth
const currentHeight = window.innerHeight
const currentScreenRate = parseFloat((currentWidth/currentHeight).toFixed(5));

let xRate,yRate
if(currentScreenRate > targetRate) {
    xRate = (currentHeight * targetRate / width).toFixed(5);
    yRate = (currentHeight / height).toFixed(5);
}else {
    xRate = (currentWidth / width).toFiexd(5);
    yRate = (currentWidth / taregtRate / height).toFixed(5);
}
const transformStyle = `scale(${xRate},${yRate}) translate(-50%, -50%)`;


// 一行代码的简写,声明变量可以通过reduce来传递,有几层变量就嵌套基层reduce。也得到了上面transformStyle的结果
Array(1).fill(0).reduce((_) => Array(1).fill(0).reduce(__ => (__.currentScreenRate > __.targetRate ? (_.xRate = (_.currentHeight * __.targetRate / _.width).toFixed(5),_.yRate = (_.currentHeight / _.height).toFixed(5)):(_.xRate = (_.currentWidth / _.width).toFiexd(5),_.yRate = (_.currentWidth / __.taregtRate / _.height).toFixed(5)),`scale(${_.xRate},${_.yRate}) translate(-50%, -50%)`), Object({targetRate: parseFloat((_.width/_.height).toFixed(5)), currentScreenRate: parseFloat((_.currentWidth/_.currentHeight).toFixed(5))})), Object({width: 1920, height: 1080, currentWidth: window.innerWidth, currentHeight: window.innerHeight, xRate: void 0, yRate: void 0}))
目录
相关文章
|
2天前
|
前端开发
【Web前端】CSS基本语法规范和引入方式&&常见选择器用法&&常见元素属性
【Web前端】CSS基本语法规范和引入方式&&常见选择器用法&&常见元素属性
|
12天前
|
缓存 移动开发 前端开发
【专栏:HTML与CSS前端技术趋势篇】HTML与CSS在PWA(Progressive Web Apps)中的应用
【4月更文挑战第30天】PWA(Progressive Web Apps)结合现代Web技术,提供接近原生应用的体验。HTML在PWA中构建页面结构和内容,响应式设计、语义化标签、Manifest文件和离线页面的创建都离不开HTML。CSS则用于定制主题样式、实现动画效果、响应式布局和管理字体图标。两者协同工作,保证PWA在不同设备和网络环境下的快速、可靠和一致性体验。随着前端技术进步,HTML与CSS在PWA中的应用将更广泛。
|
12天前
|
前端开发 JavaScript 开发者
【专栏:HTML与CSS前端技术趋势篇】前端框架(React/Vue/Angular)与HTML/CSS的结合使用
【4月更文挑战第30天】前端框架React、Vue和Angular助力UI开发,通过组件化、状态管理和虚拟DOM提升效率。这些框架与HTML/CSS结合,使用模板语法、样式管理及组件化思想。未来趋势包括框架简化、Web组件标准采用和CSS在框架中角色的演变。开发者需紧跟技术发展,掌握新工具,提升开发效能。
|
12天前
|
前端开发 JavaScript UED
【专栏:HTML 与 CSS 前端技术趋势篇】Web 性能优化:CSS 与 HTML 的未来趋势
【4月更文挑战第30天】本文探讨了CSS和HTML在Web性能优化中的关键作用,包括样式表压缩、选择器优化、DOM操作减少等策略。随着未来趋势发展,CSS模块系统、自定义属性和响应式设计将得到强化,HTML新特性也将支持复杂组件构建。同时,应对浏览器兼容性、代码复杂度和性能功能平衡的挑战是优化过程中的重要任务。通过案例分析和持续创新,我们可以提升Web应用性能,创造更好的用户体验。
|
12天前
|
移动开发 前端开发 UED
【专栏:HTML与CSS前端技术趋势篇】渐进式增强与优雅降级在前端开发中的实践
【4月更文挑战第30天】前端开发中的渐进式增强和优雅降级是确保跨浏览器、跨设备良好用户体验的关键策略。渐进式增强是从基础功能开始,逐步增加高级特性,保证所有用户能访问基本内容;而优雅降级则是从完整版本出发,向下兼容,确保低版本浏览器仍能使用基本功能。实践中,遵循HTML5/CSS3规范,使用流式布局和响应式设计,检测浏览器特性,并提供备选方案,都是实现这两种策略的有效方法。选择合适策略优化网站,提升用户体验。
|
12天前
|
前端开发 开发者 UED
【专栏:HTML与CSS前端技术趋势篇】网页设计中的CSS Grid与Flexbox之争
【4月更文挑战第30天】本文对比了CSS Grid和Flexbox两种布局工具。Flexbox擅长一维布局,简单易用,适合导航栏和列表;CSS Grid则适用于二维布局,能创建复杂结构,适用于整个页面布局。两者各有优势,在响应式设计中都占有一席之地。随着Web标准发展,它们的结合使用将成为趋势,开发者需掌握两者以应对多样化需求。
|
12天前
|
前端开发 JavaScript 搜索推荐
【专栏:HTML 与 CSS 前端技术趋势篇】HTML 与 CSS 在 Web 组件化中的应用
【4月更文挑战第30天】本文探讨了HTML和CSS在Web组件化中的应用及其在前端趋势中的重要性。组件化提高了代码复用、维护性和扩展性。HTML提供组件结构,语义化标签增进可读性,支持用户交互;CSS实现样式封装、布局控制和主题定制。案例展示了导航栏、卡片和模态框组件的创建。响应式设计、动态样式、CSS预处理器和Web组件标准等趋势影响HTML/CSS在组件化中的应用。面对兼容性、代码复杂度和性能优化挑战,需采取相应策略。未来,持续发掘HTML和CSS潜力,推动组件化开发创新,提升Web应用体验。
|
1月前
|
存储 安全 Java
大厂面试题详解:java中有哪些类型的锁
字节跳动大厂面试题详解:java中有哪些类型的锁
60 0
|
3天前
|
Java
【Java多线程】面试常考 —— JUC(java.util.concurrent) 的常见类
【Java多线程】面试常考 —— JUC(java.util.concurrent) 的常见类
13 0
|
3天前
|
安全 Java 程序员
【Java多线程】面试常考——锁策略、synchronized的锁升级优化过程以及CAS(Compare and swap)
【Java多线程】面试常考——锁策略、synchronized的锁升级优化过程以及CAS(Compare and swap)
6 0