Date
Dec. 31st, 2024
 
2024年 12月 1日

Post: A Simple Web Development Tutorial

A Simple Web Development Tutorial

Published 12:07 Jul 21, 2019.

Created by @ezra. Categorized in #Programming, and tagged as #CSS, #Cheatsheet, #Front-end, #HTML, #JavaScript.

Source format: HTML

Table of Content

1. 概述 / Introduction

1.1. 目标 / Purpose

这篇文章的主要目标是帮助你从整体上对前端开发的基本逻辑页面实现的难易程度有一定的了解和认识

1.2. 技能 / Skills

一个网站页面的开发通常涉及到以下几种技能:

  • HTML:超文本标记语言,是 XML 语言的一个子集,用于定义网页内容的结构。

  • CSS:层叠样式表,用于为网页元素定义诸如颜色、字体、阴影等样式。

  • Script:各种不同的脚本语言可用于实现更复杂和实时的特性,最常用的是 JavaScript 语言。

1.3. 编辑器 / Editors

无论 HTML、CSS 还是 JS,其代码文件本质上都与我们常见的 txt 文件没有任何区别,因此任何可用于编辑并保存纯文本文件的编辑器均可使用,例如 Windows 自带的记事本、Atom、Visual Studio Code 等。

2. HTML

HTML 是 XML 语言的一个子集,与 XML 一样是通过 <标签名>内容</标签名> 的形式定义结构的。当然,HTML 中的标签名是有指定词汇的,浏览器会根据标签名对标签进行渲染。

2.1. 基本结构 / Basic Structure

通常,我们会在 HTML 代码第一行写上 <!DOCTYPE html> 来注明此段代码为 HTML 格式。

接下来,在最外层,我们使用 <html></html> 标签包裹以定义这段 HTML 代码的起止范围。

<html>/</html> 内,分别为 <head>/</head><body>/</body> 定义的头部和主体内容的起至范围,前者将包含页面基础信息的定义,后者将包含页面元素及其结构的定义。

下面是一段十分简单的 HTML 代码示例:

<!DOCTYPE html>
<html>
    <head>
        <title>Title</title>
        <link rel="stylesheet" href="stylesheet.css">
    </heads>

    <body>
        <div class="container">
            <p>Deserunt excepteur sunt nisi quis dolore culpa eiusmod excepteur cillum voluptate aliqua. Eiusmod proident esse aute irure deserunt aute ex sunt dolore eiusmod dolor amet eiusmod. Proident fugiat aliqua nisi Lorem anim deserunt eiusmod ut consectetur cupidatat nulla qui est ex.</p>
        </div>
    </body>

</html>

2.2. 头部 / Head

2.2.1. 标题 / Title

<head>/</head> 标签内,一般至少会使用 <title>标题文字</title> 的形式定义页面标题。

2.3. 样式 / Styles

<head>/</head><body>/</body> 标签内,我们可以将 CSS 样式直接写在 <style type="text/css"></style> 之间。

例如:

<head>
    <title>CSS</title>
    <style type="text/css">
        body {
            background-color: #ffd43b;
        }
    </style>
</head>

2.4. 脚本 / Scripts

同理,我们可以将脚本也直接写在 <script type="text/javascript"></script> 之间。

<head>
    <title>JS</title>
    <script type="text/javascript">
        console.log('before: Hello, World!');
    </script>
</head>
<body>
    <p>Anim anim et officia nostrud duis deserunt sunt incididunt eu labore consectetur mollit. Consequat aliquip nulla esse nisi eu irure reprehenderit. Dolore do ullamco velit aliqua dolore occaecat qui veniam aliqua tempor incididunt amet velit. Duis laborum Lorem tempor tempor quis ex aliquip commodo do esse duis ullamco proident mollit. Tempor voluptate exercitation adipisicing Lorem aute. Laboris culpa in eu do. Lorem exercitation ipsum laborum exercitation et adipisicing in occaecat aliqua elit sunt adipisicing.</p>

    <script type="text/javascript">
        console.log('after: Hello, World!');
    </script>
</body>

2.5. 文件链接 / File Linking

如果你使用的是外部的 CSS/JS/图标 文件,则可以通过类似下面的方式链接到页面中:

<link href="/path/to/stylesheet.css" rel="stylesheet">`
<link src="/path/to/javascript.js">`
<link href="/path/to/icon.png" rel="apple-touch-icon">

2.6. 主体 / Body

在主体部分,我们将定义页面中的各种元素及其结构关系,在 HTML 已经定义了诸多元素标签,他们大多是两两成对出现。

Table 1. 常用 HTML 标签
标签 说明 示例

div

一种通用的容器标签,没有特殊含义,一般用于对元素标签进行分组。

<div style="background: #012F48; width: 100px; height: 100px;">
    <div style="background: #1482E8; width: 50px; height: 50px; margin: 10px;">一些内容</div>
</div>
一些内容

p

段落标签,顾名思义用于放置文字段落。

<p>Velit labore ad tempor minim consectetur adipisicing.</p>

Velit labore ad tempor minim consectetur adipisicing.

a

超链接标签,一般在页面点击跳转都是使用这种标签。

<a href="http://baidu.com/">点我调转到百度</a>
点我调转到百度

span

一种通用的行内容器,并无特殊含义,一般用于对元素标签进行分组。

<p>Dolore <span style="font-size: 150%;">adipisicing quis</span> qui mollit et sint laboris.</p>

Dolore adipisicing quis qui mollit et sint laboris.

img

图像标签,用于展示指定的图像内容。并不两两成对

<img src="/path/to/image.png" width="200px" />

em

强调文字标签。

<p>Anim aliqua laboris nulla ea aliquip deserunt <em>aute<em> sit sit.<p>

Anim aliqua laboris nulla ea aliquip deserunt aute sit sit.

i

斜体文字标签。

<p>Velit aliquip anim laborum velit qui occaecat <i>deserunt deserunt</i> eu aute ipsum eu.</p>

Velit aliquip anim laborum velit qui occaecat deserunt deserunt eu aute ipsum eu.

b

粗体文字标签。

<p>Velit aliquip anim laborum velit qui occaecat <b>deserunt deserunt</b> eu aute ipsum eu.</p>

Velit aliquip anim laborum velit qui occaecat deserunt deserunt eu aute ipsum eu.

strong

重要文字标签。

<p>Velit aliquip anim laborum velit qui occaecat <strong>deserunt deserunt</strong> eu aute ipsum eu.</p>

Velit aliquip anim laborum velit qui occaecat deserunt deserunt eu aute ipsum eu.

mark

高亮文字标签。

<p>Velit aliquip anim laborum velit qui occaecat <mark>deserunt deserunt</mark> eu aute ipsum eu.</p>

Velit aliquip anim laborum velit qui occaecat deserunt deserunt eu aute ipsum eu.

s

删划线文字标签。

<p>Velit aliquip anim laborum velit qui occaecat <s>deserunt deserunt</s> eu aute ipsum eu.</p>

Velit aliquip anim laborum velit qui occaecat deserunt deserunt eu aute ipsum eu.

sub

下标标签。

<p>Velit aliquip anim laborum velit qui occaecat <sub>deserunt deserunt</sub> eu aute ipsum eu.</p>

Velit aliquip anim laborum velit qui occaecat deserunt deserunt eu aute ipsum eu.

sup

上标标签。

<p>Velit aliquip anim laborum velit qui occaecat <sup>deserunt deserunt</sup> eu aute ipsum eu.</p>

Velit aliquip anim laborum velit qui occaecat deserunt deserunt eu aute ipsum eu.

small

小文字标签。

<p>Velit aliquip anim laborum velit qui occaecat <small>deserunt deserunt</small> eu aute ipsum eu.</p>

Velit aliquip anim laborum velit qui occaecat deserunt deserunt eu aute ipsum eu.

br

断行标签。并不两辆成对

<p>Velit aliquip anim laborum velit qui occaecat <br/>deserunt deserunt eu aute ipsum eu.</p>

Velit aliquip anim laborum velit qui occaecat
deserunt deserunt eu aute ipsum eu.

code

源代码标签。

<p>Velit aliquip anim laborum velit qui occaecat <code>deserunt deserunt</code> eu aute ipsum eu.</p>

Velit aliquip anim laborum velit qui occaecat deserunt deserunt eu aute ipsum eu.

audio

音频标签。

<audio controls="controls">
  <source="t-rex-roar.mp3" type="audio/mpeg">
  Your browser does not support Audio.
</audio>

video

视频标签。

<video controls  width="250"
  src="https://archive.org/download/ElephantsDream/ed_hd.ogv" >
  The <code>video</code> element is unsupported.
</video>

blockquote

引用块标签。

They said:
<blockquote>The blockquote element indicates
an extended quotation.</blockquote>
They said:
The blockquote element indicates an extended quotation.

details

可展开的额外信息标签。

<details>
  <summary>Html Cheatsheet</summary>
  <p>Inline elements</p>
  <p>Block elements</p>
</details>
Html Cheatsheet

Inline elements

Block elements

ul

无序列表标签。

<ul>
  <li>I'm an item</li>
  <li>I'm another item</li>
</ul>
  • I'm an item
  • I'm another item

ol

有序列表标签。

<ol>
  <li>I'm the first item</li>
  <li>I'm the second item</li>
</ol>
  1. I'm the first item
  2. I'm the second item

hr

水平横线标签。

before<hr>after
before
after

h1/h2/h3/h4/h5/h6

1~6级标题标签。

<h1> This is Heading 1 </h1>
<h2> This is Heading 2 </h2>
<h3> This is Heading 3 </h3>
<h4> This is Heading 4 </h4>
<h5> This is Heading 5 </h5>
<h6> This is Heading 6 </h6>
This is Heading 1
This is Heading 2
This is Heading 3
This is Heading 4
This is Heading 5
This is Heading 6

当然,在 HTML 5 规范中还定义了很多其他标签,此处不进行赘述。

3. CSS

CSS 代码用于定义页面元素的样式,例如字体、字号、颜色、阴影等,它甚至还可以进行图形绘制、帧动画定义等操作。

3.1. 基础 / Basic

CSS 代码会通过 HTML 标签及其类(class)、标识(id)等特征定位元素,并据此为元素设定样式。

<div class="sample-container" id="main">
    <div class="shadowed color-filled" id="box-01">01</div>
    <div class="shadowed color-filled" id="box-02">02</div>
    <div class="shadowed color-filled" id="box-03">03</div>
</div>

在这段代码中,最外层的 div 只有一个 classsample-container,内部的 div 均有两个 classshadowedcolor-filled

当有超过一个 class 时,使用空格分隔。

据此,我们可以为上面的 HTML 文件定义一些样式:

* {
    outline: none;
    box-sizing: border-box;
}

div {
    color: #1482E8;
    font-size: 30px;
    padding: 20px;
}

.sample-container {
    background-color: #012F48;
}

.sample-container * {
    margin: 10px;
}

.shadowed {
    box-shadow: -8px 0 0 0 #7E88A2, 8px 0 0 0 #7E88A2;
}

.color-filled {
    background-color: #ffd43b;
}

#box-03:hover {
    background-color: #F0811A;
}

这段代码做了什么事呢?

  • 通过 * { …​ } 为所有元素设定了一些样式;

  • 通过 div { …​ } 为所有 div 标签设定了一些样式;

  • 通过 .sample-container { …​ }classsample-container 的元素设定了一些样式;

  • 通过 .sample-container * { …​ }classsample-container 的元素的所有子元素设定了一些样式;

  • 通过 #box-03:hover { …​ }idbox-03 的元素的 hover 状态设定了一些样式。

CSS 的基本语法为:

选择器 {
    属性: 取值;
    属性: 取值;
}
<标签 style="属性: 取值; 属性: 取值;"></标签>
<标签 style="属性: 取值; 属性: 取值;" />

以上代码的效果如下:

01
02
03

3.1.1. 选择器 / Selectors

上面示例代码中,*/div/.sample-container/.sample-container */#box-03:hover 等均被称为选择器,通过指定的规则选择 HTML 中的对应元素。

Table 2. 主要 CSS 选择器
选择器 示例

.class

.intro

选择所有 class 包含 intro 的元素。

.class1.class2

.name1.name2

选择所有 class 同时包含 namename2 的元素。

.class1 .class2

.name1 .name2

选择所有 class 包含 name1 的元素内部的 class 包含 name2 的元素。

#id

#firstname

选择所有 idfirstname 的元素

*

*

选择所有元素。

element

p

选择所有 <p> 元素。

element.class

p.intro

选择所有 class 包含 intro<p> 元素。

element,element

div, p

选择所有 <div> 元素与所有 <p> 元素。

element element

div p

选择所有处于 <div> 元素内部的 <p> 元素。

element>element

div > p

选择所有父元素为 <div> 元素的 <p> 元素。

element+element

div + p

选择第一个紧跟 <div> 元素的 <p> 元素。

element1~element2

p ~ ul

选择所有在 <p> 元素前的 <ul> 元素。

[attribute]

[target]

选择所有拥有 target 属性的元素。

<a href="#" target="_blank">link</a>

[attribute=value]

[target=_blank]

选择所有 target 属性值为 _blank 的元素。

[attribute~=value]

[title~=flower]

选择所有 title 属性值含有 flower 的元素。

[attribute|=value]

[lang|=en]

选择所有 lang 属性值等于 en 或以 en- 开头的元素。

[attribute^=value]

a[href^="https"]

选择所有 href 属性值以 https 开头的 <a> 元素。

[attribute$=value]

a[href$=".pdf"]

选择所有 href 属性值以 .pdf 结尾的 <a> 元素。

[attribute*=value]

a[href*="flower"]

选择所有 href 属性值包含 flower<a> 元素。

:active

a:active

选择所有 active 状态的 <a> 元素。

::after

p::after

在所有 <p> 所有的内容之后插入一些内容。

::before

p::before

在所有 <p> 所有的内容之前插入一些内容。

:checked

input:checked

选择所有 checked 状态的 <input> 元素。

:default

input:default

选择所有 default 状态的 <input> 元素。

:disabled

input:disabled

选择所有 disabled 状态的 <input> 元素。

:empty

p:empty

选择所有没有子元素(包括文字节点)的 <p> 元素。

:enabled

input:enabled

选择所有 enabled 状态的 <input> 元素。

:first-child

p:first-child

选择所有刚好是其父元素的首个子元素的 <p> 元素。

::first-letter

p::first-letter

选择所有 <p> 元素的首个字母。

::first-line

p::first-line

选择所有 <p> 元素的第一行。

:first-of-type

p:first-of-type

选择所有刚好是其父元素的首个子 <p> 元素的 <p> 元素。

:focus

input:focus

选择所有 focus 状态的 <input> 元素。

:fullscreen

:fullscreen

选择处于 fullscreen 模式的元素。

:hover

a:hover

选择所有处于 hover 状态的 <a> 元素。

:in-range

input:in-range

选择所有 value 值处于特定范围的 <input> 元素。

:indeterminate

input:indeterminate

选择所有 indeterminate 状态的 <input> 元素。

:invalid

input:invalid

选择所有 value 值非法 invalid<input> 元素。

:lang(language)

p:lang(it)

选择所有 lang 属性值等于 it<p> 元素。

:last-child

p:last-child

选择所有刚好是其父元素的最后一个子元素的 <p> 元素。

:last-of-type

p:last-of-type

选择所有刚好是其父元素的最后一个子 <p> 元素的 <p> 元素。

:link

a:link

选择所有未访问过 (unvisited) 的 <a> 元素。

::marker

::marker

选择所有列表项的 markers

:not(selector)

:not(p)

选择所有不是 <p> 元素的元素。

:nth-child(n)

p:nth-child(2)

选择所有刚好是其父元素的第 2 个子元素的 <p> 元素。

:nth-last-child(n)

p:nth-last-child(2)

选择所有刚好是其父元素的倒数第 2 个子元素的 <p> 元素。

:nth-last-of-type(n)

p:nth-last-of-type(2)

选择所有刚好是其父元素的倒数第 2 个子 <p> 元素的 <p> 元素。

:nth-of-type(n)

p:nth-of-type(2)

选择所有刚好是其父元素的第 2 个子 <p> 元素的 <p> 元素。

:only-of-type

p:only-of-type

选择所有刚好是其父元素的唯一子 <p> 元素的 <p> 元素。

:only-child

p:only-child

选择所有刚好是其父元素的唯一子元素的 <p> 元素。

:optional

input:optional

选择所有没有 required 属性的 <input> 元素。

:out-of-range

input:out-of-range

选择 value 值超出特定范围的 <input> 元素。

::placeholder

input::placeholder

选择设定了 placeholder 属性的 <input> 元素。

:read-only

input:read-only

选择设定了 readonly 属性的 <input> 元素。

:read-write

input:read-write

选择未设定了 readonly 属性的 <input> 元素。

:required

input:required

选择设定了 required 属性的 <input> 元素。

:root

:root

选择 HTML 文档的根元素。

::selection

::selection

选择元素中被用户选中的部分。

:target

#news:target

选择当前激活且为 news 的锚点 (anchor)。

:valid

input:valid

选择所有所有 value 值合法的 <input> 元素。

:visited

a:visited

选择所有访问过 (visited) 的 <a> 元素。

3.2. 盒子模型 / Box Model

margin
border
padding
content

如上即为盒子模型。

  • margin 为外边距;

  • border 为边框;

  • padding 为内边距;

  • content 为内容区域。

通常在使用盒子模型之前我们会首先定义以下样式:

* {
    outline: none;
    box-sizing: border-box;
}

3.3. 属性 / Properties

属性 示例

color

color: #1482E8;

Non quis elit irure veniam nulla ex.

font-family

font-family: Arial, sans-serif;

Non quis elit irure veniam nulla ex.

font-size

font-size: 25px;

Non quis elit irure veniam nulla ex.

font-weight

font-weight: bold;

Non quis elit irure veniam nulla ex.

background

background: linear-gradient(to right top, #051937, #004d7a, #008793, #00bf72, #a8eb12);

background: #ffffff url('https://www.baidu.com/img/flexible/logo/pc/result@2.png') no-repeat scroll center;

margin

margin: 20px;

padding

padding: 5px 30px;

border

border: 10px solid #1482E8;

width

width: 5rem;

height

height: 5rem;

display

display: none;


display: block;

display: inline-block;

display: flex;
flex-flow: row nowrap;
display: flex;
flex-flow: column nowrap;

box-shadow

box-shadow: 5px 5px 15px 5px #000000;

border-radius

border-radius: 10px;

text-shadow

text-shadow: 2px 2px 2px #1C6EA4;

Exercitation dolor esse reprehenderit nisi enim minim laborum amet. Consequat ad dolore consectetur occaecat ea consequat est cupidatat sit occaecat consectetur irure duis. Nisi enim sit ad voluptate velit magna ullamco elit minim.

transform

transform: scale(1.2) rotate(95deg) translate(-12px, 12px) skew(18deg, -38deg);

TRANSGORM

transition

transition: all 2s ease-in;

Nisi dolore irure velit aliqua id deserunt in aliqua sint aliqua nulla deserunt.

3.4. 媒体查询 / Media Queries

Media Queries 的基本语法为:

@media not|only mediatype and (media feature) {
    /* CSS Code */
}
<link rel="stylesheet" media=mediatype and|not|only (media feature href="mystylesheet.css">

例如:

@media screen and (max-width: 480px) { ... }
@media screen and (max-width: 600px), (max-height: 500px) { ... }
@media print { ... }
@media (prefers-color-scheme: dark) { ... }

3.4.1. 媒体类型 / Media Type

  • all

  • print

  • screen

  • speech

3.4.2. 媒体特性 / Media Feature

特性

说明

width

viewport 宽度

height

viewport 高度

orientation

viewport 朝向

aspect-ratio

宽高比

color

每种颜色的位数

color-index

可显示的颜色数

monochrome

灰度设备的颜色

resolution

设备分辨率

scan

设备扫描进程

grid

设备是网格 (grid) 或位图 (bitmap)

3.5. 布局 / Layout

3.5.1. 基础 / Basic

Table 3. display
控制元素才布局流中的呈现方式。
display: inline

允许其他元素在其旁边,此时 marginpaddingwidth 无效。

display-inline.svg

display: block

占用一整行,此时 marginpaddingwidth 有效。

display-block.svg

display: inline-block

允许其他元素在其旁边,此时 marginpaddingwidth 有效。可以创建列,但在盒子之间会强制留空。

display-inline-block.svg

Table 4. float
控制文本是否环绕元素。
float: left|right|none

允许其他元素环绕该元素。

float.svg

多个 float

可以创建带有接触边的框的列。

multi-float.svg

clear: left|right|both

强制将元素置于浮动元素下方。

clear.svg

overflow: hidden

在父元素上使用以强制它环绕浮动的子元素。

overflow.svg

Table 5. position
对布局进行严格的、基于坐标的控制。
position: absolute

根据坐标移动元素。

absolute.svg

position: relative

添加到父元素以重置 absolute 子元素的坐标。

relative.svg

position: fixed

当页面滚动时,强制元素不移动。

fixed.svg

z-index

控制元素的堆叠顺序——数字越大越接近。

z-index.svg

Table 6. 元素居中
方式 说明 示例
text-align: center

仅适用于 display: inlineinline-block 元素。

必须应用于父元素。

<figure class="img-box">
    <img src="images/argentinosaurus.jpg" alt="">
    <figcaption>The mighty Argentinosaurus</figcaption>
</figure>
.img-box {
    text-align: center;
}
margin: 0 auto

仅适用于 display: block 元素。

元素必须有 width

如果你想要顶部或底部的边距,也可以仅指定 margin-left: automargin-right: auto

<div class="box">Stegosaurus</div>
.box {
    width: 24em; /* Without a width `auto` won’t work */
    margin-left: auto;
    margin-right: auto;
}
vertical-align: middle

仅适用于 display: inlineinline-block 元素。

<ul>
    <li>Pteranodon</li>
    <li>Quetzalcoatlus</li>
</ul>
ul li {
    display: inline-block;
    vertical-align: middle;
}

absolute 元素居中

采用 transform50% 坐标以使绝对定位的元素居中。

<div class="banner">
    <div class="content">
        <h1>Micropachycephalosaurus</h1>
        <p>Longest dinosaur name ever!</p>
    </div>
</div>
.banner {
    position: relative;
}

.content {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
}

或垂直居中:

.content {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
}

float 元素居中

没有 float: center, 不能居中浮动元素。

使用 flexbox 居中

flexbox 有很多不同的对齐,它们总是应用于父类 。

<div class="card">
    <h2>Edmontosaurus</h2>
    <a href="#">See the bones!</a>
</div>
.card {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-content: center;
    align-items: center;
}
Table 7. 通用模式
模式 说明 示例
box-sizing: border-box;

用于更改宽度和填充的布局数学计算,放在每个 CSS 文件的顶部。

html {
    box-sizing: border-box;
}

*,
*::before,
*::after {
    box-sizing: inherit;
}

用于 float 元素的 clearfix

添加到浮动元素的父元素以强制父元素包围浮动元素。

可以用来代替 overflow: hidden

.clearfix::after {
    content: " ";
    display: block;
    clear: both;
}

灵活的图像

采用 widthdisplay 使图像收缩到其父级的大小。

img {
    display: block;
    width: 100%;
}

3.5.2. Flex-box

Table 8. 容器元素

display

为所有子元素启用 flex

display: flex
display: inline-flex

flex-direction

确立主轴。

flex-direction: row
flex-direction: row-reverse
flex-direction: column
flex-direction: column-reverse

flex-wrap

如果子元素不能在一行内展示,则自动换行。

flex-wrap: nowrap
flex-wrap: wrap
flex-wrap: wrap-reverse

justify-content

尝试在主轴上分配额外空间。

justify-content: flex-start
justify-content: flex-end
justify-content: center
justify-content: space-between
justify-content: space-around
justify-content: space-evenly

align-items

确定项目在交叉轴上的布局方式。

align-items: flex-start
align-items: flex-end
align-items: center
align-items: baseline
align-items: stretch

align-content

仅对多行内容产生影响。

此处显示的示例使用 flex-wrap

align-content: flex-start
align-content: flex-end
align-content: center
align-content: space-between
align-content: space-around
align-content: stretch
Table 9. 子元素

order

允许你明确设置你希望每个子元素出现的顺序。

order: 整数

flex-grow

允许你确定如何允许每个子元素作为整体的一部分增长。

/* 适用于所有 */
flex-grow: 1
/* 第一个 */
flex-grow: 1

/* 第二个 */
flex-grow: 3

/* 第三个 */
flex-grow: 6

flex-basis

在分配剩余空间之前定义元素的大小。

/* 第一个 */
flex-basis: 20%

/* 第二个 */
flex-basis: 40%

flex-shrink

如有必要,允许项目缩小。

只有在设置大小或 flex-basis 时才真正有用。

/* 第一个和第二个 */
flex-basis: 100%

/* 第二个 */
flex-shrink: 2

align-self

设置单个项目的对齐方式。

有关选项参考 align-items

/* 第三个 */
align-self: flex-end

3.5.3. Grid

Table 10. 子元素

display

为子级建立新的网格格式化上下文。

display: grid
display: inline-grid

grid-template

定义网格的行和列。

grid-template-columns: 12px 12px 12px;
grid-template-rows: 12px 12px 12px;
grid-template-columns: repeat(3, 12px);
grid-template-rows: repeat(3, auto);
grid-template-columns: 8px auto 8px;
grid-template-rows: 8px auto 12px;
grid-template-columns: 22% 22% auto;
grid-template-rows: 22% auto 22%;

grid-gap

指定列和行间距的大小。

grid-row-gap: 1px;
grid-column-gap: 9px;
grid-gap: 1px 9px;
grid-gap: 6px;

justify-items

沿行轴对齐网格项中的内容。

justify-items: start;
justify-items: end;
justify-items: center;
/* 默认 */
justify-items: stretch;

align-items

沿列轴对齐网格项目中的内容。

align-items: start;
align-items: end;
align-items: center;
/* 默认 */
align-items: stretch;

justify-content

当总网格大小小于容器时,对齐行轴上的所有网格内容。

justify-content: start;
justify-content: end;
justify-content: center;
justify-content: stretch;
justify-content: space-around;
justify-content: space-between;
justify-content: space-evenly;

align-content

当总网格大小小于容器时,对齐列轴上的所有网格内容。

align-content: start;
align-content: end;
align-content: center;
align-content: stretch;
align-content: space-around;
align-content: space-between;
align-content: space-evenly;

grid-auto-flow

自动放置未明确放置的网格项目的算法。

grid-auto-flow: row;
grid-auto-flow: column;
grid-auto-flow: dense;

3.6. 动画 / Animations

3.6.1. 基础 / Basic

创造一个炫酷的动画效果一共有如下几个步骤:

步骤 示例 效果

创建 HTML 元素

<div class="animation-wrapper">
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
</div>

赋予元素基础样式

.animation-wrapper {
    height: 100px;
    background: #012F48;
    padding: 0 20px;
    border-radius: 6px;
    min-width: 160px
}

.animation-wrapper .circle {
    display: inline-block;
    margin: 20px 6px 0 0;
    width: 20px;
    height: 20px;
    border-radius: 100%;
    background-color: #1482E8;
}

创建一个关键帧动画

@keyframes move-the-circle {
    0% {
        transform: translate(0, 0);
    }
    50% {
        transform: translate(0, 25px);
    }
    100% {
        transform: translate(0, 0);
    }
}

为元素指定动画

.animation-wrapper .circle {
    animation: move-the-circle 1s ease infinite;
}

为元素设置动画延迟(可选)

.animation-wrapper .circle:nth-child(1) { animation-delay: 0.1s; }
.animation-wrapper .circle:nth-child(2) { animation-delay: 0.2s; }
.animation-wrapper .circle:nth-child(3) { animation-delay: 0.3s; }
.animation-wrapper .circle:nth-child(4) { animation-delay: 0.4s; }
.animation-wrapper .circle:nth-child(5) { animation-delay: 0.5s; }
.animation-wrapper .circle:nth-child(6) { animation-delay: 0.6s; }

将更多属性加入动画中(可选)

@keyframes move-the-circle {
    0% {
        transform: translate(0, 0) scale(1);
        opacity: 1;
        background-color: turquoise;
    }
    50% {
        transform: translate(0, 50px) scale(.4);
        opacity: .5;
        background-color: blue;
    }
    100% {
        transform: translate(0, 0) scale(1);
        opacity: 1;
        background-color: turquoise;
    }
}

3.6.2. 缓入效果 / Ease-in

普通缓入效果:

.class {
    animation-timing-function: ease-in;
}

贝赛尔曲线缓入效果:

.class {
    animation-timing-function: cubic-bezier(.44,.24,.83,.67);
}

弹性缓入效果:

.class {
    animation-timing-function: cubic-bezier(.4,1.21,.83,1.16);
}

3.6.3. 动画与滚动 / Animation and Scrolling

首先当然还是创建 HTML 元素:

<div class="square">
</div>

然后赋予这个元素一些基本的样式:

.square {
    width: 100px;
    height: 100px;
    background: #ffd43b;
    border-radius: 6px;
    margin: 10px auto;
}

创建一个动画:

@keyframes wipe-enter {
	0% {
		transform: scale(0, .025);
	}
	50% {
		transform: scale(1, .025);
	}
}

将动画指定给元素:

.square {
    animation-name: wipe-enter;
    animation-duration: 1s;
    animation-iteration-count: infinite;

    /* 或者 */
    /* animation: wipe-enter 1s infinite; */
}

此时我们已经有了一个不错的动画效果,但是:

  • 这个动画会无限次的执行下去;

  • 如果我们将 infinite 更换为某个数字,动画也将执行指定的次数。

那么,如果我们希望:

  • 动画的执行可以手动激活和关闭;

  • 动画仅在每次元素展示到用户面前时才执行一次

应当怎么做呢?

手动激活和关闭 / Active/Deactive Manually

对于第一个需求,我们应当将指定给 square 类元素的动画指定给另一个 square-animation 类,然后在需要时为 square 元素增加或删除 square-animation 类名:

<!-- 未激活动画时 -->
<div id="square" class="square"></div>

<!-- 激活动画时 -->
<div id="square" class="square square-animation"></div>
.square {
    width: 100px;
    height: 100px;
    background: #ffd43b;
    border-radius: 6px;
    margin: 10px auto;
    /* animation: wipe-enter 1s infinite; */
}

.square-animation {
    animation: wipe-enter 1s infinite;
}

通过 JavaScript 进行控制:

square = document.getElementById("square");
if (square.classList.contains('square-animation')) {
    square.classList.remove('square-animation');
} else {
    square.classList.remove('square-animation');
}
滚动时触发 / Active on Scroll

对于第二个问题,答案是通过使用 Intersection Observer API 测量用户滚动时元素的偏移量:

<div class="square-wrapper">
    <div class="square"></div>
</div>
.square {
    width: 100px;
    height: 100px;
    background: #ffd43b;
    border-radius: 6px;
    margin: 10px auto;
    /* animation: wipe-enter 1s infinite; */
}

.square-animation {
    /* animation: wipe-enter 1s infinite; */
    animation: wipe-enter 1s 1;
}
const observer = new IntersectionObserver(entries => {
    entries.forEach(entry => {
        const square = entry.target.querySelector('.square');

        if (entry.isIntersecting) {
            square.classList.add('square-animation');
            return; // if we added the class, exit the function
        }

        // We're not intersecting, so remove the class!
        square.classList.remove('square-animation');
    });
});

observer.observe(document.querySelector('.square-wrapper'));

现在,这个动画效果仅会在每次元素展示时执行一次:

另一个示例 / Another Example
<div class="star-box">
    <span>Star Animation</span>
    <a href="https://caveops.com/" target="_blank">Check it out</a>
    <img class="star star-1" src="imgs/star.svg" />
    <img class="star star-2" src="imgs/star.svg" />
    <img class="star star-3" src="imgs/star.svg" />
    <img class="star star-4" src="imgs/star.svg" />
    <img class="star star-5" src="imgs/star.svg" />
</div>
@keyframes stars {
    0% {
        transform: translateY(40px)
    }

    50% {
        opacity: 1;
        transform: translateY(10px) scale(1.4)
    }

    to {
        opacity: 1
    }
}
.star-box {
    position: relative;
    display: flex;
    flex-flow: column nowrap;
    align-items: center;
    justify-content: center;
    width: 70%;
    height: 200px;
    margin: 10px auto;
    border: 1px solid #d3e0da;
    border-radius: 6px;
    word-break: break-all;
    background: #F8FAF9;
    font-family: Nunito,sans-serif;
}

.star-box span {
    display: block;
    font-size: 30px;
    padding: 30px;
}

.star-box a {
    color: #fff !important;
    text-shadow: 0 1px 2px rgba(0,0,0,.4);
    border-radius: 6px;
    font-size: 20px;
    padding: 14px 18px;
    display: inline-block;
    background: linear-gradient(175deg,#d69721,#f08827 37%,#edad69);
    background: linear-gradient(175deg,#2198d6,#6996ed);
    font-weight: 700;
    text-decoration: none !important;
    transition: all .2s ease;
}

.star-box a:hover {
    opacity: 0.9;
}

.star-box .star {
    opacity: 1
    z-index: 999;
}

.star-box .star-animation {
    -webkit-animation: stars 1s 1 forwards;
    animation: stars 1s 1 forwards;
}

.star-box .star {
    position: absolute;
    width: 60px;
    top: 0;
    opacity: 0
}

.star-box .star-1 {
    top: 25%;
    left: -28px;
    transform: rotate(-14deg)
}

.star-box .star-2 {
    top: -6px;
    left: 4.5%;
    width: 30px;
    transform: rotate(15deg);
    -webkit-animation-delay: .1s;
    animation-delay: .1s
}

.star-box .star-3 {
    top: auto;
    bottom: 58px;
    right: -15px;
    transform: rotate(15deg);
    -webkit-animation-delay: .2s;
    animation-delay: .2s
}

.star-box .star-4 {
    width: 40px;
    bottom: -14px;
    top: auto;
    right: 5px;
    transform: rotate(5deg);
    -webkit-animation-delay: .3s;
    animation-delay: .3s
}

.star-box .star-5 {
    width: 30px;
    bottom: 26px;
    top: auto;
    right: 10px;
    transform: rotate(-27deg);
    -webkit-animation-delay: .4s;
    animation-delay: .4s
}
const observer_star = new IntersectionObserver(function(entries) {
    entries.forEach(entry => {
        const stars = entry.target.querySelectorAll('.star');
        stars.forEach(star => {
            if (entry.isIntersecting) {
                star.classList.add('star-animation');
                return;
            }
            star.classList.remove('star-animation');
        });
    });
});

observer_star.observe(document.querySelector('.star-box'));

最终效果:

Star Animation Check it out [img class="star star-1"]star.svg[/img] [img class="star star-2"]star.svg[/img] [img class="star star-3"]star.svg[/img] [img class="star star-4"]star.svg[/img] [img class="star star-5"]star.svg[/img]

4. 脚本 / Scripts

在一些情境下,例如处理一些用户交互、实时改变页面内容等,仅凭 HTML 与 CSS 无法满足我们的需求,这时我们需要借助脚本语言的力量。而在这个领域中,最流行的脚本语言是 JavaScript。

4.1. 数据 / Data

场景的数据分为以下几种类型:

  • 数字(number)

  • 字符串(string)

  • 对象/字典/键值对(object)

  • 布尔/逻辑(boolean)

  • 数组(array)

  • 空(null)

  • 未定义(undefined)

values
false, true                     // boolean
18, 3.14, 0b10011, 0xF6, NaN    // number
"flower", 'John'                // string
undefined, null , Infinity      // special

4.1.1. 变量与常量 / Variables and Constants

通过 let/var 关键字可以定义变量,而 const 关键字可以定义常量。顾名思义,变量的值可以修改,而常量不可以。

var age = 18;                           // number
var name = "Jane";                      // string
var name = {first:"Jane", last:"Doe"};  // object
var truth = false;                      // boolean
var sheets = ["HTML","CSS","JS"];       // array
var a; typeof a;                        // undefined
var a = null;                           // value null

4.1.2. 数据类型与操作 / Data Types and Operatings

var a;                          // variable
var b = "init";                 // string
var c = "Hi" + " " + "Joe";     // = "Hi Joe"
var d = 1 + 2 + "3";            // = "33"
var e = [2,3,5,8];              // array
var f = false;                  // boolean
var g = /()/;                   // RegEx
var h = function(){};           // function object
const PI = 3.14;                // constant
var a = 1, b = 2, c = a + b;    // one line
let z = 'zzz';                  // block scope local variable
object
var student = {                 // object name
    firstName:"Jane",           // list of properties and values
    lastName:"Doe",
    age:18,
    height:170,
    fullName : function() {     // object function
        return this.firstName + " " + this.lastName;
    }
};

student.age = 19;           // setting value
student[age]++;             // incrementing
name = student.fullName();  // call object function
string
var abc = "abcdefghijklmnopqrstuvwxyz";
var esc = 'I don\'t \n know';   // \n new line
var len = abc.length;           // string length
abc.indexOf("lmno");            // find substring, -1 if doesn't contain
abc.lastIndexOf("lmno");        // last occurance
abc.slice(3, 6);                // cuts out "def", negative values count from behind
abc.replace("abc","123");       // find and replace, takes regular expressions
abc.toUpperCase();              // convert to upper case
abc.toLowerCase();              // convert to lower case
abc.concat(" ", str2);          // abc + " " + str2
abc.charAt(2);                  // character at index: "c"
abc[2];                         // unsafe, abc[2] = "C" doesn't work
abc.charCodeAt(2);              // character code at index: "c" -> 99
abc.split(",");                 // splitting a string on commas gives an array
abc.split("");                  // splitting on characters
128.toString(16);               // number to hex(16), octal (8) or binary (2)
number
var pi = 3.141;
pi.toFixed(0);          // returns 3
pi.toFixed(2);          // returns 3.14 - for working with money
pi.toPrecision(2)       // returns 3.1
pi.valueOf();           // returns number
Number(true);           // converts to number
Number(new Date())      // number of milliseconds since 1970
parseInt("3 months");   // returns the first number: 3
parseFloat("3.5 days"); // returns 3.5
Number.MAX_VALUE        // largest possible JS number
Number.MIN_VALUE        // smallest possible JS number
Number.NEGATIVE_INFINITY// -Infinity
Number.POSITIVE_INFINITY// Infinity
math
var pi = Math.PI;       // 3.141592653589793
Math.round(4.4);        // = 4 - rounded
Math.round(4.5);        // = 5
Math.pow(2,8);          // = 256 - 2 to the power of 8
Math.sqrt(49);          // = 7 - square root
Math.abs(-3.14);        // = 3.14 - absolute, positive value
Math.ceil(3.14);        // = 4 - rounded up
Math.floor(3.99);       // = 3 - rounded down
Math.sin(0);            // = 0 - sine
Math.cos(Math.PI);      // OTHERS: tan,atan,asin,acos,
Math.min(0, 3, -2, 2);  // = -2 - the lowest value
Math.max(0, 3, -2, 2);  // = 3 - the highest value
Math.log(1);            // = 0 natural logarithm
Math.exp(1);            // = 2.7182pow(E,x)
Math.random();          // random number between 0 and 1
Math.floor(Math.random() * 5) + 1;  // random integer, from 1 to 5
array
var dogs = ["Bulldog", "Beagle", "Labrador"];
var dogs = new Array("Bulldog", "Beagle", "Labrador");  // declaration

alert(dogs[1]);             // access value at index, first item being [0]
dogs[0] = "Bull Terier";    // change the first item

for (var i = 0; i < dogs.length; i++) {     // parsing with array.length
console.log(dogs[i]);
}

dogs.toString();                        // convert to string: results "Bulldog,Beagle,Labrador"
dogs.join(" * ");                       // join: "Bulldog * Beagle * Labrador"
dogs.pop();                             // remove last element
dogs.push("Chihuahua");                 // add new element to the end
dogs[dogs.length] = "Chihuahua";        // the same as push
dogs.shift();                           // remove first element
dogs.unshift("Chihuahua");              // add new element to the beginning
delete dogs[0];                         // change element to undefined (not recommended)
dogs.splice(2, 0, "Pug", "Boxer");      // add elements (where, how many to remove, element list)
var animals = dogs.concat(cats,birds);  // join two arrays (dogs followed by cats and birds)
dogs.slice(1,4);                        // elements from [1] to [4-1]
dogs.sort();                            // sort string alphabetically
dogs.reverse();                         // sort string in descending order
x.sort(function(a, b){return a - b});   // numeric sort
x.sort(function(a, b){return b - a});   // numeric descending sort
highest = x[0];                         // first item in sorted array is the lowest (or highest) value
x.sort(function(a, b){return 0.5 - Math.random()});     // random order sort

4.2. 操作符 / Operators

a = b + c - d;      // addition, substraction
a = b * (c / d);    // multiplication, division
x = 100 % 48;       // modulo. 100 / 48 remainder = 4
a++; b--;           // postfix increment and decrement

4.2.1. 运算符 / Arithmetic Operators

a * (b + c)         // grouping
person.age          // member
person[age]         // member
!(a == b)           // logical not
a != b              // not equal
typeof a            // type (number, object, function...)
x << 2  x >> 3      // minary shifting
a = b               // assignment
a == b              // equals
a != b              // unequal
a === b             // strict equal
a !== b             // strict unequal
a < b   a > b       // less and greater than
a <= b  a >= b      // less or equal, greater or eq
a += b              // a = a + b (works with - * %...)
a && b              // logical and
a || b              // logical or

4.2.2. 位运算符 / Bitwise Operators

符号 含义 示例

&

AND/与

5 & 1 (0101 & 0001)	1 (1)

|

OR/或

5 | 1 (0101 | 0001)	5 (101)

~

NOT/非

~ 5 (~0101)	10 (1010)

^

XOR/异或

5 ^ 1 (0101 ^ 0001)	4 (100)

<<

left shift/左移

5 << 1 (0101 << 1)	10 (1010)

>>

right shift/右移

5 >> 1 (0101 >> 1)	2 (10)

>>>

zero fill right shift/右移填充零

5 >>> 1 (0101 >>> 1)	2 (10)

4.3. 函数 / Functions

function addNumbers(a, b) {
    return a + b;
}
x = addNumbers(1, 2);

4.4. 流程控制 / Flow Control

4.4.1. if else

    if ((age >= 14) && (age < 19)) {        // logical condition
    status = "Eligible.";               // executed if condition is true
} else {                                // else block is optional
    status = "Not eligible.";           // executed if condition is false
}

4.4.2. switch case

switch (new Date().getDay()) {      // input is current day
case 6:                         // if (day == 6)
	text = "Saturday";
	break;
case 0:                         // if (day == 0)
	text = "Sunday";
	break;
default:                        // else...
	text = "Whatever";
}

4.4.3. for

for (var i = 0; i < 10; i++) {
    document.write(i + ": " + i*3 + "<br />");
}
var sum = 0;
for (var i = 0; i < a.length; i++) {
    sum + = a[i];
}               // parsing an array
html = "";
for (var i of custOrder) {
    html += "<li>" + i + "</li>";
}

4.4.4. while

var i = 1;                      // initialize
while (i < 100) {               // enters the cycle if statement is true
    i *= 2;                     // increment to avoid infinite loop
    document.write(i + ", ");   // output
}

4.4.5. do while

var i = 1;                      // initialize
do {                            // enters cycle at least once
    i *= 2;                     // increment to avoid infinite loop
    document.write(i + ", ");   // output
} while (i < 100)               // repeats cycle if statement is true at the end

4.4.6. break/continue

for (var i = 0; i < 10; i++) {
    if (i == 5) { break; }          // stops and exits the cycle
    document.write(i + ", ");       // last output number is 4
}
for (var i = 0; i < 10; i++) {
    if (i == 5) { continue; }       // skips the rest of the cycle
    document.write(i + ", ");       // skips 5
}

4.5. DOM

<div class="sample-container">
    <span id="elementID">Hi, there!</span>
</div>
document.getElementById("elementID").innerHTML = "Hello World!";

上面的代码找到 idelementID 的元素,并退换其内容为 Hello World!

Hi, there!

4.6. 输出 / Output

console.log(a);             // write to the browser console
document.write(a);          // write to the HTML
alert(a);                   // output in an alert box
confirm("Really?");         // yes/no dialog, returns true/false depending on user click
prompt("Your age?","0");    // input dialog. Second argument is the initial value

4.7. 注释 / Comments

每一行代码中,所有在 // 之后的内容将作为注释存在,他们不可执行,会被解释器忽略。

而使用 // 包裹的内容将被作为注释,这种注视并不局限于单独一行。

/* Multi line
comment */

var abc = "abc"; // One line
star.svg
Pinned Message
HOTODOGO
The Founder and CEO of Infeca Technology.
Developer, Designer, Blogger.
Big fan of Apple, Love of colour.
Feel free to contact me.
反曲点科技创始人和首席执行官。
开发、设计与写作皆为所长。
热爱苹果、钟情色彩。
随时恭候 垂询