整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

HTML基础

TML的作用

HTML是用来开发网页的,它是开发网页的语言

HTML的定义

全称HyperText Mark-up Language,超文本标记语言

标记就是标签

<标签名称></标签名称> 比如 <html></html> <h1></h1>等,标签大多数都是成对出现的。

超文本 两层含义:

  1. 因为网页中还可以有图片、视频、音频等内容(超越文本限制)
  2. 它还可以在网页中跳转到另一个网页,与世界各地主机的网页链接(超链接文本)

HTML的基本结构

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>网页标题</title>
    </head>
    <body>
        网页显示内容
    </body>
</html>

第一行<!DOCTYPE html>是文档声明

用来指定页面所使用的html的版本, 这里声明的是一个html5的文档

<html>...</html>标签是开发人员在告诉浏览器

整个网页是从<html>这里开始的,到</html>结束

也就是html文档的开始和结束标签

<head>...</head>标签用于定义文档的头部

是负责对网页进行设置标题、编码格式以及引入css和js文件的

<body>...</body>标签是编写网页上显示的内容

网页文件的后缀是.html, 一个html文件就是一个网页,html文件用编辑器打开显示的是文本,可以用文本的方式编辑它,如果用浏览器打开,浏览器会按照标签描述内容将文件渲染成网页

VS Code 安装

VS Code全拼是 Visual Studio Code 是由微软研发的一款免费、开源的跨平台代码编辑器

目前是前端(网页)开发使用最多的一款软件开发工具

下载网址: https://code.visualstudio.com/Download

选择对应的安装包进行下载:

安装一切默认

VS Code 的插件安装

  • Chinese(Simplified) Language Pack for VS Code 中文汉化包
  • open in browser 右击在浏览器打开html

常用的HTML标签

1 标签不区分大小写,但是推荐使用小写

2 根据标签的书写形式,标签分为双标签(闭合标签)和单标签(空标签) 2.1 双标签是指由开始标签和结束标签组成的一对标签,这种标签允许嵌套和承载内容,比如: div标签 2.2 单标签是一个标签组成,没有标签内容, 比如: img标签

标签的使用形式

  1. 成对出现的标签
  2. 标签的嵌套
  3. 单个出现的标签
  4. 带属性的标签


列表标签

  1. 无序列表标签(ul标签)
  2. 有序列表标签(ol标签)

网页效果

表格标签

<table>标签:表示一个表格

<tr>标签:表示表格中的一行

<td>标签:表示表格中的列

<th>标签:表示表格中的表头

属性设置

border: 1px solid black:设置边框和颜色

border-collapse: collapse:设置边框合并



网页效果

表单标签

表单用于搜集不同类型的用户输入的数据,然后可以把用户数据提交到web服务器

<form>标签 表示表单标签,定义整体的表单区域

一个表单中有很多信息组成,比如 姓名,爱好,地址等,这些内容有很多其他标签来承载

这些标签称为表单元素标签

网页效果

表单提交

表单用于搜集不同类型的用户输入的数据,然后可以把用户数据提交到web服务器

  • action属性 设置表单数据提交地址
  • method属性 设置表单提交的方式,一般有“GET”方式和“POST”方式, 不区分大小写

两种方式的区别:

  • “GET”方式 : 没有请求体
  • “POST”方式 : 有请求体

表单元素属性设置

  • name: 表单元素的名称,用于作为提交表单数据时的参数名
  • value: 表单元素的值,用于作为提交表单数据时参数名所对应的值

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<meta http-equiv="X-UA-Compatible" content="ie=edge">

<title>Document</title>

</head>

<body>

<!--

姓名 type="text" 定义单行文本输入框

密码 type="password" 定义密码输入框

性别 type="radio" 定义单选框

爱好 type="checkbox" 定义复选框

照片 type="file" 定义上传文件

个人描述 <textarea></textarea> 定义多行文本输入框

地址 <select></select> 定义下拉列表

提交 type="submit" 定义提交按钮

重置 type="reset" 定义重置按钮

按钮 type="button" 定义一个普通按钮

-->

<form action="http://192.168.1.106:8080" method="POST">

<label>姓名:</label>

<input type="text" name="username" >

<br>

<label>密码:</label>

<input type="password" name="password">

<br>

<label>性别:</label>

<input type="radio" name="sex" value="1">男

<input type="radio" name="sex" value="0">女

<br>

<label>爱好:</label>

<input type="checkbox" name="like" value="睡觉">睡觉

<input type="checkbox" name="like" value="吃饭">吃饭

<input type="checkbox" name="like" value="打豆豆">打豆豆

<br>

<label>照片:</label>

<input type="file" name="pic">

<br>

<label>个人描述:</label>

<textarea name="desc"></textarea>

<br>

<label>地址:</label>

<select name="addr">

<option value="1">北京</option>

<option value="2">上海</option>

<option value="3">广州</option>

<option value="4">深圳</option>

</select>

<br>

<input type="submit" value="提交">

<input type="reset" value="重置">

<input type="button" value="按钮">

</form>

</body>

</html>


点击提交:

可以看到服务器收到了请求报文。

源:https://www.sitepoint.com/

现代应用相比普通的网页有不同的要求。但是浏览器是一个有着一套(大部分)固定可用的技术的平台,JavaScript依然是web应用的核心语言;任何需要在浏览器上跑的应用都需要使用这种语言。

我们都知道Javascript并不是最好的语言,特别是在复杂的应用中,它可能不太能胜任。为了避免这种情况,一些新的语言或现有语言的编译器被创造出来,你不用写一行Javascript或者考虑这种语言的局限,就能生产在浏览器能运行的代码。

这篇文章包括了十种有趣的语言能够编译为Javascript,在浏览器或者Node.js中被执行。

--ADVERTISEMENT--

Dart

Dart是一个典型的面向对象的语言,任何东西都是一个对象并且任何对象都是一个类的实例(对象也可以表现为函数)。它的特殊性用于打造面向浏览器,服务器和移动设备的应用。它由谷歌来维护,是用于驱动下一代的AdWords UI。AdWords UI是谷歌盈利的重要产品,这也证明了它在体量上的强大。

这种语言可以编译为JavaScript用于浏览器,或者直接通过Dart VM解释,这样也可以允许你构建服务端应用。移动应用可以通过Flutter SDK创建。

复杂的应用还需要一系列特别为任务所设计的成熟的库和语言特性,Dart这些都有。举例来说一个流行的库是AngularDart,一个Dart版本的Angular。

它允许你写非侵入式的类型安全的代码,但是这不是必须的,因为他们可以自动检测类型。它可以允许你快速构建原型而不用过于思考细节,一旦你需要的时候,你可以加入类型让它更健壮。

至于在VM中的并发编程,相比与共享内存线程(Dart是单线程的),Dart使用所谓的_Isolates_,有它自己的堆内存,而交流是通过传递信息。在浏览器上,情况就有点不一样了:相比与创建一个新的_isolates_,你创建一个新的_Workers_。

// Example extracted from dartlang.org

import 'dart:async';

import 'dart:math' show Random;

main() async {

print('Compute π using the Monte Carlo method.');

await for (var estimate in computePi()) {

print('π ≅ $estimate');

}

}

/// Generates a stream of increasingly accurate estimates of π.

Stream<double> computePi({int batch: 1000000}) async* {

var total = 0;

var count = 0;

while (true) {

var points = generateRandom().take(batch);

var inside = points.where((p) => p.isInsideUnitCircle);

total += batch;

count += inside.length;

var ratio = count / total;

// Area of a circle is A = π⋅r², therefore π = A/r².

// So, when given random points with x ∈ <0,1>,

// y ∈ <0,1>, the ratio of those inside a unit circle

// should approach π / 4\. Therefore, the value of π

// should be:

yield ratio * 4;

}

}

Iterable<Point> generateRandom([int seed]) sync* {

final random = new Random(seed);

while (true) {

yield new Point(random.nextDouble(), random.nextDouble());

}

}

class Point {

final double x, y;

const Point(this.x, this.y);

bool get isInsideUnitCircle => x * x + y * y <= 1;

}

Get started with Dart https://www.dartlang.org/guides/get-started

TypeScript

TypeScript 是Javascript的超集;一个有效的Javascript项目也是一个有效的TypeScript项目只是添加了静态类型。编译器也可以作为ES2015+到当前实现的转译器,这样你总是能得到最新的特性。

不同于其他语言,TypeScript保持了Javascript完整的精神,只是此外添加了增加代码可靠性的功能。这些功能就是类型注释和其他类型相关的功能,得益于专业工具像是静态分析器和其他工具在重构过程的加入,这些功能使写Javascript更加有趣。并且,类型的加入改善了你的应用不同组件之间的接口。

类型诊断是支持性的,你不必从一开始就写所有的类型。你可以先快速的写代码,然后再加入类型来让代码更稳定。

TypeScript同样也支持高级类型,像是交叉类型,联合类型,类型别名,可辨识联合和类型保护。你可以在TypeScript Documentation网站的Advanced Types页面查看。

如果你使用React的话,通过添加React类型,JSX也是支持的。

class Person {

private name: string;

private age: number;

private salary: number;

constructor(name: string, age: number, salary: number) {

this.name = name;

this.age = age;

this.salary = salary;

}

toString(): string {

return `${this.name} (${this.age}) (${this.salary})`;

}

}

——

Elm

Elm是一个可以编译成JS,HTML和JS的纯函数式编程语言。你可以只通过Elm创建一个完整的网站,这使得它是一个对像React这样的Javascript框架的一个很好的代替。通过它创建的应用自动使用了虚拟DOM库,使得它很快。一个大的加分项是内建的结构让你忘记数据流而是关注于数据声明和逻辑。

在Elm中,所有函数都是纯粹的,这意味着他们总是对一个给予的输入返回一个相同的输出。T他们不能做其他任何事情,除非你指定。举例来说,获取一个远程的API你会创建一个_command_函数来通讯外部世界,和一个 subscriptions 函数监听回复。另一个纯粹的点是,值是不可变的,当你需要什么的时候,你创建一个新值而不是改变它。

ELm的接受可以是平缓的;可以使用_ports_来和Javascript或其他库沟通。虽然Elm还没有到达版本1,它已经用于复杂大型的应用了,这使得它对复杂应用是一个可行的解决方案。

ELm其中一个吸引人的功能是初学者友好的编译器,它生成帮助你修复你的代码的信息,而不是产生难以阅读的信息。如果你正在学习这门语言,编译器本身就是一个大的帮助。

module Main exposing (..)
import Html exposing (..)
-- MAIN
main : Program Never Model Msg
main =
 Html.program
 { init = init
 , update = update
 , view = view
 , subscriptions = subscriptions
 }
-- INIT
type alias Model = String
init : ( Model, Cmd Msg )
init = ( "Hello World!", Cmd.none )
-- UPDATE
type Msg
 = DoNothing
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
 case msg of
 DoNothing ->
 ( model, Cmd.none )
-- VIEW
view : Model -> Html Msg
view model =
 div [] [text model]
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
 Sub.none

Get Started with Elm:https://www.sitepoint.com/functional-reactive-programming-elm-introduction/

PureScript

PureScript 是一个纯函数强类型的编程语言,由Phil Freeman创造。它旨在与现有的JavaScript库进行很好的兼容,与Haskell精神上类似,但是核心保留了Javascript。

PureScript一个重要的点是它的极简主义。它没有包含任何在其他语言认为很重要的功能库。比如,相比于在编译器中包含generators和promises,你可以自己使用指定的库来完成这个任务。你可以选择你想要的功能的实现,当使用PureScript的时候需要高效和个性化的经验,能使生成的代码尽可能的小。

这个编译器另一个重要的功能是构建出清晰可读的代码,能够兼容Javascript包括库和工具。

和其他语言一样,PureScript有它自己的构建工具称为Pulp,可以和Gulp做对比,只是用这个语言写的。

至于类型系统,不同于另一个ML类的语言Elm,PureScript支持更先进的类型特性比如高级类类型和类型类,这些是从Haskell来的特性,允许创建复杂的抽象。

module Main where
import Prelude
import Data.Foldable (fold)
import TryPureScript
main =
 render $ fold
 [ h1 (text "Try PureScript!")
 , p (text "Try out the examples below, or create your own!")
 , h2 (text "Examples")
 , list (map fromExample examples)
 ]
 where
 fromExample { title, gist } =
 link ("?gist=" <> gist) (text title)
 examples =
 [ { title: "Algebraic Data Types"
 , gist: "37c3c97f47a43f20c548"
 }
 , { title: "Loops"
 , gist: "cfdabdcd085d4ac3dc46"
 }
 , { title: "Operators"
 , gist: "3044550f29a7c5d3d0d0"
 }
 ]

Get Started with PureScripthttps://github.com/purescript/documentation/blob/master/guides/Getting-Started.md

CoffeeScript

CoffeeScript是一个旨在暴露JavaScript的精华并提供一个干净的语法并在合适地方保留语义的语言。虽然近年来这个语言的热度在下降,它正在改变方向并且现在有一个新的大版本支持ES2015+特性。

你用CoffeeScript写的代码直接转化为可读的Javascript代码并且兼容现有的库。从2版本开始,编译器会产生兼容最新版本的ECMAScript的代码,比如,每次你使用class,你就在Javascript中得到class。并且,如果你使用React,好消息是,JSX兼容CoffeeScript。

这个编译器有一个十分有特色的功能是有能力处理用literate style写的代码。literate style相比于强调代码而把注释作为添加这种方式,而是你需要在一开始就写注释,代码只是偶尔出现。这种写代码的方式由Donald Knuth推荐,使得一个代码文件非常像一个技术文档。

相比于其他语言,CoffeeScript代码可以在浏览器中用一个库直接执行。所以如果你想要写一个快速测试,你可以写你的代码在一个text/coffeescriptscript标签中,并且引入编译器,这样就可以把你的代码轻易的转化为JavaScript了。

# Assignment:
number = 42
opposite = true
# Conditions:
number = -42 if opposite
# Functions:
square = (x) -> x * x
# Arrays:
list = [1, 2, 3, 4, 5]
# Objects:
math =
 root: Math.sqrt
 square: square
 cube: (x) -> x * square x
# Splats:
race = (winner, runners...) ->
 print winner, runners
# Existence:
alert "I knew it!" if elvis?
# Array comprehensions:
cubes = (math.cube num for num in list)

Get Started with CoffeeScript http://coffeescript.org/v2/#coffeescript-2

ClojureScript

ClojureScript是一个转化Clojure编程语言为JavaScript的编译器。Clojure是一个多用途的函数式原因伴随着动态类型和不可变数据结构的支持。

这是这个列表中唯一一个属于Lisp家族的语言,自然有着它们共同的特性。举例来说,代码可以作为数据,支持宏系统,使得元编程成为可能。Unlike other Lisps, Clojure has support for immutable data structures, making the management of side-effects easier.不同于其他类Lisp,Clojure支持不可变数据结构,使得函数副作用的管理更容易。

这个语法对初学者看起吓人,因为圆括号的使用。但这样使用是经过深思熟虑的,并且在长远看来你一定会感谢这种语法的。语法的极简和抽象能力使得Lisp成为一个解决高抽象问题的强力工具。

虽然Clojure主要是一个函数式语言,但是不像PureScript或者Elm那样纯粹。函数副作用还是会发生,但是其他函数式特性也会存在。

ClojureScript使用Google Closure做代码优化并且也兼容现有的JavaScript库。

; Extracted from https://github.com/clojure/clojurescript/blob/master/samples/dom/src/dom/test.cljs
(ns dom.test
 (:require [clojure.browser.event :as event]
 [clojure.browser.dom :as dom]))
(defn log [& args]
 (.log js/console (apply pr-str args)))
(defn log-obj [obj]
 (.log js/console obj))
(defn log-listener-count []
 (log "listener count: " (event/total-listener-count)))
(def source (dom/get-element "source"))
(def destination (dom/get-element "destination"))
(dom/append source
 (dom/element "Testing me ")
 (dom/element "out!"))
(def success-count (atom 0))
(log-listener-count)
(event/listen source
 :click
 (fn [e]
 (let [i (swap! success-count inc)
 e (dom/element :li
 {:id "testing"
 :class "test me out please"}
 "It worked!")]
 (log-obj e)
 (log i)
 (dom/append destination
 e))))
(log-obj (dom/element "Text node"))
(log-obj (dom/element :li))
(log-obj (dom/element :li {:class "foo"}))
(log-obj (dom/element :li {:class "bar"} "text node"))
(log-obj (dom/element [:ul [:li :li :li]]))
(log-obj (dom/element :ul [:li :li :li]))
(log-obj (dom/element :li {} [:ul {} [:li :li :li]]))
(log-obj (dom/element [:li {:class "baz"} [:li {:class "quux"}]]))
(log-obj source)
(log-listener-count)

Get Started with ClojureScript https://clojurescript.org/guides/quick-start

Scala.js

Scala.js是一个将Scala编程语言转化为JavaScript的编译器。Scala是一个旨在融合面向对象和函数式编程两种思想到一种语言,为了打造容易接受的强力的工具

作为一个强类型语言,你会从它部分类型推断这种灵活的类型系统中受益。大部分的值会被推断,但函数参数仍然需要明确的类型注释。

虽然许多通常的面向对象模式都支持(比如任何值都是一个对象并且操作是一个方法调用),但你也有函数式特性比如一等函数和不可变数据结构。

Scala.js其中一个特殊的优势是,你可以毫不费力的从你熟悉的面向对象开始向更函数式的转移,以你自己的需要和步调。同样的,现存的JavaScript代码和库和你的Scala代码兼容。

Scala的初学者会发现这个语言和JavaScript并没有多大不同,对比下面两个意思一样的代码:

// JavaScript

var xhr = new XMLHttpRequest();

xhr.open("GET",

"https://api.twitter.com/1.1/search/" +

"tweets.json?q=%23scalajs"

);

xhr.onload = (e) => {

if (xhr.status === 200) {

var r = JSON.parse(xhr.responseText);

$("#tweets").html(parseTweets(r));

}

};

xhr.send();

// Scala.js

val xhr = new XMLHttpRequest()

xhr.open("GET",

"https://api.twitter.com/1.1/search/" +

"tweets.json?q=%23scalajs"

)

xhr.onload = { (e: Event) =>

if (xhr.status == 200) {

val r = JSON.parse(xhr.responseText)

$("#tweets").html(parseTweets(r))

}

}

xhr.send()

Get Started with Scala.jshttps://www.scala-js.org/tutorial/basic/

Reason

Reason是一个由Facebook创造和维护的语言,它为OCaml编译器提供了新的语法,并且代码可以转换成JavaScript和原生代码。

作为ML家族的一部分并且自己本身是函数式语言,它天生提供了强大但是灵活的伴随类型推断的类型系统,代数数据类型和模式匹配。它也支持不可变数据类型和参数多态(也被其他语言称为泛型),但是在OCaml中,也是支持面向对象编程的。

通过 bucklescript绑定就可以使用现存的JavaScript库。你也可以在你的Reason代码旁边混入你的JavaScript。插入的JavaScript代码不会严格的检查,但作为快速修复和原因也是不错的。

如果你是一个React开发者,绑定是可能的,并且这个语言也支持JSX。

/* A type variant being pattern matched */
let possiblyNullValue1 = None;
let possiblyNullValue2 = Some "Hello@";
switch possiblyNullValue2 {
| None => print_endline "Nothing to see here."
| Some message => print_endline message
};
/* Parametrized types */
type universityStudent = {gpa: float};
type response 'studentType = {status: int, student: 'studentType};
let result: response universityStudent = fetchDataFromServer ();
/* A simple typed object */
type payload = Js.t {.
 name: string,
 age: int
};
let obj1: payload = {"name": "John", "age": 30};

Get Started with Reason https://reasonml.github.io/guide/javascript/quickstart

Haxe

Haxe是一个多范式编程语言,并且它的编译器可以产生二进制或者其他语言的源代码。

虽然Haxe提供了严格的类型系统并带有类型推断,它也可以作为动态语言只要目标语言支持。同样的,它也支持多种的编程风格比如面向对象,泛型,函数式。

当你写Haxe代码的时候,你可以为编译指定多个平台或语言,但不需要对代码做什么大的改变。指定目标的代码块也支持。

你可以用Haxe同时写前端和后端用同样的代码,并且通过Haxe Remoting进行沟通,既可以同步连接也可以异步连接。

不出所料,Haxe代码可以兼容现有的库但也提供了成熟的标准库。

// Example extracted from http://code.haxe.org

extern class Database {

function new();

function getProperty<T>(property:Property<T>):T;

function setProperty<T>(property:Property<T>, value:T):Void;

}

abstract Property<T>(String) {

public inline function new(name) {

this = name;

}

}

class Main {

static inline var PLAYER_NAME = new Property<String>("playerName");

static inline var PLAYER_LEVEL = new Property<Int>("playerLevel");

static function main() {

var db = new Database();

var playerName = db.getProperty(PLAYER_NAME);

trace(playerName.toUpperCase());

db.setProperty(PLAYER_LEVEL, 1);

}

}

Get Started with Reasonhttps://haxe.org/documentation/introduction/language-introduction.html

Nim

Nim是一个静态类型,多范式编程语言,有着极简风格与空格敏感的语法,编译为C,C++和JavaScript。

这个语言本身很小,但它的元编程能力会吸引你自己去实现一些在别的语言内置的功能。这些构建模块有宏,模板和泛型,通过它们你可以实现不论是简单的功能还是不同的泛型。这使得Nim成为一个非常通用的语言可以适应你的需求,有着Lisp的精髓。

Nim的语法抽象功能允许你去让语言去适应你的功能,让真正的[DSLs][20]成为可能。如果你有着专门的任务需要处理,你可以获得更高级的表达性。

# Reverse a string
proc reverse(s: string): string =
 result = ""
 for i in countdown(high(s), 0):
 result.add s[i]
var str1 = "Reverse This!"
echo "Reversed: ", reverse(str1)
# Using templates
template genType(name, fieldname: expr, fieldtype: typedesc) =
 type
 name = object
 fieldname: fieldtype
genType(Test, foo, int)
var x = Test(foo: 4566)
echo(x.foo) # 4566

Get Started with Nimhttps://nim-lang.org/documentation.html

结尾

如果JavaScript不是你最喜欢的语言,你依然可以创建web应用而不用忍受这个技术的缺点。可供选择的范围很广,从纯粹的函数式语言,比如PureScript,到面向对象语言,比如Dart。并且如果你想要不只是语言的转化,你也可以选择比如Elm,Elm提供像是虚拟DOM和内置的架构这样的工具。

你是否有尝试了这篇文章的任何一种语言,又或者你有自己的推荐?请在评论中让我知道

今天我们一起来了解下HTML,

首先HTmL包含三层结构,分别是结构层,表现层,行为层。

结构层:html => 网页上有什么,比如说文字啊、按钮啊、图片啊等等。

表现层:css => 显示成什么样子,比如说文字的大小啊,位置啊,颜色啊等等。

行为层:JavaScript => 具体怎么操作,比如说点击按钮让图片放大缩小等等。

===============================

在了解了html的三层结构之后,我们来学习如何写html。html不是编程语言,它是一套标签。最简单的html文本是下图1这个样子。我们可以在电脑桌面上新建一个记事本文件,然后把后缀名改一下(.txt=>.html),把这段标签代码粘贴到html文件里,这样一个空白的网页就做成了。如果需要在网页上添加内容,我们只需要在第10行的位置添加各种各样的标签即可。比如我在图二添加了一个按钮标签和一段文字标签,双击html文件,页面上就从左到右,从上到下显示对应的内容。是不是很简单。我们日常浏览的网页都是这样一个标签一个标签画上去的。

我给大家总结了一张图,基本上覆盖了工作中常用的知识点。同时分享几个小技巧。

1.最简单的网页写成什么样子,也就是html模板不需要记忆,下图也说了,去百度下载一个VSCode软件(类似于记事本,是现在主流的前端代码编辑器),用它打开我们的html文件,输入英文叹号回车就自动生成了,学编程不要死记硬背。

2.控件的标签不需要记忆,直接百度html XXX标签,例如:百度搜“html按钮标签”,他就会告诉我们是<button>,用的时间长了自然就记住了。是不是省力。

3.标签的属性很重要,可以不去记他的写法,因为写可以百度,重要的是你需要记住标签有什么属性,下图的属性记住足矣。为什么要记呢,因为工作中,有的时候会遇到这样一种情况,明明设置一个属性可以完成的功能,我们不知道,花费了大力气用css和js去实现,结果还存在着特定场合的bug,让人很无奈。

4.对于html还有两个标签<canvas>和<svg>,他们是用来绘图的,做特殊效果的。我们可以先跳过,等框架啥的都学完了,有兴趣,学习一下。

5.给大家推荐一个小白学习html的网站,w3cschool,图里不明白的可以去上边学学练练。

6.如果觉得一个人学习前端有难度,我建了一个小白前端学习交流群,可以私聊我,大家在群里多多交流,我会经常给大家答疑,组织大家练习,一起做小项目。有方向,少走弯路。