1. 1. Let’s Go Go Go
  2. 2. 准备工作
    1. 2.1. 页面模版
    2. 2.2. 利用browser-sync实时刷新页面
    3. 2.3. 引入normalize.css
  3. 3. 导航页面
    1. 3.1. BEM
    2. 3.2. 完成导航
  4. 4. 总结
Table of Contents ▼

CSS第一课 你热了么

按照Sketch设计稿,实现一个完整的页面:

希望你学完这一些列课程后,能够系统地掌握CSS,真正把CSS玩转

Let’s Go Go Go

首先下载素材文件(Windows用户可以下载pdf版

设计稿

用Sketch打开文件后(可能会出现找不到字体的问题,字体下载),你可以通过commad + 1 将Artboard缩放至视口大小。

按住control + L可以显示出栅格系统,栅格系统可以帮你快速排版。

如果你不熟悉sketch,想了解更多,同时不占用你写代码的时间,可以看看这篇用Sketch制作登录页面的教程

我们之后会单独推送一期sketch的教程,现在还是主要关注代码。

准备工作

新建一个html文件和css文件
├── css
│ └── style.css
└── index.html

页面模版

还记得在HTML的课程中,为了保持代码的一致性并节省时间,保存的html模板么

大多数编辑器都允许你按照自己的风格定制模板

如果你用的atom,参考atom代码补全snippets配置

<!DOCTYPE html>
<html lang="zh-cmn-Hans">
  <head>
    <title>CSS Lesson 1</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
    <meta http-equiv="Cache-Control" content="no-siteapp">
    <link href="css/normalize.css" rel="stylesheet">
    <link href="css/style.css" rel="stylesheet">
  </head>
  <body>

  </body>
</html>

利用browser-sync实时刷新页面

为了省去每次修改代码后都要手动刷新页面,我习惯使用browser-sync监听文件,自动刷新浏览器

  1. 安装Browsersync
    npm install -g browser-sync
  2. 运行Browsersync
    browser-sync start --server --files index.html --files "css/*.css"

引入normalize.css

Normalize.css,保证默认元素在不同浏览器上变现一致。

Normalize.css 只是一个很小的CSS文件,但它在默认的HTML元素样式上提供了跨浏览器的高度一致性。相比于传统的CSS reset,Normalize.css是一种现代的、为HTML5准备的优质替代方案。——来,让我们谈一谈 Normalize.css

导航页面

根据设计稿,我们把整个页面分为三个部分,头部、内容区域、页脚

<header class = "site__header">      
</header>
<main class = "site__main">      
</main>
<footer class = "site__footer">
 </footer>

用BEM作为CSS的命名规范,虽然site__header丑了点,但是在你代码越来越多的时候,这个东西可以让你的代码没那么混乱

BEM

BEM 其实很简单,有点面向对象编程的意思,不过比OOP还简单直接。只要记住,BEM是由Block(块)Element(元素)Modifier(修饰符)组成,__连接Element,--连接Modifier;你把代码按照模块来组织。举个例子:

.person{}
.person__avatar{}
.person__avatar--round{}

我们有一个personBlock,每个人都有头像、名字、描述之类的,所以我们用到.person__element;头像我们可能需要方的、圆的……都需要对这些进行单独设置,所以这时候对每个元素就用到Modifier。代码非常扁平是不是,如果按照我们以前的写法,可能就是这样:

.person{}
.person .avatar{}
.round{}

好像除了长一点,没什么区别呀!
那现在加一个动物,加个狗吧:

.dog{}
.dog .avatar{}
.round{}

现在有个人养了一条狗,我们的HTML是这样:

<div class  = "person">
    <div class = "avatar"></div> <!-- 人头 -->
        …

    <!-- dog -->
    <div class = "dog">
        <div class = "avatar round"> <!-- 狗脑 -->
    </div>
</div>

有没有晕乎乎的感觉,这两个avatar是一样的还是不一样的,到底应用了哪条样式,还有没有公共的样式+_+?(模块这个东西看起来很悬,不同人理解可能也有偏差,但是你只要用着舒服就行了,写多了,你就知道到底怎么按模块化来写代码了)

完成导航

HTML结构

<header class="site__header">
    <nav class="navbar">
      <a class="navbar__brand" href="#">Company Logo</a>
      <ul class="navbar__nav list-nostyle">
        <li><a href="#">Platform</a></li>
        <li><a href="#">About</a></li>
        <li><a class="active" href="#">Sign Up</a></li>
      </ul>
    </nav>
  </header>

运行
browser-sync start --server --files 'index.html' --files "css/*.css"

好了,改点样式让它看来好看点

  1. 给导航设置一个固定高度
  2. 去掉li默认的样式
  3. 左右布局
/* list with no style
  ========================================================================== */

/**
* 1. remove the margin and padding
* 2. remove list style
*/

.list-nostyle{
  margin: 0;
  padding: 0;
}
.list-nostyle li{
  list-style: none;
}

/* site header
  ========================================================================== */

.site__header{
  height: 70px;
}
.navbar{
  padding: 15px 20px;
}
.navbar__brand{
  float: left;
}
.navbar__nav{
  float: right;
}
.navbar__nav li{
  display: inline-block;
}

首先,我们为页眉设置了一个70px的高度

通过浮动来实现Logo左对齐,导航右对齐

因为<li>块级元素,所以会产生换行,我们把li设置成inline-block,在同一行显示

<a>标签我们一般更习惯不要下划线,而是通过颜色来突出是链接,所以我们把<a>标签的下划线统一去掉:

a{
    text-decoration: none;
}

现在你看到的应该是这样:

inline-block空格的问题

现在回去看看,有个问题需要处理一下:

PlatFormAboutSign Up之间为什么会有间隙?**

使用了inline-blockinline-block会表现得像文字排版一样,<li><li>之间存在空白符,所以最后产生了一个空格

有各种奇奇怪怪的方法可以解决这个问题,这里我只给出我平常用得最多的两个方法:

  • 设置font-size: 0;(如果浏览器设置了最小字体大小要跪。。。)

      ul{
          font-size: 0;
      }
      li{
          display: inline-block;
          font-size: 1rem;
      }
    
  • 去掉标签之间的空白符

      <li>…</li><li>…</li><li>…</li>
    

喜欢哪个方法就用哪个,快自己把这个bug修复了

美化导航样式

.navbar__brand, .navbar__nav li a{
  display: inline-block;

  box-sizing: border-box;
  height: 40px;
  padding: 8px 24px 8px 24px;
  border: 1px solid #ccc;

  line-height: 22px;
}

这里加了边框方便调试:

  • 为了能够设置在垂直方向上的高度(padding-top/bottom, margin-top/bottom, height):我们设置行内元素<a> displayinline-block

    行内元素是就像水一样,垂直方向上设置高度都没用,所以有时候需要设置为inline-blockblock
    有个形象的比喻,inline=>水,inline-block=>果冻,block=>石头

  • 设置box-sizingborder-box

    默认情况下,元素的height只包括内容区域。但是我们经常需要加入border或者padding,元素的高度的实际高度是padding + border + height,每次你都需要减去paddingborder。除了计算麻烦之外,用百分比设置高度的时候,你经常会遇到内容区域溢出的问题:

      <style>
        html,body{
          height: 100%;
          width:100%;
        }
        .container{
          padding: 0 20px;
        }
      </style>
    </head>
    <body>
      <div class="container">
        Hello World
      </div>
    </body>
    

  • 通过line-height进行垂直居中:
    css中水平居中很简单,但是垂直居中就不好做了。通过设置line-height等于height可以让文字垂直居中。关于居中的问题,参考[译]CSS居中完全指南http://www.voyax.me/2016/04/19/译-CSS居中完全指南/

    最后还有一个大坑!!!

为啥navbar高度没有撑开!!!好吧,都是float的错,float导致元素溢出了文档流,从而父元素的高度不会随着float元素高度的变化而适应。
单从float的角度说,有两个思路:

  1. 将父元素变成BFC
  2. 清除浮动

代码如下:

通过overflow触发BFC

.navbar::after{
    overflow: hidden;
}

clearfix(关于clearfix的讨论,看看stackoverflow上的这个讨论

.clearfix:after {
   content: " "; /* Older browser do not support empty content */
   visibility: hidden;
   display: block;
   height: 0;
   clear: both;
}

总结

这一章主要带着你踩踩坑,介绍了几个开发中经常遇到的问题。下一张我们看看在实际开发中,如果从零开始组织你的代码,同时逐步完成这个页面。