阅读 934

设计DOM&CSS

本文有点长,有兴趣的同学欢迎耐心阅读

在页面重构过程中同一个页面让10个不同的前端人员开发,最终的页面展示效果肯定是一样的,可背后的代码设计却是10种不同的风格,有的杂乱无章,标签胡乱嵌套;有的规划有序,标签和样式命名合理、明了。

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

一,观察设计图(设计方案)


无论是这个demo网站的设计还是其它任何类型的网站设计,我们都可以对页面做以下分析:

  • 一个页面可以按展示内容或设计图效果被划分成多个独立的展示块
  • 每个展示块限定了信息展示区域。全屏风格——信息展示区为全屏;限定宽度(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">
		<div class="g-container"></div>
	</div>
	<!-- 同上 -->
</body>
</html>
复制代码
3,内容展示区的限定区域居中

布局实现主要依靠CSS,增加我们的CSS实现,用类名.g-container表示内容展示区的限定区域

<!-- 现在我们的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>
	</div>
	<!-- 同上 -->
</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模块化方案计,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,而不是我们常见的以模块元素的直接父元素进行重写

// index.scss

// block
.block{
	...
	&-global{
		.m-button-primay{
			...
		}
	}
}

复制代码

四、HTML5语义标签总结版

如果你有耐心看到这里,或者你对上面所讲的理解了,恭喜你,我又要说点不一样的东西。
我一直认为好的DOM设计、适合的CSS命名,当我们在打开浏览器的调试模式切换到elemnet这一栏时是在与开发者进行一次对话。
结合我们上面说的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>
	<title>demo</title>
	<style type="text/css">
		...
	</style>
</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的知识推荐大漠老师的博客网站

写在最后

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

补充

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

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