w3ctech

html,css 命名空间 和 复用

关于html, css命名空间

最近在学校接一个外包项目,等做完过后,才发现html,css命名空间的惨目忍睹的状况,几乎无任何复用性可言,借此整理一下自己的看法,希望能和各位探讨出一个比较好的办法去解决样式复用的问题

为什么需要命名空间?

在做了接近2年前端后,我发现命名其实在应届生中是一个非常痛苦的问题,如果想简单判断一个学生是不是有大量的编程经验,那么直接show the code,看命名空间就可以了. 命名是给人看的,我们之所以需要命名空间,一方面是为了扩展,最重要的原因我认为是让你在2个月不看这份代码或则别人接盘你的代码的时候,能够简单快速的了解你的各个函数,模块是做什么的 我认为这是命名空间需要解决的问题,就是变量冲突和能够在隔一段时间或则别人接盘你的代码之后快速上手. 这在现今的css开发过程中是非常重要的.

接触css之初

在刚接触css的时候,我的命名方式通常是这样的

    .float{}
    .left{}

直接以这样的方式来命名,完全的没有分模块,只是简单的考虑到比如设计稿上这个图片在什么地方,需要浮动就用浮动,在左边就在左边,那个时候代码写出来是这样的

    .float{
        float: left;
        width: 100px;
        height: 200px;
    }    

那个时候的命名完全体现不出模块化的思想,只是简单按照设计图一块一块来做,不会去分析整体设计。导致到后面的命名会非常混乱,可以复用的样式也无法复用了

    .float-1{}
    .float-2{}

进阶css之时

其实这个时候,已经做了大量的css开发的工作,自己也学习了网上比较出名的命名方式---BEM

    .menu{}
    .menu__item{}
    .menu__item--default{}

bem这种命名方式非常的清晰,也非常直观的能帮助我们了解这个元素到底具体应用了些什么样式,非常直观。 但是弊端我觉的也是很明显的 团队之间使用这种命名规范的时候,水平的高低直接决定使用的效果,比如什么时候ELement叫item, 如果两个menu非常相近的情况下(可能只是位置上变动),是不是又需要一个命名Modifier去修饰它,本来使用这种命名方式的成本也不小(命名太长了),这些因素导致了对开发团队的要求太高,不利于推广。 曾经有段时间,也试过非常极端的处理方式,通过类组合的形式来解决

    .f12{
        font-size: 12px;
    }    
    .f-bloder{
        font-weight: bloder;
    }
    .m12{
        margin-top: 12px;
    }

这样书写的好处显而易见的就是单个命名非常短小,命名规则也非常的简单,通俗易懂,但是弊端也非常的明显

    h1.f12.m20.bg-red...

类名组合太长,也许一个复杂的样式,极端点可能不下10几个组合命名 既然这样极端方式也不可以,那么我们采取两种方式结合的方式去命名,把常用样式写成.f12,这样的形式,再针对设计稿上一些功能上的区分结合bem去命名

    .f12{
        font-size: 12px;
    }
    .menu-item{
        width: 100px;
        height: 120px;
    }

好像这样的命名方式解决了我所面临的问题,类名也不是过长,不需要很多Modifier去修饰,直到有一天我看了设计稿,发现一个menu的样式几乎是完全一样,就换了下position,background,height 这时候按原方案应该就是加Modifier, 但是问题是.menu-item上, 我如果将width当成Modifier去书写, 那么.meni-item 的width将没什么作用, 如果将整个width抽离出来成Modifier,那么按照modifier的规范我应该抽离成一种default, red 这样状态修饰

    .menu-item{
        height: 120px;
    }    
    .menu-item-default{
        width: 120px
    }

这样做的弊端在于,我发现我又绕回到类名组合的方式去了

sass,less出现

这个时候其实发现,如果我能够通过参数传递,去生成样式的话,那么许多问题就是能够解决,正好这个时候sass,less开始火热了起来(以下均以.scss文件为例)

sass为我们提供了@function, @mixin, %extend 这几种非常好的方式去组织我们的css代码,为css复用提供了更好的支持

举个例子,我们去实现一个alert弹窗(样式就以原生模版的来好了)

首先思考,什么时候需要弹窗,可能是警告用户操作,可能是提示用户信息操作,用户信息操作使用了灰色背景,警告操作使用了红色背景,一个命名为notify, 一个命名为warning,如下

      div.notify
      div.warning

假设单行文字, 整体居中, 就background不一样

    @mixin alert($background) {
        width: 100px;
        height: 100px;
        background: $backgorund;
    }        

    .notify{
        @include alert(grey);
    }
    .warning{
        @include alert(red);
    }

采用这个组件的功能名,组件可能还有一些非常特殊的样式可以这样来定义

    @mixin alert($background) {
        width: 100px;
        height: 100px;
        background: $backgorund;
    }        

    .notify{
        @include alert(grey);
        font-size: 24px;
    }
    .warning{
        @include alert(red);
        font-weight: bloder;
    }        

这样即实现了样式的复用,也能够清晰了解这个模块复用了什么样式,扩展性也够强。

当然像这样.notify, .warning这样的组件命名方式是非常通用化的命名方式,可能一个项目才能用一次,这个时候其实原理也一样,我可以在组件命前标注这个功能模块是属于那个页面的

.index-notify{}

通过这样的方式,可以做到,如果.index-notify是在@minxin alert上的扩展,那么我可以直接引用,并且可以很好的去扩展原组件上没有的样式

写在结尾

命名这样的事情,没有什么标准答案,但是我css命名空间的制定是非常考验一个工程师的设计能力的事情,只要找到适合自己团队的方式,能够在此基础上快速扩展,那就非常ok了,当然团队还是的需要找到一个大家都能比较通用的解决方案,这样在开发中,才能够更加快速,高效的工作,希望大家积极反馈,提供更加优秀的解决方案

w3ctech微信

扫码关注w3ctech微信公众号

共收到6条回复

  • Hello world

    回复此楼
  • Hello world

    回复此楼
  • 写的很棒,注册个账号来点赞。嘿嘿

    回复此楼
  • 大哥有空求交流

    回复此楼
  • 多谢分享。~

    回复此楼
  • 我刚学完sass之际就看到了贵文,没看之前对sass做了一次深入思考,主要是它到底能给csser带来啥好事!结论是:它只适合大型项目,小型的就是鸡肋。看了贵篇后,感觉小型也要用,原因当然是命名空间了。其实我也一直为命名空间发愁,有了sass,问题好多了!

    回复此楼