如何构建CSS

既然你已经了解了什么是CSS,以及使用CSS的基础知识,是时候更深入的了解该语言本身的结构了。我们已经见过了本页讨论的很多概念;如果在之后对某些概念感到困惑的话,可以返回至此进行回顾。

前置知识

在开始本单元之前,您应该:

目标

  • 理解 HTML文档链接CSS文档的几个基本套路,
  • 并能运用所学的CSS,做些文字上的格式化操作。

在你的HTML里面应用CSS

我们需要了解的第一件事情就是在文档中应用CSS的三种方法

外部样式表

Getting started with CSS 中我们将外部样式表链接到页面。这是将css附加到文档中的最常见和最有用的方法,因为您可以将css链接到多个页面,从而允许您使用相同的样式表设置所有页面的样式。在大多数情况下,一个站点的不同页面看起来几乎都是一样的,因此您可以使用相同的规则集来获得基本的外观。

外部样式表是指将CSS编写在扩展名为.css 的单独文件中,并从HTML<link> 元素引用它的情况:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>My CSS experiment</title>
    <link rel="stylesheet" href="styles.css">
  </head>
  <body>
    <h1>Hello World!</h1>
    <p>This is my first CSS example</p>
  </body>
</html>

CSS文件可能如下所示:

h1 {
  color: blue;
  background-color: yellow;
  border: 1px solid black;
}

p {
  color: red;
}

<link> 元素的 href 属性需要引用你的文件系统中的一个文件。

在上面的例子中,CSS文件和HTML文档在同一个文件夹中,但是你可以把CSS文件放在其他地方,并调整指定的路径以匹配,例如:

<!-- Inside a subdirectory called styles inside the current directory -->
<link rel="stylesheet" href="styles/style.css">

<!-- Inside a subdirectory called general, which is in a subdirectory called styles, inside the current directory -->
<link rel="stylesheet" href="styles/general/style.css">

<!-- Go up one directory level, then inside a subdirectory called styles -->
<link rel="stylesheet" href="../styles/style.css">

内部样式表

内部样式表是指不使用外部CSS文件,而是将CSS放在HTML文件<head>标签里的<style>标签之中。

于是HTML看起来就像下面这个样子:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>My CSS experiment</title>
    <style>
      h1 {
        color: blue;
        background-color: yellow;
        border: 1px solid black;
      }

      p {
        color: red;
      }
    </style>
  </head>
  <body>
    <h1>Hello World!</h1>
    <p>This is my first CSS example</p>
  </body>
</html>

有的时候,这种方法会比较有用(比如你使用的内容管理系统不能直接编辑CSS文件),但该方法和外部样式表比起来更加低效 。在一个站点里,你不得不在每个页面里重复添加相同的CSS,并且在需要更改CSS时修改每个页面文件。

内联样式

内联样式表存在于HTML元素的style属性之中。其特点是每个CSS表只影响一个元素:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>My CSS experiment</title>
  </head>
  <body>
    <h1 style="color: blue;background-color: yellow;border: 1px solid black;">Hello World!</h1>
    <p style="color:red;">This is my first CSS example</p>
  </body>
</html>

除非你有充足的理由,否则不要这样做!它难以维护(在需要更新时,你必须在修改同一个文档的多处地方),并且这种写法将文档结构和文档表现混合起来了,这使得代码变得难以阅读和理解。将不同类型的代码分开存放在不同的文档中,会让我们的工作更加清晰。

在某些地方,内联样式更常见,甚至更可取。 如果您的工作环境确实很严格(也许网站管理系统(CMS)仅允许您编辑HTML正文),则可能不得不使用它们。 您也会发现它们很长时间被应用在HTML电子邮件中,以便与尽可能多的电子邮件客户端兼容。

在文本中使用CSS

有的时候我们会在文本中使用大量的CSS。为了做到这些,我们推荐你在你的计算机上创建一个新的文件夹,然后在文件夹中创建下面两个文件的副本。

index.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>My CSS experiments</title>
    <link rel="stylesheet" href="styles.css">
  </head>
  <body> 

    <p>Create your test HTML here</p>

  </body>
</html>

styles.css:

/* Create your test CSS here */

p {
  color: red;
}

然后,当您遇到一些您想要试验的CSS时,替换HTML<body>内容与一些HTML样式,并开始添加CSS样式在您的CSS文件。

如果你没有可以轻松创建文件的系统,则可以使用下面交互式编译器进行实验。

 

继续读下去,希望你能享受其中!

选择器

讲到CSS就不得不说到选择器, 并且在之前的辅导教程中我们已经列举了一些不同的选择器。为了样式化某些元素,我们会通过选择器来选中HTML文档中的这些元素。如果你的样式没有生效,那很可能是你的选择器没有像你想象的那样选中你想要的元素。

每个CSS规则都以一个选择器或一组选择器为开始,去告诉浏览器这些规则应该应用到哪些元素上。以下都是有效的选择器或组合选择器的示例。

h1
a:link
.manythings
#onething
*
.box p
.box p:first-child
h1, h2, .intro

尝试创建一些使用上述选择器的CSS规则,并创建一些HTML样式。如果您不知道上面的一些语法意味着什么,请尝试在MDN上搜索它!

注意:在下一个模块中,您将在我们的CSS选择器教程中了解更多关于选择器的内容。

专一性

通常情况下,两个选择器可以选择相同的HTML元素。考虑下面的样式表,其中我有一个规则,其中有一个将段落设置为蓝色的p选择器,还有一个将选定元素设置为红色的类。

.special {
  color: red;
}

p {
  color: blue;
}

比方说,在我们的HTML文档中,我们有一个带有特殊类的段落。这两条规则都适用,那么谁赢了?你认为我们的段落会变成什么颜色?

<p class="special">What color am I?</p>

CSS语言有规则来控制在发生碰撞时哪条规则将获胜--这些规则称为级联规则和专用规则。在下面的代码块中,我们为p选择器定义了两个规则,但是段落最后是蓝色的。这是因为将其设置为蓝色的声明将出现在样式表的后面,而稍后的样式将覆盖以前的样式。这就是起作用的级联。

p {
  color: red;
}

p {
  color: blue;
}

但是,在我们使用类选择器和元素选择器的早期块中,类将获胜,使得段落变红--即使它出现在样式表的前面。一个类被描述为比元素选择器更具体,或者具有更多的特异性,所以它获胜了。

自己试试上面的实验--将HTML添加到您的实验中,然后将两个p{.}规则添加到样式表中。接下来,将第一个p选择器更改为.Special,以查看它如何更改样式。

一开始,具体性和层叠的规则看起来有点复杂,一旦你积累了更多的CSS知识,就更容易理解了。在我们的级联和继承文章(将在下一个模块中讨论)中,我将详细解释这一点,包括如何计算专用性。现在,请记住这是存在的,有时CSS可能不会像您预期的那样应用,因为样式表中的其他内容具有更高的特异性。确定一个元素可以适用不止一个规则是解决这些问题的第一步

属性和值

在最基本的层面上,CSS由两个组成部分组成:

  • 属性:人类可读的标识符,指示您想要更改的样式特征(例如font-size, width, background-color) 你想改变。
  • 值:每个指定的属性都有一个值,该值指示您希望如何更改这些样式特性(例如,要将字体、宽度或背景色更改为。)

下面的图像突出显示单个属性和值。 属性名为 color, 值为 blue.

A declaration highlighted in the CSS

与值配对的属性称为CSS声明。CSS声明放在CSS声明块中。下一张图片显示了我们的CSS,并突出显示了声明块。

A highlighted declaration block

最后,CSS声明块与选择器配对,以生成CSS规则集(或CSS规则)。我们的图像包含两个规则,一个用于H1选择器,另一个用于p选择器。h1的规则被突出显示。

The rule for h1 highlighted

将CSS属性设置为特定值是CSS语言的核心功能。CSS引擎计算哪些声明应用于页面的每个元素,以便适当地布局和样式它。重要的是要记住,在css中,属性和值都是区分大小写的。每对中的属性和值由冒号(:)分隔。

尝试查找以下属性的不同值,并编写将它们应用于不同HTML元素的CSS规则:

重要事项:如果属性未知或某个值对给定属性无效,则声明被视为无效,并被浏览器的CSS引擎完全忽略。

重要:在CSS(和其他网络标准)中,当语言表达存在不确定性时,美国的拼写被视作公认的标准。例如,颜色应该始终拼写为color。colour是不起作用的。

函数

虽然大多数值是相对简单的关键字或数值,但也有一些可能的值以函数的形式出现。一个例子是calc()函数。这个函数允许您在CSS中进行简单的计算,例如:

<div class="outer"><div class="box">The inner box is 90% - 30px.</div></div>
.outer {
  border: 5px solid black;
}

.box {
  padding: 10px;
  width: calc(90% - 30px);
  background-color: rebeccapurple;
  color: white;
}

如下所示:

一个函数由函数名和一些括号组成,其中放置了该函数的允许值。在上面的calc()示例中,我要求此框的宽度为包含块宽度的90%,减去30像素。这不是我可以提前计算的东西,只是在CSS中输入值,因为我不知道90%会是什么。与所有值一样,MDN上的相关页面将有使用示例,这样您就可以看到函数是如何工作的。

另一个例子是<transform>, 例如 rotate().

<div class="box"></div>
.box {
  margin: 30px;
  width: 100px;
  height: 100px;
  background-color: rebeccapurple;
  transform: rotate(0.8turn)
}

以上代码的输出如下所示:

尝试查找一下属性的不同值,并编写将他们应用于不同HTML元素的CSS规则:

@规则

到目前为止,我们还没有遇到 @rules (pronounced "at-rules"). 这是一些特殊的规则,为 CSS提供了一些关于如何表现的指导。 有些@rules 规则很简单,有规则名和值。例如,要将额外的样式表导入主CSS样式表,可以使用@import:

@import 'styles2.css';

您将遇到的最常见的 @rules 之一是@media,它允许您使用 媒体查询 来应用CSS,仅当某些条件成立(例如,当屏幕分辨率高于某一数量,或屏幕宽度大于某一宽度时)。

在下面的 CSS中,我们将给 <body> 元素一个粉红色的背景色。但是,我们随后使用@media创建样式表的一个部分,该部分仅适用于视口大于30em的浏览器。如果浏览器的宽度大于30em,则背景色将为蓝色。

body {
  background-color: pink;
}

@media (min-width: 30em) {
  body {
    background-color: blue;
  }
}

在这些教程中,你将遇到一些其他的规则 @rules 

查看是否可以将媒体查询添加到CSS中,该查询将根据视口宽度更改样式。更改浏览器窗口的宽度以查看结果。

速记属性

一些属性,如 font, background, padding, border, and margin 等属性称为速记属性--这是因为它们允许您在一行中设置多个属性值,从而节省时间并使代码更整洁。

例如,这一行代码:

/* In 4-value shorthands like padding and margin, the values are applied
   in the order top, right, bottom, left (clockwise from the top). There are also other 
   shorthand types, for example 2-value shorthands, which set padding/margin
   for top/bottom, then left/right */
padding: 10px 15px 15px 5px;

与这四行代码是等价的:

padding-top: 10px;
padding-right: 15px;
padding-bottom: 15px;
padding-left: 5px;

这一行:

background: red url(bg-graphic.png) 10px 10px repeat-x fixed;

与这五行代码是等价的:

background-color: red;
background-image: url(bg-graphic.png);
background-position: 10px 10px;
background-repeat: repeat-x;
background-attachment: fixed;

我们现在不打算详尽地教授这些内容--在后面的课程中,您将看到许多例子,我们建议您查找CSS参考中的速记属性名称,以查找更多内容。

尝试将上述声明添加到CSS中,看看它如何影响HTML的样式。试着尝试一些不同的属性值。

警告:虽然速记经常允许您忽略值,但它们会将不包含的任何值重置为它们的初始值。这确保使用了一组合理的值。但是,如果您期望速记只更改传入的值,这可能会使您感到困惑。

注释

与任何的代码工作一样,在编写CSS过程中,最好的练习方式就是添加注释。这样做可以帮助您在过了几个月后回来修改或优化代码时了解它们是如何工作的,同时也便于其他人理解您的代码。

CSS中的注释以/*开头,以*/结尾。在下面的代码块中,注释标记了不同代码节的开始。当代码库变得更大时,这对于帮助您导航代码库非常有用--在代码编辑器中搜索注释可以高效地定位代码节。

/* Handle basic element styling */
/* -------------------------------------------------------------------------------------------- */
body {
  font: 1em/150% Helvetica, Arial, sans-serif; 
  padding: 1em; 
  margin: 0 auto; 
  max-width: 33em;
}

@media (min-width: 70em) {
  /* Let's special case the global font size. On large screen or window,
     we increase the font size for better readability */
  body {
    font-size: 130%;
  }
}

h1 {font-size: 1.5em;}

/* Handle specific elements nested in the DOM  */
/* -------------------------------------------------------------------------------------------- */
div p, #id:first-line {
  background-color: red; 
  border-radius: 3px;
}

div p{
  margin: 0; 
  padding: 1em;
}

div p + p {
  padding-top: 0;
}

“注释掉”代码这一操作常用于在测试中临时禁用一段代码。例如,如果您试图找出代码的哪一部分会导致错误。在下例中,.special selector规则被“注释”掉了,也就是被禁用了。

/*.special { 
  color: red; 
}*/

p { 
  color: blue; 
}

添加一些注释到您的CSS,以适应使用他们。

空白

空白是指实际空格、制表符和新行。以与HTML相同的方式,浏览器往往忽略CSS中的大部分空白;许多空白只是为了提高可读性。

在下面的第一个示例中,我们将每个声明(以及规则开始/结束)都放在自己的行中--这可以说是编写CSS的好方法,因为它使维护和理解变得更加容易:

body {
  font: 1em/150% Helvetica, Arial, sans-serif;
  padding: 1em;
  margin: 0 auto;
  max-width: 33em;
}

@media (min-width: 70em) {
  body {
    font-size: 130%;
  }
}

h1 {
  font-size: 1.5em;
}

div p,
#id:first-line {
  background-color: red;
  border-radius: 3px;
}

div p {
  margin: 0;
  padding: 1em;
}

div p + p {
  padding-top: 0;
}

您可以编写完全相同的CSS,删除大部分空格--这在功能上与第一个示例相同,但我相信您肯定也觉得阅读起来有点困难:

body {font: 1em/150% Helvetica, Arial, sans-serif; padding: 1em; margin: 0 auto; max-width: 33em;}
@media (min-width: 70em) { body {font-size: 130%;} }

h1 {font-size: 1.5em;}

div p, #id:first-line {background-color: red; border-radius: 3px;}
div p {margin: 0; padding: 1em;}
div p + p {padding-top: 0;}

您选择的代码布局通常是个人偏好,尽管当您开始在团队中工作时,您可能会发现现有团队有自己的样式指南,指定要遵循的约定。 

在CSS中,属性和它们的值之间的空格需要小心。

例如,以下声明是有效的CSS:

margin: 0 auto;
padding-left: 10px;

以下内容无效:

margin: 0auto;
padding- left: 10px;

“0auto”不被识别为边距属性的有效值(“0”和“AUTO”是两个独立的值),而浏览器会将“padding- ”识别为有效属性。因此,您应该始终确保通过至少一个空格将不同的值分隔开来,但将属性名称和属性值作为单个未中断的字符串放在一起。

试着在CSS中使用空格,看看什么情况下破坏了东西,什么时候没有破坏

接下来是什么?

了解一下浏览器如何将HTML和CSS转换成网页是很有用的, 所以在下一篇文章 — CSS是如何工作的 — 我们将看看这个过程。

在这个模块中

  1. 什么是CSS?
  2. 开始使用CSS 
  3. 如何构建CSS  
  4. CSS是如何工作的
  5. 使用你的新知识