前言
这篇文章是CSS布局系列的第六篇文章。前面几篇文章简单介绍了CSS盒模型,CSS的几种布局模型。在这篇文章中,我想跟大家聊一下如何利用CSS和html将网页的设计图转换成实际可以在前端工程中使用的html和css资源,或者也可以说复现已有的网页页面结构。
在如上图所示的框图中,html5+css3就是一个blackbox,我们需要做的事情就是解开这个blackbox的结构,使得输入和输出的静态网页页面看起来一模一样。
第一步:设计稿界面分区
要想还原页面,首先要做的就是将拿到的设计稿或者html页面进行分区。分区的方法是:
- 对页面划分区域,一般的网页都会有:标题栏、导航栏、主页面、侧边栏、脚注。第一步,需要把这几个元素都找出来
- 分别对每个元素进行分析,该元素由哪几部分组成,排列方向是怎样的 以掘金首页为例:
该页面的导航栏和标题栏是在一起的,在导航栏之后的部分是主页面和侧边栏,没有脚注。粗略划分之后的结果如下图所示: 接下来要做的事情是确定每个元素的布局方式
- 标题栏/导航栏: 该页面的导航栏分为两个部分,如果点一下最上面的导航栏标签会发现,第二个导航栏的内容会根据第一个导航栏的标签变化而变化。这说明这两个导航栏之间有包含关系。每一个导航栏都是单行的排列,因此采用
flex
布局可以很方便的实现。 - 主页面: 主页面是文章列表,它包含两个部分:热门/最新/热榜三个标签,文章简要信息的卡片。标签部分是由排成一行的三个小标签组成,它可以使用
flex
布局;文章简要信息的卡片,每一个的样式都是相同的,因此,CSS样式的代码只需要做好一个小卡片即可。文章的小卡片可以分为两列,左边的一列是文章的信息,右边的一列是文章的封面,可以使用flex
布局。文章的信息又可以分为四行,第一行标明了文章的作者、日期,以及文章的标签;第二行是文章的题目,第三行是文章的简介;第四行标明浏览量、点赞量,以及评论的数目。关于这部分的布局,可以采用流式布局。 - 侧边栏: 侧边栏有很多信息,但都是以小卡片的形式摆放在主页面的旁边。只需要把每一个部分都做好,然后按照文档流的布局方式放在这边即可。
第二步:html结构确定以及页面分区
在分析好设计图或者现成网页的布局之后就可以构建html骨架结构了。根据第一步分析的结果,html文件的结构如下:
<!DOCTYPE HTML>
<html>
<head>
<title>掘金首页复现</title>
</head>
<body>
<!-- 导航栏 -->
<div class="nav-bar">
<div>掘金</div>
<div>首页</div>
<div>沸点</div>
<div>资讯</div>
...
</div>
<div class="sub-nav-bar">
<div>推荐</div>
<div>关注</div>
...
</div>
<!-- 主页面容器 -->
<div class="main-container">
<!-- 主页面 -->
<div class="main">
<!-- 主页面的小标签 -->
<div class="tags">
<div>热门</div>
<div>最新</div>
<div>热榜</div>
</div>
<!-- 文章列表的容器 -->
<div class="article-container">
<div class="article-item">
<div class="aritcle-content>
<div class="article-info">
<div>作者</div>
<div>时间</div>
<div>标签</div>
</div>
<h2>文章标题</h2>
<p>文章简介</p>
<div class="article-count">
<div>浏览</div>
<div>点赞</div>
<div>评论</div>
</div>
</div>
<div class="article-cover">
<img>
</div>
</div>
</div>
</div>
<!-- 侧边栏容器 -->
<div class="aside-container">
</div>
</div>
</body>
</html>
第三步:选择合适的布局模型
第二步的结果是一个比较丑的界面。如下图所示,所有的元素都挤在整个页面的小角落里。这一步,我们需要根据第一步的分析结果对这个页面添加布局和样式。 我个人的习惯是先由外到内的写布局,即先把外层的框架搭建起来,然后在往里面填元素,并且对背景、边框、边距这些参数进行调节。这就是一个体力活了,只能边写边看效果。这边只展示几个关键的代码.
- 文章列表卡片的代码:
- html
<div class="article-item">
<div class="article-item-info">
<div class="article-info-author">椿湫</div>
<div class="article-info-date">2021-07-07</div>
<div class="article-info-tags">javascript · react · 前端</div>
</div>
<h2>react学习笔记(一)</h2>
<p>这是一篇关于react的学习笔记,初步介绍了react的各种特性,以及如何安装,如何使用脚手架创建工程,构建前端项目,...</p>
<div class="article-item-count">
<div class="article-count-view">浏览:324</div>
<div class="article-count-agree">点赞:6</div>
<div class="article-count-comment">评论:5</div>
</div>
</div>
- css
.article-item {
width: 95%;
border-bottom: 1px solid #ccc;
margin: 10px;
padding: 10px;
display: flex;
flex-direction: column;
row-gap: 10px;
}
.article-item h2 {
color: var(--border-color);
}
.article-item-info {
display: flex;
color: #ccc;
font-size: 16px;
}
.article-info-author,
.article-info-date {
margin-right: 10px;
padding-right: 10px;
border-right: 1px solid #ccc;
}
.article-info-author {
color: #999;
}
.article-item-count {
display: flex;
column-gap: 20px;
color: #999;
}
- 导航栏
- html
<div class="blog-navbar-list">
<div class="blog-navbar-item"><a href="#">网站首页</a></div>
<div class="blog-navbar-item"><a href="#">前端技术</a></div>
<div class="blog-navbar-item"><a href="#">生活分享</a></div>
</div>
- css
.blog-navbar-list {
display: flex;
width: 50%;
height: calc(var(--navbar-height) - (var(--navbar-border-width))*2);
align-items: center;
column-gap: 5px;
position: relative;
padding-left: 5px;
}
.blog-navbar-item {
width: 20%;
height: calc(var(--navbar-height) - (var(--navbar-border-width))*2);
/* background-color: turquoise; */
display: flex;
justify-content: center;
align-items: center;
}
.blog-navbar-item a {
text-shadow: 2px 2px 2px #aeaeae;
text-decoration: none;
height: 100%;
width: 100%;
text-align: center;
padding: 5px;
color: #fff;
/* border: 1px solid #fff; */
font: var(--font);
font-size: 20px;
}
.blog-navbar-list :target .blog-navbar-item a,
.blog-navbar-list .blog-navbar-item a:focus,
.blog-navbar-list .blog-navbar-item a:active {
background-color: #fff;
color: var(--border-color);
box-shadow: 3px 3px 3px rgba(0,0,0,0.2);
box-shadow: 0 0 2px inset rgba(0, 0, 0, 0.5);
border-radius: 0 0 5px 5px ;
}
- 搜索框设计
- html
<div class="blog-navbar-search">
<select style="border:none;outline:medium;" class="blog-navbar-search-select">
<option>标签</option>
<option>题目</option>
<option>作者</option>
</select>
<input class="blog-navbar-search-input" style="border:none;outline:medium;" type="text" placeholder="请输入搜索内容">
<a class="blog-navbar-search-submit" href="#">搜索</a>
</div>
- css
/* 制作 3D 搜索框 */
.blog-navbar-search {
position: absolute;
display: flex;
height: var(--navbar-item-height);
width: 270px;
top: 5px;
right: 20%;
border: 1px solid var(--border-color);
border-radius: calc((var(--navbar-height) - 20px)/2);
justify-content: center;
align-items: center;
row-gap: 10px;
background-color: #fff;
box-shadow: 1px 1px #ccc inset, 1px 1px 1px #ccc;
box-shadow: 0 0 3px rgba(0, 0, 0, 0.5);
}
.blog-navbar-search-select {
border: transparent;
height: calc(var(--navbar-item-height) - 10px);
width: 50px;
color: #666;
font: var(--font);
font-weight: normal;
font-size: 12px;
}
.blog-navbar-search-input {
border: transparent;
height: calc(var(--navbar-item-height) - 10px);
width: 50%;
color: #666;
font: var(--font);
font-weight: normal;
font-size: 12px;
margin-left: 15px;
/* background-color: red; */
}
.blog-navbar-search-submit {
border: transparent;
height: calc(var(--navbar-item-height) - 10px);
width: 50px;
font: var(--font);
font-size: 12px;
font-weight: normal;
background-color: #fff;
color: #666;
text-decoration: none;
text-align: center;
margin-top: 3px;
/* margin-left: 35px; */
}
.blog-navbar-search-submit:active {
color: #fff;
text-shadow: rgba(0,0,0,1) 1px 1px 0,
rgba(0,0,0,0.8) 2px 2px 0,
rgba(0,0,0,0.25) 0 0 5px;
text-decoration: none;
}
- 列表标签设计
- html
<div class="article-list-title">
<div><a href="#">热门</a></div>
<div><a href="#">最新</a></div>
<div><a href="#">热议</a></div>
</div>
- css
.article-list-title {
display: flex;
width: 100%;
height: 50px;
border-bottom: 1px solid #ccc;
align-items: center;
}
.article-list-title div {
height: 20px;
display: flex;
align-items: center;
}
.article-list-title div a {
text-decoration: none;
font-size: 18px;
border-right: 1px solid #ccc;
/* margin: 10px; */
color: #ccc;
padding: 0 20px;
}
.article-list-title :target div a,
.article-list-title div a:active,
.article-list-title div a:focus {
color: var(--border-color);
}
.article-list-title div:nth-last-child(1){
border: none;
}
布局之后的结果
最终,我并没有真的还原这个html页面,只是参考了这个页面的部分,实现了一个新的html页面。结果如下图所示: