整合营销服务商

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

免费咨询热线:

为什么我推荐使用JSX开发Vue3

很长的一段时间中,Vue 官方都以简单上手作为其推广的重点。这确实给 Vue 带来了非常大的用户量,尤其是最追求需求开发效率, 往往不那么在意工程代码质量的国内中小企业中,Vue 占据的份额极速增长。但是作为开发者自身,我们必须要认清一个重点,简单易用从来不应该在技术选型中占据很大的份额,可维护性才是。

以防万一有的同学实在不看官方文档,我先提一嘴,SFC 就是写 Vue 组件的时候写的.vue文件,这一个文件就是一个 SFC,全称 Single File Component,也即单文件组件。

在开始说我个人的观点之前,我们先来看几个事实:

一是:Vue3 的定义原生支持 JSX,并且 Vue3 源码中有jsx.d.ts来便于使用 JSX。 不知道同学们看到这里会想到什么, 我的第一反应是:社区对于 JSX 的需求声音是不小的,所以会反向推动 Vue3 官方对于 JSX 的支持。

二是:AntDesign 的 vue3 版本,基本全部都是用 JSX 开发的,而且 Vue3 现在官方的 babel-jsx 插件就是阿里的人一开始维护的, 虽然我向来不喜欢阿里系的 KPI 推动技术方式,而且现在的 JSX 语法支持也不是很符合我的期望,但至少在使用 JSX 开发是更优秀的选择这点上,我还是很认可 AntDesign 团队的。

OK,说这些呢,主要是先摆出一些事实作为依据,让有些同学可以不需要拿什么:

  • 啊,这都是你空想的,你太自以为是了
  • 你再怎么想都没用,咱们 Vue 就是应该用 SFC 开发

这些观点来批斗我,首先我都会从客观的角度来分析为什么,至少是我是能讲出优劣势的理由的。

OK,前言差不多到这里,接下来咱给您分析分析,为什么你应该选择 JSX 来开发 Vue。


TypeScript 支持

其实第一点就已经是杀手了,对于想要使用 TypeScript 来开发 Vue3 应用的同学来说,这简直就是 SFC 无法克服的世界难题。

一句话概括:TypeScript 原生支持 JSX 语法,而基本无望 TS 官方能支持 SFC 的 template 语法

TS 毫无疑问在前端社区的重要性越来越大,但凡未来对于代码质量有一定要求的前端团队,都应该会选择使用 TS 来进行开发。 而且现在基本上在 NPM 上都能看到包你都能找到对应的 TS 定义,现在使用 TS 开发成本已经只剩下你是不是会 TS 语法了,在这种情况下是否支持 TS 则是开发模式在未来走不走的远的重要原因。

目前 SFC 只能通过shim让 TS 可以引入.vue文件,但是对于所有 SFC 的组件的定义都是一样的:

declare module '*.vue' {
    import { DefineComponent } from 'vue'
    const component: DefineComponent<{}, {}, {}, any>
    export default component
}

也就是说你引入的 SFC 组件,TS 是不知道这个组件的 Props 应该接收什么的。所以你无法享受到这些 TS 的优势:

  • 开发时的自动提示
  • 编译时的 TS 校验,让你尽早发现问题
  • 编译组件生成你的组件定义(对于类库开发尤其重要)

当然你会说既然 Vue 官方能开发处 SFC 的语法,自然会支持这些特性。我表示这当然有可能,但是这个难度是非常大的,需要很多方面的支持,甚至可能需要 TS 官方团队愿意协助, 但是我想不到 TS 官方有什么理由来支持 SFC,因为这只是 Vue 自己创建的方言,在其他场景下是没有使用的,TS 是面向全社区的,我觉得他们不会考虑主动来支持 SFC。

那么有同学要问了,JSX 不也是非原生的 JS 语法么,他怎么就能让 TS 官方支持了呢,是不是 FB 和微硬之间有什么 PY 交易?

这就涉及第二点了,JSX 和静态模板的灵活性区别。

JSX 其实并不是方言

很多人弄错了一个问题,就是觉得 SFC 的模板语法和 JSX 是一样的,都是一种别人发明的语法,并不是 JS 原生的。这是事实,但又有一些区别,这个区别主要是体现在对于 JSX 的认知上。

一句话概括:JSX 并没有扩展 JS 的语法,他只是缩略了 JS 的写法!其本质就是 JS 的语法糖

就像 es6 给增加的语法糖,比如

const a = 1
const b = 2

const obj = { a, b }

// 其实就等价于
const obj = { a: a, b: b }

这种写法并没有扩展 JS 的能力,只是简便了写法,JSX 也是一样的。

JSX 其实就是方法调用,他和 JS 是有一对一对应关系的,我们来看一个例子:

const element = <div id="root">Hello World</div>

这里的 JSX 语法编译之后其实就是:

const element = createElement('div', { id: 'root' }, 'Hello World')

而 JSX 就是这些了,没有什么更多的内容,所以说 JSX 只是方便我们写嵌套的函数调用的语法糖,而其本身没有扩展任何其他的内容。

但是 SFC 就不一样了。

SFC 定义的不仅是语法,更是文件。

SFC 的具体定义是单文件组件,它本身就是把一个文件看作一个单位,所以他的约束性是要大很多的,你必须具有固定的文件结构才能使用 SFC,这做了很多的限制:

  • 一个文件只能写一个组件
  • 节点片段只能写在 template 里面,非常不灵活
  • 变量绑定只能获取this上面的内容,不能使用全局变量(很多时候我们都要把全局变量先挂载到this上)

我们一点点来讲

一个文件只能写一个组件

这个说实话非常非常不方便,很多时候我们写一个页面的时候其实经常会需要把一些小的节点片段拆分到小组件里面进行复用(如果你现在没有这个习惯可能就是因为 SFC 的限制让你习惯了全部写在一个文件内)。

React 生态中丰富的 css-in-js 方案就是很好的例子,我们可以通过:

const StyledButton = styled('button', {
    color: 'red',
})

如果我们这个页面需要使用特定样式的按钮,通过这种方式在页面文件里面封装一下是非常常见的。因为没必要把这个组件拆分出去,他也不是一个可复用的组件,拆分出去了还要多一次import。

Vue 生态基本没有 css-in-js 的成熟方案其实跟这个限制也很有关系。

再来一个例子,比如我们封装了一个 Input 组件,我们希望同时导出 Password 组件和 Textarea 组件来方便用户根据实际需求使用,而这两个组件本身内部就是用的 Input 组件,只是定制了一些 props:

const Input = { ... }

export default Input

export const Textarea = (props) => <Input multiline={true} {...props} />

export const Password = (props) => <Input type="password" {...props} />

在 JSX 中可以非常简单地实现,但是如果通过 SFC,你可能就要强行拆成三个文件,另外为了方便,你可能还要增加一个index.js来导出这三个组件,你能想象这多了多少工作量么。

节点片段只能写在 template 里面,非常不灵活

我不知道有多少同学看过 Vue 的 template 编译出来之后的代码,以我的经验来说看过的可能不会超过 50%(乐观估计),建议同学们如果还不了解的,可以去尝试看一下。

为什么要看这个呢?因为你看了之后你会发现,你在 template 里面写的类似 HTMl 的内容,其实跟 HTML 根本没啥关系,他们也会被编译成类似 JSX 编译出来的结果。

{
    render(h) {
        return h('div', {on: {}, props: {}}, h('span'))
    }
}

类似这样的结果,而这里面h函数调用的结果就是一个 VNode,是 Vue 中的节点的基础单元。那么既然这些单元就是一个对象,其实理所当然的,他们是可以作为参数传递的。 也就是说,理论上他们是可以通过props把节点当作参数传递给其他组件的。

这个做法在 React 中非常常见,叫做renderProps,并且其非常灵活:

const Comp = () => <Layout header={<MyHeader />} footer={<MyFooter />} />

但是因为 SFC 模板的限制,我们很难在 SFC 里面的 props 上写节点:

<template>
    <Layout :header="<MyHeader/>"></Layout>
</template>

这样写是不行的,因为 SFC 定义了:header绑定接受的只能是 js 表达式,而<MyHeader/>显然不是。

因为通过 props 传递不行,所以 Vue 才发明了 slot 插槽的概念

虽然我们一直再说 Vue 简单,但是事实上ScopedSlots一度成为新手理解 Vue 的噩梦,很多同学都被这个绕来绕去的作用域整的死去活来。

我们看一个ScopedSlots的例子:

<template>
    <Comp>
        <template v-slot:scope="ctx">
            <div>{{ctx.name}}</div>
        </template>
    </Comp>
</template>

这里ctx是Comp里面的属性,通过这种方式传递出来,让我们在当前组件可以调用父组件里面的属性。这简直就是理解的噩梦,但是如果用 JSX 实现类似功能就非常简单:

<Comp scope={name => <div>{name}</div>} />

我们只是给一个叫做scope的 props 传递来一个函数,这个函数接受一个name属性,在Comp里面会调用这个函数并传入name。 简单来说我们传入的就是一个构建节点片段的函数,就是这么简单。

这就是因为 SFC 的模板的限制,导致灵活性不足,Vue 需要去创造概念,创造关键字来抹平这些能力的不足,而创造的概念自然就引入了学习成本。

所以其实我一直不认可 Vue 比 React 好学的说法的,如果你真的认真研究所有用法,并且总是尝试用最合理的方式实现功能,那么 Vue 绝对不会比 React 简单。

变量绑定只能获取this上面的内容,不能使用全局变量

这个体现在两个方面,一个是我们定义在全局的一些固定数据如果要在组件内使用的话,就要通过this挂载到组件上。

比如我们缓存了一份城市数据,这种数据基本上是不会改的,所以也没必要挂载到组件上让其能够响应式。但是在 SFC 里面这是做不到的, 因为模板的执行上下文是在编译时绑定。你在模板里面访问的变量,都会在编译时自动绑定到this上,因为模板需要编译,其本身也是字符串不具有作用域的概念。

而这在 JSX 中则不复存在:

const citys = []

const Comp = () => {
    return citys.map(c => <div>{c}</div>)
}

另外一个方面则是在组件使用上,在 SFC 中,组件必须事先注册,因为我们在模板里面写的只能是字符串而不能是具体某个组件变量。 那么模板中的组件和真实的组件对象只能通过字符串匹配来实现绑定。这带来了以下问题:

  • 多了注册组件这个步骤,增加代码量
  • 通过字符串名注册自然就会出现可能的冲突问题
  • 模板解析组件支持不同的样式,比如<MyComp>和<my-comp>,容易导致风格不一的问题

在 JSX 中则没有这些问题,因为 JSX 里面直接使用组件引用作为参数:

const Comp = {...}

const App = () => <Comp />

需要通过directive来扩展能力

其实上面能看出来,除了 SFC 本身的问题之外,Vue 使用字符串模板也会带来很多的灵活性问题。 最直接的证据,就是 Vue 使用了directive来扩展功能(当然这不是 Vue 发明的,老早的模板引擎就有类似问题)。

为什么说directive是不得已的选择呢?因为静态模板缺失逻辑处理的能力。我们拿列表循环举例,在 JS 中我们可以非常方便地通过map函数来创建列表:

const list = arr.map(name => <span key={name}>{name}</span>)

而因为 JSX 本身就是函数调用,所以上面的代码和 JSX 结合起来也非常自然:

const App = () => (
    <div>
        <Header />
        {arr.map(name => (
            <span key={name}>{name}</span>
        ))}
    </div>
)

上面的例子对应到 JS 如下:

const App = () =>
    createElement('div', {}, [
        <Header />,
        arr.map(name => createElement('span', { key: name }, name)),
    ])

这仍然是因为 JSX 只是 JS 的语法糖的原因,所有能在 JS 中实现的在 JSX 里面都能实现。

而 SFC 的模板是基于字符串编译的,其本身就是一段字符串,我们不能直接在模板里面写map来循环节点,(当然我们可以在可以接收表达式的地方写,比如v-on里面)。

那么我们不能循环节点,有需要这样的功能来渲染列表,怎么办呢?就是发明一个标志来告诉编译器这里需要循环,在 Vue 中的体现就是v-for指令。

同学们可能要问了,既然 Vue 能实现v-for,为什么不直接实现表达式循环列表呢?他当然也可以实现,但是他肯定不会这么选,因为成本太高了。 他要这么做就相当于他要实现一个 JS 引擎,而其实里面很多内容又是不必须的,一个v-for其实就能够适用大部分情况了。

但有了v-for就需要v-if,那么后面还会需要其他各种能力,这就是一种方言的产生和发展的过程。

当然指令也不仅仅是 JS 表达式的代替品,其本身也是增加了一些其他能力的,比如它能够让我们更方便地访问 DOM 节点, 但是嘛,我们用框架的理由不就是为了能够尽可能的屏蔽 DOM 操作嘛~

总结

以上就是我对应该选择使用 JSX 还是 SFC 进行开发的分析,其实归根到底 SFC 的问题在于其没有拥抱 JS, 他的语法是自己发明的,他需要有一个 JS 实现的 compiler 来让其最终能在 JS 环境中运行,这本质上就是一种发明, 我们不能否认发明确实有优点,但我们也不能只看有点不看问题,没能拥抱 JS 自然就很难完全复用 JS 社区的优势 而 JS 社区一直在蓬勃发展,好用的工具一直在涌现,而 SFC 想要使用 JS 社区的这些工具还要自己再实现一份,我们可以细数以下 SFC 做了哪些兼容

  • vue-loader 之于 webpack
  • eslint-plugin-vue 之于 eslint
  • rollup-plugin-vue 之于 rollup
  • vue-jest 之于 jest
  • Vetur 用来做代码提醒

基本上常用的工具我们都需要等待 Vue 社区或者官方开发了插件之后才能运行。而 JSX 因为有 babel 和 typescript 的官方支持, 基本上所有新的 JS 生态工具原生都是支持的。

在这 Vue3 开始预备发力的阶段,我们还是希望 Vue 社区能够使用更优秀更规范的方式来进行开发, 其实如果我们直接使用 JSX 开发 Vue3,我们会发现很多时候我们都不需要用到emit、attrs这些概念, 甚至如果 Vue3 的 JSX 插件支持,我们甚至能够抛弃slots。

但是因为 Vue3 一定要考虑兼容 Vue2,导致本身潜力很好的 Vue3 总是显得缩手缩脚,这不得不说是一种遗憾。

人熟悉前端(html,css,js,vue等),后端(python),小程序,老板有需求联系我。

1.CSS初识

  • 概念: CSS(Cascading Style Sheets) ,通常称为CSS样式表或层叠样式表(级联样式表)
  • 作用:主要用于设置 HTML页面中的文本内容(字体、大小、对齐方式等)、图片的外形(宽高、边框样式、边距等)以及版面的布局和外观显示样式。CSS以HTML为基础,提供了丰富的功能,如字体、颜色、背景的控制及整体排版等,而且还可以针对不同的浏览器设置不同的样式。

2. 引入CSS样式表(书写位置)

2.1 行内式(内联样式)

  • 概念: 称行内样式、行间样式. 是通过标签的style属性来设置元素的样式
  • 其基本语法格式如下:
<标签名 style="属性1:属性值1; 属性2:属性值2; 属性3:属性值3;"> 内容 </标签名>

实际上任何HTML标签都拥有style属性,用来设置行内式。

  • 案例:
<div style="color: red; font-size: 12px;">青春不常在,抓紧谈恋爱</div>
  • 注意:style其实就是标签的属性样式属性和值中间是:多组属性值之间用;隔开。只能控制当前的标签和以及嵌套在其中的字标签,造成代码冗余
  • 缺点:没有实现样式和结构相分离

2.2 内部样式表(内嵌样式表)

  • 概念: 称内嵌式 是将CSS代码集中写在HTML文档的head头部标签中,并且用style标签定义
  • 其基本语法格式如下:
<head>
<style type="text/CSS">
    选择器(选择的标签) { 
      属性1: 属性值1;
      属性2: 属性值2; 
      属性3: 属性值3;
    }
</style>
</head>
<style>
     div {
        color: red;
        font-size: 12px;
     }
</style>
  • 注意:style标签一般位于head标签中,当然理论上他可以放在HTML文档的任何地方。type="text/css" 在html5中可以省略。只能控制当前的页面
  • 缺点:没有彻底分离

综合案例

<style>
   /*选择器{属性:值;}*/
   p {
      color:#06C; 
      font-size:14px;  
    }  /*文字的颜色是 蓝色*/
   h4 {
     color:#900;
   }
   h1 {
     color:#090; 
     font-size:16px; 
    }
   body { 
     background:url(bg2.jpg);
   }
</style>

2.3 外部样式表(外链式)

  • 概念: 称链入式 是将所有的样式放在一个或多个以.CSS为扩展名的外部样式表文件中, 通过link标签将外部样式表文件链接到HTML文档中
  • 其基本语法格式如下:
<head>
  <link rel="stylesheet" type="text/css" href="css文件路径">
</head>
  • 注意: link 是个单标签link标签需要放在head头部标签中,并且指定link标签的三个属性

属性

作用

rel

定义当前文档与被链接文档之间的关系,在这里需要指定为“stylesheet”,表示被链接的文档是一个样式表文件。

type

定义所链接文档的类型,在这里需要指定为“text/CSS”,表示链接的外部文件为CSS样式表。我们都可以省略

href

定义所链接外部样式表文件的URL,可以是相对路径,也可以是绝对路径。

2.4 三种样式表总结(位置)

样式表

优点

缺点

使用情况

控制范围

行内样式表

书写方便,权重高

没有实现样式和结构相分离

较少

控制一个标签(少)

内部样式表

部分结构和样式相分离

没有彻底分离

较多

控制一个页面(中)

外部样式表

完全实现结构和样式相分离

需要引入

最多,强烈推荐

控制整个站点(多)

CSS选择器(重点)

2. CSS基础选择器

2.1 标签选择器

  • 概念:标签选择器(元素选择器)是指用HTML标签名称作为选择器,按标签名称分类,为页面中某一类标签指定统一的CSS样式。
  • 语法:
标签名{属性1:属性值1; 属性2:属性值2; 属性3:属性值3; } 
  • 作用:标签选择器 可以把某一类标签全部选择出来 比如所有的div标签 和 所有的 span标签
  • 优点:是能快速为页面中同类型的标签统一样式
  • 缺点:不能设计差异化样式。

2.2 类选择器

类选择器使用“.”(英文点号)进行标识,后面紧跟类名.

  • 语法:类名选择器.类名 {
    属性1:属性值1;
    属性2:属性值2;
    属性3:属性值3;
    }
    标签<p class='类名'></p>
  • 优点:可以为元素对象定义单独或相同的样式。 可以选择一个或者多个标签
  • 注意类选择器使用“.”(英文点号)进行标识,后面紧跟类名(自定义,我们自己命名的)长名称或词组可以使用中横线来为选择器命名。不要纯数字、中文等命名, 尽量使用英文字母来表示。

命名规范: 见附件(Web前端开发规范手册.doc)

命名是我们通俗约定的,但是没有规定必须用这些常用的命名。

课堂案例:

<head>
        <meta charset="utf-8">
        <style>
    
        .blue {
            color: blue;
            font-size: 100px;
        }
        .red {
            color: red;
            font-size: 100px;
        }
        .orange {
            color: orange;
            font-size: 100px;
        }
        .green {
            color: green;
            font-size: 100px;
        }
        </style>
    </head>
    <body>
        <span class="blue">G</span>
        <span class="red">o</span>
        <span class="orange">o</span>
        <span class="blue">g</span>
        <span class="green">l</span>
        <span class="red">e</span>
    </body>

2.3 类选择器特殊用法- 多类名

我们可以给标签指定多个类名,从而达到更多的选择目的。

注意:

  • 各个类名中间用空格隔开。
  • 多类名选择器在后期布局比较复杂的情况下,还是较多使用的。
<div class="pink fontWeight font20">亚瑟</div>
<div class="font20">刘备</div>
<div class="font14 pink">安其拉</div>
<div class="font14">貂蝉</div>

2.4 id选择器

id选择器使用#进行标识,后面紧跟id名

  • 其基本语法格式如下:id选择器#id名 {属性1:属性值1; 属性2:属性值2; 属性3:属性值3; }标签<p id="id名"></p>
  • 元素的id值是唯一的,只能对应于文档中某一个具体的元素。
  • 用法基本和类选择器相同。

id选择器和类选择器区别

  • W3C标准规定,在同一个页面内,不允许有相同名字的id对象出现,但是允许相同名字的class。

id选择器和类选择器最大的不同在于 使用次数上。

总结他们**

  • 类选择器我们在修改样式中,用的最多。
  • id选择器一般用于页面唯一性的元素身上,经常和我们后面学习的javascript 搭配使用。

2.6 通配符选择器

  • 概念通配符选择器用*号表示, * 就是 选择所有的标签 他是所有选择器中作用范围最广的,能匹配页面中所有的元素。
  • 其基本语法格式如下:
* { 属性1:属性值1; 属性2:属性值2; 属性3:属性值3; }

例如下面的代码,使用通配符选择器定义CSS样式,清除所有HTML标记的默认边距。

* {
  margin: 0;                    /* 定义外边距*/
  padding: 0;                   /* 定义内边距*/
}
  • 注意:会匹配页面所有的元素,降低页面响应速度,不建议随便使用

2.7 基础选择器总结

选择器

作用

缺点

使用情况

用法

标签选择器

可以选出所有相同的标签,比如p

不能差异化选择

较多

p { color:red;}

类选择器

可以选出1个或者多个标签

可以根据需求选择

非常多

.nav { color: red; }

id选择器

一次只能选择器1个标签

只能使用一次

不推荐使用

#nav {color: red;}

通配符选择器

选择所有的标签

选择的太多,有部分不需要

不推荐使用

* {color: red;}

2.8 团队约定

选择器

  • 尽量少用通用选择器 *
  • 尽量少用 ID 选择器
  • 不使用无具体语义定义的标签选择器 div span

CSS字体样式属性调试工具

1.font字体

1.1 font-size:大小

  • 作用:font-size属性用于设置字号
p {  
    font-size:20px; 
}
  • 单位:可以使用相对长度单位,也可以使用绝对长度单位。相对长度单位比较常用,推荐使用像素单位px,绝对长度单位使用较少。

注意:

  • 我们文字大小以后,基本就用px了,其他单位很少使用
  • 谷歌浏览器默认的文字大小为16px
  • 但是不同浏览器可能默认显示的字号大小不一致,我们尽量给一个明确值大小,不要默认大小。一般给body指定整个页面文字的大小

1.2 font-family:字体

  • 作用:font-family属性用于设置哪一种字体。
p{ font-family:"微软雅黑";}
  • 网页中常用的字体有宋体、微软雅黑、黑体等,例如将网页中所有段落文本的字体设置为微软雅黑
  • 可以同时指定多个字体,中间以逗号隔开,表示如果浏览器不支持第一个字体,则会尝试下一个,直到找到合适的字体, 如果都没有,则以我们电脑默认的字体为准。
p{font-family: Arial,"Microsoft Yahei", "微软雅黑";}

常用技巧:

1. 各种字体之间必须使用英文状态下的逗号隔开。
2. 中文字体需要加英文状态下的引号,英文字体一般不需要加引号。当需要设置英文字体时,英文字体名必须位于中文字体名之前。
3. 如果字体名中包含空格、#、$等符号,则该字体必须加英文状态下的单引号或双引号,例如font-family: "Times New Roman";。
4. 尽量使用系统默认字体,保证在任何用户的浏览器中都能正确显示。

CSS Unicode字体

  • 为什么使用 Unicode字体在 CSS 中设置字体名称,直接写中文是可以的。但是在文件编码(GB2312、UTF-8 等)不匹配时会产生乱码的错误。xp 系统不支持 类似微软雅黑的中文。
  • 解决:方案一: 你可以使用英文来替代。 比如font-family:"Microsoft Yahei"。方案二: 在 CSS 直接使用 Unicode 编码来写字体名称可以避免这些错误。使用 Unicode 写中文字体名称,浏览器是可以正确的解析的。font-family: "FAEF6FC5ED1"; 表示设置字体为“微软雅黑”。

字体名称

英文名称

Unicode 编码

宋体

SimSun

B8BF53

新宋体

NSimSun

B0B8BF53

黑体

SimHei

ED1F53

微软雅黑

Microsoft YaHei

FAEF6FC5ED1

楷体_GB2312

KaiTi_GB2312

77F53_GB2312

隶书

LiSu

B6E66

幼园

YouYuan

E7C06

华文细黑

STXihei

4E87EC6ED1

细明体

MingLiU

EC60EF53

新细明体

PMingLiU

B0EC60EF53

1.3 font-weight:字体粗细

  • 在html中如何将字体加粗我们可以用标签来实现使用 b 和 strong 标签是文本加粗。
  • 可以使用CSS 来实现,但是CSS 是没有语义的。

属性值

描述

normal

默认值(不加粗的)

bold

定义粗体(加粗的)

100~900

400 等同于 normal,而 700 等同于 bold 我们重点记住这句话

提倡:

我们平时更喜欢用数字来表示加粗和不加粗。

1.4 font-style:字体风格

  • 在html中如何将字体倾斜我们可以用标签来实现字体倾斜除了用 i 和 em 标签,
  • 可以使用CSS 来实现,但是CSS 是没有语义的

font-style属性用于定义字体风格,如设置斜体、倾斜或正常字体,其可用属性值如下:

属性

作用

normal

默认值,浏览器会显示标准的字体样式 font-style: normal;

italic

浏览器会显示斜体的字体样式。

小技巧:

平时我们很少给文字加斜体,反而喜欢给斜体标签(em,i)改为普通模式。

1.5 font:综合设置字体样式 (重点)

font属性用于对字体样式进行综合设置

  • 基本语法格式如下:
选择器 { font: font-style  font-weight  font-size/line-height  font-family;}
  • 注意:使用font属性时,必须按上面语法格式中的顺序书写,不能更换顺序,各个属性以空格隔开。其中不需要设置的属性可以省略(取默认值),但必须保留font-size和font-family属性,否则font属性将不起作用。

1.6 font总结

属性

表示

注意点

font-size

字号

我们通常用的单位是px 像素,一定要跟上单位

font-family

字体

实际工作中按照团队约定来写字体

font-weight

字体粗细

记住加粗是 700 或者 bold 不加粗 是 normal 或者 400 记住数字不要跟单位

font-style

字体样式

记住倾斜是 italic 不倾斜 是 normal 工作中我们最常用 normal

font

字体连写

1. 字体连写是有顺序的 不能随意换位置 2. 其中字号 和 字体 必须同时出现

2. CSS外观属性

2.1 color:文本颜色

  • 作用:color属性用于定义文本的颜色,
  • 其取值方式有如下3种:

表示表示

属性值

预定义的颜色值

red,green,blue,还有我们的御用色 pink

十六进制

#FF0000,#FF6600,#29D794

RGB代码

rgb(255,0,0)或rgb(100%,0%,0%)

  • 注意我们实际工作中, 用 16进制的写法是最多的,而且我们更喜欢简写方式比如 #f00 代表红色

2.2 text-align:文本水平对齐方式

  • 作用:text-align属性用于设置文本内容的水平对齐,相当于html中的align对齐属性
  • 其可用属性值如下:

属性

解释

left

左对齐(默认值)

right

右对齐

center

居中对齐

  • 注意:是让盒子里面的内容水平居中, 而不是让盒子居中对齐

2.3 line-height:行间距

  • 作用:line-height属性用于设置行间距,就是行与行之间的距离,即字符的垂直间距,一般称为行高。
  • 单位:line-height常用的属性值单位有三种,分别为像素px,相对值em和百分比%,实际工作中使用最多的是像素px
  • 技巧:
一般情况下,行距比字号大7.8像素左右就可以了。
line-height: 24px;

2.4 text-indent:首行缩进

  • 作用:text-indent属性用于设置首行文本的缩进,
  • 属性值其属性值可为不同单位的数值、em字符宽度的倍数、或相对于浏览器窗口宽度的百分比%,允许使用负值,建议使用em作为设置单位。

1em 就是一个字的宽度 如果是汉字的段落, 1em 就是一个汉字的宽度

p {
      /*行间距*/
      line-height: 25px;
      /*首行缩进2个字  em  1个em 就是1个字的大小*/
      text-indent: 2em;  
 }

2.5 text-decoration 文本的装饰

text-decoration 通常我们用于给链接修改装饰效果

描述

none

默认。定义标准的文本。 取消下划线(最常用)

underline

定义文本下的一条线。下划线 也是我们链接自带的(常用)

overline

定义文本上的一条线。(不用)

line-through

定义穿过文本下的一条线。(不常用)

2.6 CSS外观属性总结

属性

表示

注意点

color

颜色

我们通常用 十六进制 比如 而且是简写形式 #fff

line-height

行高

控制行与行之间的距离

text-align

水平对齐

可以设定文字水平的对齐方式

text-indent

首行缩进

通常我们用于段落首行缩进2个字的距离 text-indent: 2em;

text-decoration

文本修饰

记住 添加 下划线 underline 取消下划线 none

3. sublime快捷操作emmet语法

Emmet的前身是Zen coding,它使用缩写,来提高html/css的编写速度。

  1. 生成标签 直接输入标签名 按tab键即可 比如 div 然后tab 键, 就可以生成 <div></div>
  2. 如果想要生成多个相同标签 加上 * 就可以了 比如 div*3 就可以快速生成3个div
  3. 如果有父子级关系的标签,可以用 > 比如 ul > li就可以了
  4. 如果有兄弟关系的标签,用 + 就可以了 比如 div+p
  5. 如果生成带有类名或者id名字的, 直接写 .demo 或者 #two tab 键就可以了
  6. 如果生成的div 类名是有顺序的, 可以用 自增符号 $ .demo$*3
    <div class="demo1"></div>
    <div class="demo2"></div>
    <div class="demo3"></div>

4. 拓展阅读@

emment语法

件引用规范

先说加载的规范,这个规范主要是为了提高页面加载速度或者是首屏的速度。

1 CSS 文件或样式在 head 标签中引用。页面的渲染需要 CSS,所以尽量早的让 CSS 文件加载出来。

2 JS 文件要放在 body 标签尾部。页面里加载和运行 JS 都会阻塞页面的渲染过程,所以把 JS 放在尾部可以加快首屏显示的速度,但对整个页面完成加载的时间没什么影响。

3 使用压缩后的文件。线上使用的静态文件,尽量都是压缩好的,CSS 使用 .min.css 形式,JS 使用 .min.js 形式,这样可以减少文件的体积,从而减少下载的时间。

4 减少 import 方式引用 css 文件。import 方式引入的 CSS 文件要等原 CSS 文件加载并解析后才会去请求, 会拖慢 CSS 文件的加载速度。

属性的书写规范

一、使用缩写

在 CSS 中有很多属性或属性值可以缩写, 在能用缩写的地方尽量使用缩写。

1、属性的缩写。CSS 中有些属性是可以合并的, 如:

margin-top: 10px;
margin-bottom: 0;
margin-left: 5px;
margin-right: 5px;

上面这几组 margin 相关的属性占了四条样式, 我们可以使用一条 margin 属性代替这四个方向的 margin:

margin: 10px 5px 0 5px;

一般带有方向的属性, 缩写的时候各个方向的值都是按着"上 右 下 左"的顺序写的。另外如果四个方向值一样,可以直接用一个值代替四个方向;如果左右方向的值一样,则可以省略最后一个左侧的值。

上面这条缩写也可以写成:

margin: 10px 5px 0;

2、颜色的缩写。在使用十六进制颜色的时候, 如果 rgb 三个颜色位置中, 每两位的颜色值相同, 可以把六位的颜色写成三位。

如:color: #22ffcc;

就可以写成:

color: #2fc;

这两种写法是等效的, 但要注意的是如果需要兼容低版本 IE 浏览器, 还是要用六位的颜色值。

3、数字的缩写。在 CSS 中如果整数部分是 0 的小数, 可以忽略小数点前面的 0; 如果属性值是 0, 则可以忽略属性值的单位。

如: font-size: 0.8rem; padding: 0px;

这两条属性就可以做简写:

font-size: .8rem; padding: 0;

二、属性顺序的规范

理论上, CSS 的属性是一条一条解析执行的。这种情况下, 就要把能确定大小和位置的属性写在前面, 把对布局没什么影响的属性写在后面, 避免返工。

一般说的使用顺序如下:

1. 位置属性 (position, top, right, z-index, display, float等)  

2. 大小 (width, height, padding, margin)  

3. 文字系列 (font, line-height, letter-spacing, color- text-align等)  

4. 背景 (background, border等) 5. 其他 (animation, transition等)

注释规范

一 文件头注释

/*
* @Author: zhangsan
* @Date: 2023-04-18 20:09:21
* @Last Modified by: zhangsan
* @Last Modified time: 2023-05-05 10:21:21
*/



二 普通注释

/* 头部导航 */
.nav-top{
background: #ccc;
}

CSS-Reset


上一篇:HTML 布局
下一篇:HTML 实例