关于业务大屏我一定要谈谈的CSS知识

155 阅读5分钟

前言

我是一名工作在苏州的中后台前端工程师,一般情况下,我并不需要掌握太多css方面的知识,但因为没有抵抗住花花世界的诱惑,我还是花了很多精力在它上面,就当是打游戏了。

所幸现在待的公司有很多出于商业宣传和吸睛的业务需求,要求页面酷、炫、拽,这就让web视觉领域的知识有了用武之地。在成功吸引到甲方爸爸后,本次文章的业务背景就出现了——定制化业务大屏

因为是绝对的甲方市场,所以懂得都懂,什么拖拽生成、外包就不要想了,市场的兄弟已经拍着胸脯跟甲方保证,大屏效果绝对酷炫拽、高大上。接下来的项目节奏就变成了领取主线任务——让甲方众人无敢哗然者,设计师摩拳擦掌,工程师磨刀霍霍。

弹性布局 display: flex;display: grid;

我个人更喜欢网格布局,组里的另外两名大哥都更喜欢flex; 在大多数web场景下,垂直方向是可滚动的,这就很契合flex的设计思路。而业务大屏不同于常规场景的地方在于,它通常是一屏的,整屏出现滚动的话,甲方爸爸直摇头。当然仅仅如此的话,flex依然可以胜任,但在编写布局的时候,还有一个非常重要的隐藏任务——减少嵌套。网格布局是二维的,在减少嵌套方面有天然优势。

  • 布局html部分
<div id="app" class="layout">
  <div class="title">TitleArea</div>
  <div class="stat">StatArea</div>
  <div class="card1">Card 1</div>
  <div class="card2">Card 2</div>
  <div class="card3">Card 3</div>
  <div class="card4">Card 4</div>
  <div class="card5">Card 5</div>
  <div class="center">Center</div>
</div>
  • 布局less部分
.layout {
   display: grid;
    grid-template-areas:
        "title title title"
        "stat stat stat"
        "card4 center card3"
        "card1 center card3"
        "card2 center card3"
        "card2 center card5";
    grid-template-rows: 6.5rem 7.75rem 10.5rem 16.13rem 0.63rem 1fr;
    grid-template-columns: 28.75rem 1fr 28.75rem;
    gap: 1.25rem;
    ......
}

完整代码链接

这一套下来,相当于用了一段很简短的话,描述了组件占位、间距、与响应式策略,且此时嵌套深度仅为2,grid子项默认宽高100%。定义好布局组件结构后,就能很快的分配好开发任务,没有复杂的页面细节的话,静态内容很快就可以完成。

工作到今天,我已经忘了我为什么要坚持减少嵌套,我也知道大多数前端开发都可以在几层弹性布局嵌套中游刃有余,直到有一天,我拿到一套10余层左右flex嵌套、出了高度溢出问题的代码,我才回忆起当初被滚动条支配的恐惧。

::after、::before 与 background

写大屏,使用::after、::before、background是再平常不过的事,只不过没想到他俩有一天也能扯上关系。业务场景是贴图,设计师为了保证屏幕尺寸变化的时候,背景图案不变形,将一个小组件的背景图切成了多个部分如下:

  1. 切片-左

green_power_card_left.png

  1. 切片-中

green_power_mid.png

  1. 切片-右

green_power_right.png

我们都知道一般情况下是没必要写成如下的代码的:

<div class="container">
  <img src="" alt="我是切片-左" />
  <img src="" alt="我是切片-中" />
  <img src="" alt="我是切片-右" />
</div>
<!-- 或是这样 -->
<div class="container">
  <div>我使用切片左做背景</div>
  <div>我使用切片中做背景</div>
  <div>我使用切片右做背景</div>
</div>

简单共识就是不创建多余的dom元素。于是就有人想到了::after、::before,大致就是如下的的写法:

div { 
    &::after{
        ......
    }
    
    &::before{
        ......
    }
}

很好,至少它不直接显示在html文件里了。很快就会发现,它作为伪元素,仍然是参与到布局当中的,意味着如果你不想让贴图影响布局,你仍然需要声明其脱离文档流,一切努力似乎变得没有意义,代码仍然很多,元素仍然被创建了,甚至比直接创建dom元素还要多,因为一个dom元素只有两个伪元素(不包括::marker),如果要贴第三张图,就意味着你需要创建一个新的dom元素,然后使用它的伪元素......

所以停下来简单思考一下,伪元素并不是给我们贴图用的,尽管我们可以这么干。再回到最开始看,我们经常使用backgound属性,我们也知道它是个简写属性,但往往忽略了他是可以写多个的。

所以在大屏业务场景下,我习惯这么写:

background-image: url(../../../../assets/green_power_card_left.png),
    url(../../../../assets/green_power_mid.png),
    url(../../../../assets/green_power_right.png);
background-repeat: no-repeat, no-repeat, no-repeat;
background-position: center left, 11.625rem 0, center right;
background-size: 11.625rem 7.125rem, calc(100% - 11.625rem - 3.5rem) 7.125rem,
3.5rem 7.125rem;

// 没有简写是因为less对position和size连着写总会编译成数值除法结果,一直没有深究其原因,有大哥知道的话麻烦解惑一下

再看bakcground,它支持多重背景差不多是在2011年左右,那个时候由于网络带宽的限制,web工程师经常需要把大的背景图切成很多份,然后在拼成一张完整的。所以在css3中background加入了多重背景的支持,所以它是纯贴图中的首选方案。用它唯一的缺点大概就是打开f12进行调试的时候会有些困惑和不方便。

加上background-image支持使用url()gradient()渐变的支持,使得background变得异常强大。比如用它画个简单图像。

code.juejin.cn/pen/7170198…

其它

还有很多其它想说的内容,比如伪类选择器,适当使用的话,会很舒服,毕竟给class命名是个挺累人的事情,即使有css-module的情况下。但是一旦嵌套多了话,维护真的巨痛苦,所以我一般只会在最右侧使用。但业务大屏这东西一般是一作一扔,即使甲方爸爸不满意,大概率也是推翻重做,很少有我这种需要不停修修改改的情况,很多样式方面的问题也就没有讨论的必要了。毕竟它都已经脱离工程的范畴了。

结语

理不辨不明,欢迎就文章内容进行讨论。内容之外的就不要问我了,我就是个画图的,我什么都不会。