阅读 1161

设计DOM&CSS

本文内容主要是个人工作的总结,当然也是对他人优秀方案的借鉴

进行页面重构时我们的主要工具手段是DOM标签,如:没有语义的DIV和有语义的SECTION。我们应该如何有效的管理繁杂的标签嵌套和使用语义化标签,这是本文的内容。

为了帮助说明设计demo来自这个网站,设计师@果汁

一,观察设计图


无论是这个demo网站的设计又或者是其它任何类型网站的设计,开始重构前做以下分析:

  • 一个页面可以根据要展示的内容被区分为多个独立的展示块
    • 头部展示块
    • banner展示块
    • xx内容展示块
    • 底部展示块
  • 每个展示块同样会限定信息展示区域。
    • 全屏风格(100%宽)——信息展示区为全屏;
    • 限定宽度(980px宽、1200px宽)——信息展示区为指定的宽度
  • 信息展示区布局样式——通常为居中布局
  • 划分好信息展示区就需要对信息展示区进行内容填充,考虑到展示信息的多样性我们需要对展示区进行布局规划
    • 两栏布局
    • 三栏布局
    • 两栏自适应布局
    • 其它。。。
  • 内容模块——完成了信息展示区的布局设计,现在页面整体框架的框架已经呈现在我们的面前(看下图)只需填充内容模块

二,页面分析完成之后的DOM设计(设计方案)

拿到设计稿根据上面的分析思路我们可以得到:

1,展示块

根据要展示的内容划分展示块,图中红框表示我们对展示块的划分

// 现在我们DOM结构应该如下
<!DOCTYPE html>
<html>
  <head>
    <title>demo</title>
  </head>
  <body>
    <!-- 内容展示块 -->
    <div class="block-head"></div>
    <div class="block-nav"></div>
    <div class="block-banner"></div>
    <div class="block-service"></div>
    <div class="block-global"></div>
  </body>
</html>
复制代码

2,限定信息展示区域

图中我用黄色框表示出这个页面每个内容展示块中的信息展示区域

<!-- 现在我们的DOM结构如下 -->
<!DOCTYPE html>
<html>
  <head>
    <title>demo</title>
  </head>
  <body>
    <!-- 同下 -->
    <div class="block-serivce">
      <!-- .g-container控制展示区域的大小和定位 -->
      <div class="g-container"></div>
    </div>
    <!-- 同上 -->
  </body>
</html>
复制代码

3,信息展示区布局样式

增加我们的CSS实现

<!-- 现在我们的DOM结构如下 -->
<!DOCTYPE html>
<html>
  <head>
    <title>demo</title>
    <style type="text/css">
      .g-container{
        width: 1200px;
        margin: auto;
      }
    </style>
  </head>
  <body>
    ...
  </body>
</html>
复制代码

4,展示区进行布局规划

图中我用绿色框表示对信息展示区的布局规划。(以demo设计图中我们的服务这个内容展示块为例)
我们的服务可以被设计成成三行:

  • 第一行标题内容——单列;
  • 第二行服务介绍——三列;
  • 第三行服务介绍——三列


.g-row表示行布局,.g-col-*表示列布局


<!-- 现在我们的DOM结构如下 -->
<!DOCTYPE html>
<html>
  <head>
    <title>demo</title>
    <style type="text/css">
      .g-container{
        width: 1200px;
        margin: auto;
      }
    </style>
  </head>
  <body>
    ...
    <div class="block-service">
      <div class="g-container">
        <!-- 第一行 -->
        <div class="g-row">我们的服务</div>
        <!-- 第二行 -->
        <div class="g-row">
          <div class="g-col-4"></div>
          <div class="g-col-4"></div>
          <div class="g-col-4"></div>
        </div>
        <!-- 第三行 -->
        <div class="g-row">
          <div class="g-col-4"></div>
          <div class="g-col-4"></div>
          <div class="g-col-4"></div>
        </div>
      </div>
    </div>
	...
</body>
</html>
复制代码

样式:我们使用的12格栅格

<style>
  .g-row{
    width: 100%;
  }
  .g-row:after{
    content: "";
    display: table;
    clear: both;
  }
  .g-col-4{
    float: left;
    width: 33.33333%;
  }
</style>
复制代码

分析设计结束回头看DOM树已经有了一个整体的框架,就好比建一栋高楼现在大楼的主体结构已经搭建完毕接下来需要墙体装修,然后就是每层每户装修,在然后就是房间装修搬家具入住


三,DOM之后的CSS(成品展示)

有了上面DOM结构的设计,在装修阶段(CSS)如果乱搞一通结果也是豆腐渣工程。结合上面DOM的设计CSS的设计有需怎样呢。
提示:下面代码基于sass,使用less的同学整体思路差不多。(假设场景:重构demo网站的首页,sass文件命名index.scss)

1,sass——展示块命名

下面实现中展示块以block-作为前缀,在实际场景中如果是首页可以采用index-或者加网站名简写(azoyaclub:ac)acindex-,详情页使用detail-acdetail
关于块前缀的建议: 如果你的前缀使用了两个以上的单词,建议不要使用驼峰或者-_连接,直接写成word1word2-。因为我们对前缀的需求是功能划分,虽是两个单词但只是名称归类的作用,写在一起简单明了,方便区分、管理

//index.scss
.block{
  &-head{
    ...
  }
  &-nav{
    ...
  }
  &-banner{
    ...
  }
  &-service{
    ...
  }
  &-global{
    ...
  }
}
复制代码

2,sass——布局命名

学习bootstrap的经验,布局实现做网站公共样式,以.g-*作为标识

// _layout.scss
$gridColumns: 12;

.g-{
  &-container{
    ...
  }
  &-row{
    ...
  }
}

@for $i from 1 through $gridColumns { 
  .g-col-#{$i} { 
    width: (1 / $i) * 100%; 
  } 
}
复制代码

3,sass——全局模块命名

全局模块也就是全站共用模块,整站的input、button、dialog、商城的商品块等。 相信大家如果看过比较有名点的网站,在他们的DOM中经常能看到以.m-*.mod-*.module-*命名的class。
对于表示状态的场景个人习惯.m-name.active.m-name.disable的方式

题外话,工作中为了节省开发时间通常会使用到第三方的通用UI组件,不管怎样能有一个自己的UI框架听起来就很不错。老实说,如果你在完成全局模块这一步有追求的话(质量高,通用性强),然后将他们从项目中独立出来,恭喜你,你就有用了一个至少自己用起来顺手的UI框架

// dialog 实现
%placeholer-button{
  ...
}
.m-dialog{
  &-title{
    ...
  }
  &-content{
    ...
  }
  &-cancle{
    @extend %placeholer-button
  }
  &-ok{
    @extend %placeholer-button
  }
}
复制代码
// button实现
%placeholder-button{
  ...
  &.active{
    ...
  }
  &.disable{
    ...
  }
}
.m-button{
  &-primary{
    ...
    @extend %placeholder-button
  }
  &-hollow{
    ...
    @extend %placeholder-button
  }
}
复制代码

4,sass——页面级模块命名

在JS中我们有全局变量、局部变量,在CSS中同样可以区分上面提到的全局模块和接下来介绍的页面级模块
打开我们的demo网站我们的服务包含6个服务介绍模块、全球商家包含8个商家介绍模块,他们是专属于首页的,那我们的解决方案是什么呢

// index.scss

// block
.block{
  &-head{
    ...
  }
  ...
}
// module
.service{
  &-pic{
  ...
  }
  &-title{
    ...
  }
  &-content{
    ...
  }
}
.business{
  &-pic{
    ...
  }
  &-logo{
    ...
  }
  ...
}

复制代码

看scss文件,我们是直接在当前页面对应的scss文件(index.scss)中按模块进行开发。如果你担心发生命名冲突,可以加前缀.p-service-*.p-business-*或者其它你喜欢的前缀方式

5,sass——样式覆盖

我们把一个模块样式写好了,面对我们产品的奇思妙想要百分百适用于全站大多时候是不可能的,这就需要我们对模块的某些样式进行覆盖重写。
回顾: 前面我们对DOM树进行设计时已经将页面划分多个独立的内容展示块,而这些全局模块是属于这个内容展示块的,所以想要覆盖全局模块的样式,我们的方案是在他所属的内容展示块中(辈分关系——祖孙)实现为

  .block-xx{
    .m-x-xx{
      ...    
    }
  }
复制代码

建议: 可以在内容展示块上进行重写或者给模块新加一个class,而不是我们常见的以模块元素的直接父元素进行重写

// 不建议
.block-xx{
  
  &-global{
    .m-button-primay{
      ...
    }
  }
}

// 建议
.block-xx{
  .m-button-primay{
    ...
  }
}
// 或者
.m-button-primay{
  &.new-button-primay{
    ...
  }
}
复制代码

四、HTML5语义标签总结版

如果你有耐心看到这里,或者你有点认同对上面所讲的理解了,恭喜你,我又要说点不一样的东西。
个人认为好的DOM设计、适合的CSS命名是当其它开发者在浏览你的代码又或者是浏览器渲染页面时大家在做一次对话。
下面结合HTML5的语义标签让我们的重构之路更上一层楼

1,语义标签理解

  • header nav section aside footer :划分模块——处于相同的上下文。

    什么意思呢,我们把一个网页比作人。人分头、胸、手、屁股、腿和脚,从局部看他们是独立的,但他们是组成人这个整体的一员。

  • article figure video: 划分模块——可独立存在。

    这又是什么意思呢,依旧把网页比作人,人身上可以有项链、戒指、手机、手表和MP3。戒指可以在左手上,也可以在右手上,鼻子耳朵上也可能有,他们属于人,但他们作为一个物体独立存在,没有任何功能和语境上的限制。

  • ul dl em i:这些大家应该比较熟悉了
  • div span: 没有语义

2,语义标签的DOM设计

有了上面标签语义的基础,我们再来设计我们的DOM树

  • 使用header nav section aside footer进行内容展示块的划分
  • 使用没有语义的div 来实现布局,当然也可以用ul+li的方式
  • 使用article figure video进行全局模块和页面级模块的划分
a,信息展示块
<!-- 现在我们的DOM结构如下 -->
<!DOCTYPE html>
<html>
  <head>
    <title>demo</title>
    <style type="text/css">
      ...
    </style>
  </head>
  <body>
    <header class="block-head"></header>
    <nav class="block-nav"></nav>
    <main>
      <section class="block-banner"></section>
      <section class="block-service"></section>
      <section class="block-global"></section>
    </main>
    <aside class="block-aside"></aside>
    <footer class="block-footer"></footer>
  </body>
</html>
复制代码
b,布局
<!-- 现在我们的DOM结构如下 -->
<!DOCTYPE html>
<html>
  <head>
    <title>demo</title>
    <style type="text/css">
      ...
    </style>
  </head>
  <body>
    ...
    <main>
      <section class="block-service">
        <div class="g-container">
          <div class="g-col-4"></div>
          <div class="g-col-4"></div>
          <div class="g-col-4"></div>
        </div>
      </section>
    </main>
    ...
  </body>
</html>
复制代码
c,模块填充
<!-- 现在我们的DOM结构如下 -->
<!DOCTYPE html>
<html>
  <head>
    ...
  </head>
  <body>
    ...
    <main>
      <section class="block-service">
        <div class="g-container">
          <div class="g-col-4">
            <!-- service模块 -->
            <article class="m-service"></article>
          </div>
          <div class="g-col-4">
            <!-- 展示图片 -->
            <figure class="p-info">
              ...
            </figure>
          </div>
          <div class="g-col-4">
            <!-- 引入视频 -->
            <video></video>
          </div>
        </div>
      </section>
    </main>
    ...
  </body>
</html>
复制代码

总结

前面讲了这么多,主要是从大局观上看DOM树的设计,CSS命名方式,算是抛砖引玉吧。
一个好的DOM、CSS代码设计方案只是提升我们工作效率和代码质量的基础,要做一个追求完美的切图仔还是需要过硬的基础知识(不知道从什么时候开始,出去面试大多只是考察javascript的知识,对于页面重构好像你知道就行了,哈哈哈哈哈哈哈~~~~)
前面涉及到的代码展示只是布局相关,想写好一个全局模块的样式对于CSS的掌握还是有一定要求的,这里推荐张鑫旭老师的博客,对于CSS3和sass的知识推荐大漠老师的博客网站

写在最后

本来表达能力就比较差,就这样磨蹭着写完了,也不知一些东西讲清楚了没。有疑问或有好的建议的可以在下面留言分享下。

补充

这里主要从大局观出发探讨页面重构的方案,如何在繁杂的标签嵌套中理清脉络,并不涉及到如何去实现页面(这可不是一篇文章就能讲清楚的,对于页面模块的实现需要大家多多积累)。如果你理解了或者你已经有了解决这个问题的答案,那么当我们在使用vue、react开发时遇到组件划分这个问题也将不是问题。祝你好运!

关注下面的标签,发现更多相似文章
评论