Skip to content

Typography 排版

DHdesign 字体体系按 PC 和移动端分别定义字阶。常规界面文本优先使用系统无衬线字体,数据、指标、时间、金额等数字场景使用强化数字字体。

ts
// Typography 基于 CSS 设计变量(design tokens),无需引入任何组件。

字体

常规中文文本优先使用 PingFang SC / Noto Sans CJK SC,并回退到各系统默认字体;数字文本优先使用 OPPO Sans,再回退到 Roboto / Helvetica / Arial。

<template>
  <div class="demo-typo-fonts">
    <div v-for="item in fonts" :key="item.name" class="demo-typo-card">
      <div class="demo-typo-card__head">{{ item.name }}</div>
      <div class="demo-typo-card__body">
        <div class="demo-typo-card__sample" :style="{ fontFamily: item.family }">
          <span class="demo-typo-card__glyph">{{ item.glyph }}</span>
          <div class="demo-typo-card__weights">
            <span
              v-for="w in item.weights"
              :key="w.label"
              :style="{ fontWeight: w.value }"
            >{{ w.label }}</span>
          </div>
        </div>
        <p class="demo-typo-card__text" :style="{ fontFamily: item.family }">
          {{ item.text }}
        </p>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
const fonts = [
  {
    name: 'PingFang SC',
    family: '"PingFang SC", sans-serif',
    glyph: '永',
    text: '永和九年,岁在癸丑,暮春之初,会于会稽山阴之兰亭,修禊事也。',
    weights: [
      { label: 'Regular', value: 400 },
      { label: 'Medium', value: 500 },
      { label: 'SemiBold', value: 600 },
    ],
  },
  {
    name: 'Noto Sans CJK / Source Han Sans',
    family: '"Noto Sans CJK SC", "Source Han Sans SC", sans-serif',
    glyph: '永',
    text: '永和九年,岁在癸丑,暮春之初,会于会稽山阴之兰亭,修禊事也。',
    weights: [
      { label: 'Regular', value: 400 },
      { label: 'Medium', value: 500 },
    ],
  },
  {
    name: 'OPPO Sans Bold',
    family: '"OPPO Sans", "PingFang SC", sans-serif',
    glyph: '永',
    text: '用于重点强化中文和运营标题展示。',
    weights: [
      { label: 'Bold', value: 700 },
    ],
  },
  {
    name: 'OPPO Sans Bold / Number',
    family: '"OPPO Sans", "Roboto", "Helvetica Neue", Helvetica, Arial, sans-serif',
    glyph: '01',
    text: '0123456789 / 重点强化数字展示。',
    weights: [
      { label: 'Bold', value: 700 },
    ],
  },
]
</script>

<style scoped>
.demo-typo-fonts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 16px;
}
.demo-typo-card {
  border: 1px solid var(--el-border-color-lighter);
  border-radius: var(--el-border-radius-base);
  overflow: hidden;
}
.demo-typo-card__head {
  padding: 8px 16px;
  background: var(--el-fill-color-light);
  color: var(--el-text-color-secondary);
  font-size: 13px;
}
.demo-typo-card__body {
  padding: 16px;
}
.demo-typo-card__sample {
  display: flex;
  align-items: center;
  gap: 24px;
  margin-bottom: 12px;
}
.demo-typo-card__glyph {
  font-size: 64px;
  line-height: 1;
  color: var(--el-text-color-primary);
}
.demo-typo-card__weights {
  display: flex;
  flex-direction: column;
  gap: 4px;
  color: var(--el-text-color-regular);
}
.demo-typo-card__text {
  margin: 0;
  color: var(--el-text-color-regular);
  font-size: 13px;
  line-height: 1.6;
}
</style>

字号

<template>
  <div class="demo-typo-table-wrap">
    <table class="demo-typo-table">
      <thead>
        <tr>
          <th>样式</th>
          <th>大小</th>
          <th>行高</th>
          <th>字重</th>
          <th>应用场景</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="item in sizes" :key="`${item.name}-${item.weightLabel}`">
          <td
            class="demo-typo-table__sample"
            :style="{
              fontSize: item.size,
              lineHeight: item.lineHeight,
              fontWeight: item.weight,
            }"
          >
            数字海南设计系统
          </td>
          <td>{{ item.sizeText }}</td>
          <td>{{ item.lineHeightText }}</td>
          <td>{{ item.weightLabel }}</td>
          <td>{{ item.name }}</td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script lang="ts" setup>
const sizes = [
  { name: '运营标题加粗-大', size: 'var(--dh-font-size-display-large)', sizeText: '56px', lineHeight: 'var(--dh-line-height-display-large)', lineHeightText: '64px', weight: 500, weightLabel: 'Medium' },
  { name: '运营标题-大', size: 'var(--dh-font-size-display-large)', sizeText: '56px', lineHeight: 'var(--dh-line-height-display-large)', lineHeightText: '64px', weight: 400, weightLabel: 'Regular' },
  { name: '运营标题加粗-中', size: 'var(--dh-font-size-display-medium)', sizeText: '48px', lineHeight: 'var(--dh-line-height-display-medium)', lineHeightText: '56px', weight: 500, weightLabel: 'Medium' },
  { name: '运营标题-中', size: 'var(--dh-font-size-display-medium)', sizeText: '48px', lineHeight: 'var(--dh-line-height-display-medium)', lineHeightText: '56px', weight: 400, weightLabel: 'Regular' },
  { name: '运营标题加粗-小', size: 'var(--dh-font-size-display-small)', sizeText: '36px', lineHeight: 'var(--dh-line-height-display-small)', lineHeightText: '42px', weight: 500, weightLabel: 'Medium' },
  { name: '运营标题-小', size: 'var(--dh-font-size-display-small)', sizeText: '36px', lineHeight: 'var(--dh-line-height-display-small)', lineHeightText: '42px', weight: 400, weightLabel: 'Regular' },
  { name: '标题加粗-大', size: 'var(--dh-font-size-title-large)', sizeText: '24px', lineHeight: 'var(--dh-line-height-title-large)', lineHeightText: '30px', weight: 500, weightLabel: 'Medium' },
  { name: '标题-大', size: 'var(--dh-font-size-title-large)', sizeText: '24px', lineHeight: 'var(--dh-line-height-title-large)', lineHeightText: '30px', weight: 400, weightLabel: 'Regular' },
  { name: '标题加粗-中', size: 'var(--dh-font-size-title-medium)', sizeText: '20px', lineHeight: 'var(--dh-line-height-title-medium)', lineHeightText: '28px', weight: 500, weightLabel: 'Medium' },
  { name: '标题-中', size: 'var(--dh-font-size-title-medium)', sizeText: '20px', lineHeight: 'var(--dh-line-height-title-medium)', lineHeightText: '28px', weight: 400, weightLabel: 'Regular' },
  { name: '标题加粗-小', size: 'var(--dh-font-size-title-small)', sizeText: '16px', lineHeight: 'var(--dh-line-height-title-small)', lineHeightText: '24px', weight: 500, weightLabel: 'Medium' },
  { name: '标题、正文-常规-小', size: 'var(--dh-font-size-title-small)', sizeText: '16px', lineHeight: 'var(--dh-line-height-title-small)', lineHeightText: '24px', weight: 400, weightLabel: 'Regular' },
  { name: '正文重点-常规-大', size: 'var(--dh-font-size-body-large)', sizeText: '14px', lineHeight: 'var(--dh-line-height-body-large)', lineHeightText: '22px', weight: 500, weightLabel: 'Medium' },
  { name: '正文-常规-大', size: 'var(--dh-font-size-body-large)', sizeText: '14px', lineHeight: 'var(--dh-line-height-body-large)', lineHeightText: '22px', weight: 400, weightLabel: 'Regular' },
  { name: '辅助文案重点', size: 'var(--dh-font-size-auxiliary)', sizeText: '12px', lineHeight: 'var(--dh-line-height-auxiliary)', lineHeightText: '20px', weight: 500, weightLabel: 'Medium' },
  { name: '辅助文案、标签文字', size: 'var(--dh-font-size-auxiliary)', sizeText: '12px', lineHeight: 'var(--dh-line-height-auxiliary)', lineHeightText: '20px', weight: 400, weightLabel: 'Regular' },
]
</script>

<style scoped>
.demo-typo-table-wrap {
  overflow-x: auto;
}
.demo-typo-table {
  min-width: 960px;
  width: 100%;
  border-collapse: collapse;
  color: var(--el-text-color-regular);
  font-family: var(--dh-font-family);
}
.demo-typo-table th,
.demo-typo-table td {
  padding: 12px 16px;
  text-align: left;
  border-bottom: 1px solid var(--el-border-color-lighter);
}
.demo-typo-table th {
  background: var(--el-fill-color-light);
  color: var(--el-text-color-secondary);
  font-weight: 500;
}
.demo-typo-table code {
  font-size: 12px;
  color: var(--el-color-primary);
}
.demo-typo-table__sample {
  color: var(--dh-color-text-primary);
  white-space: nowrap;
}
</style>

字重

字重(font-weight)用于设置文字的粗细程度。

<template>
  <div class="demo-typo-weights">
    <div class="demo-typo-weight">
      <div class="demo-typo-weight__label">Medium · 500</div>
      <div class="demo-typo-weight__text" style="font-weight: var(--el-font-weight-primary)">
        DHdesign 设计系统 · 重点文字
      </div>
    </div>
    <div class="demo-typo-weight">
      <div class="demo-typo-weight__label">SemiBold · 600</div>
      <div class="demo-typo-weight__text" style="font-weight: var(--dh-font-weight-semibold)">
        DHdesign 设计系统 · 强调文字
      </div>
    </div>
    <div class="demo-typo-weight">
      <div class="demo-typo-weight__label">Regular · 400</div>
      <div class="demo-typo-weight__text" style="font-weight: 400">
        DHdesign 设计系统 · 常规文字
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
</script>

<style scoped>
.demo-typo-weights {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.demo-typo-weight {
  display: flex;
  align-items: baseline;
  gap: 24px;
  padding: 12px 16px;
  border: 1px solid var(--el-border-color-lighter);
  border-radius: var(--el-border-radius-base);
}
.demo-typo-weight__label {
  width: 140px;
  font-size: 12px;
  color: var(--el-text-color-secondary);
}
.demo-typo-weight__text {
  font-size: 16px;
  color: var(--el-text-color-primary);
}
</style>

行高

<template>
  <section class="demo-line-height">
    <h3>3、行高</h3>
    <p>
      行高的作用是为相邻两行文字预留充足呼吸空间,避免排版拥挤、阅读压抑,保障长时间阅读的舒适度。参考行业规范逻辑,以固定数值 8 作为变量,实现不同字号文本的行间距统一,让各类字号的行高空间趋于均衡,使整体文本排版整洁有序、视觉节奏统一。
    </p>
    <div class="demo-line-height__figure">
      <div class="demo-line-height__size">
        <strong>字号</strong>
        <span>12px</span>
      </div>
      <div class="demo-line-height__measure">
        <span class="demo-line-height__dash demo-line-height__dash--top"></span>
        <span class="demo-line-height__dash demo-line-height__dash--bottom"></span>
      </div>
      <div class="demo-line-height__text">
        欢迎使用数字海南设计系统
      </div>
      <div class="demo-line-height__bar" aria-hidden="true"></div>
      <div class="demo-line-height__value">
        <strong>行高</strong>
        <span>20px</span>
      </div>
      <div class="demo-line-height__caption">正文字号 12px,行高为 20px</div>
    </div>
  </section>
</template>

<script lang="ts" setup>
</script>

<style scoped>
.demo-line-height {
  color: var(--dh-color-text-primary);
  font-family: var(--dh-font-family);
}
.demo-line-height h3 {
  margin: 0;
  font-size: 24px;
  line-height: 30px;
  font-weight: var(--dh-font-weight-medium);
}
.demo-line-height p {
  max-width: 900px;
  margin: 24px 0;
  color: var(--dh-color-text-primary);
  font-size: 16px;
  line-height: 28px;
}
.demo-line-height__figure {
  position: relative;
  display: grid;
  grid-template-columns: 88px 180px minmax(240px, 1fr) 24px 90px;
  align-items: center;
  min-height: 160px;
  padding: 28px 32px 44px;
  overflow: hidden;
  border-radius: 8px;
  background: #f5f5f5;
}
.demo-line-height__size,
.demo-line-height__value {
  display: grid;
  gap: 4px;
  color: var(--dh-color-text-primary);
  font-size: 16px;
  line-height: 22px;
}
.demo-line-height__size strong,
.demo-line-height__value strong {
  font-weight: var(--dh-font-weight-medium);
}
.demo-line-height__size span,
.demo-line-height__value span {
  color: var(--dh-color-text-secondary);
  font-size: 14px;
  line-height: 22px;
}
.demo-line-height__measure {
  position: relative;
  height: 68px;
}
.demo-line-height__dash {
  position: absolute;
  left: 0;
  width: 100%;
  border-top: 1px dashed var(--dh-color-primary);
}
.demo-line-height__dash--top {
  top: 18px;
}
.demo-line-height__dash--bottom {
  bottom: 18px;
}
.demo-line-height__text {
  display: inline-flex;
  align-items: center;
  justify-self: start;
  height: 48px;
  padding: 0 8px;
  color: var(--dh-color-primary);
  background: rgba(7, 90, 237, 0.1);
  font-size: 36px;
  line-height: 42px;
  white-space: nowrap;
}
.demo-line-height__bar {
  position: relative;
  width: 16px;
  height: 68px;
  border-top: 2px solid var(--dh-color-primary);
  border-bottom: 2px solid var(--dh-color-primary);
}
.demo-line-height__bar::before {
  position: absolute;
  top: -2px;
  bottom: -2px;
  left: 7px;
  width: 2px;
  background: var(--dh-color-primary);
  content: "";
}
.demo-line-height__caption {
  position: absolute;
  right: 0;
  bottom: 16px;
  left: 0;
  color: var(--dh-color-text-placeholder);
  font-size: 14px;
  line-height: 22px;
  text-align: center;
}
@media (max-width: 768px) {
  .demo-line-height__figure {
    grid-template-columns: 64px 72px minmax(180px, 1fr) 20px 64px;
    padding: 20px 16px 40px;
  }
  .demo-line-height__text {
    font-size: 24px;
    line-height: 30px;
  }
}
</style>

段落示例

<template>
  <div class="demo-typography">
    <h1>数字海南设计系统</h1>
    <h2>标题加粗-中</h2>
    <p class="demo-typography__body">正文-常规-大:DHdesign 使用统一字阶保持页面信息层级清晰。</p>
    <p class="demo-typography__small">辅助文案重点:适用于列表说明、表单提示等轻量信息。</p>
    <p class="demo-typography__aux">辅助文案、标签文字</p>
  </div>
</template>

<script lang="ts" setup>
</script>

<style scoped>
.demo-typography {
  font-family: var(--dh-font-family);
}
.demo-typography h1 {
  margin: 0 0 16px;
  color: var(--dh-color-text-primary);
  font-size: var(--dh-font-size-display-small);
  font-weight: var(--dh-font-weight-medium);
  line-height: var(--dh-line-height-display-small);
}
.demo-typography h2 {
  margin: 0 0 12px;
  color: var(--dh-color-text-primary);
  font-size: var(--dh-font-size-title-medium);
  font-weight: var(--dh-font-weight-medium);
  line-height: var(--dh-line-height-title-medium);
}
.demo-typography p {
  margin: 8px 0;
}
.demo-typography__body {
  color: var(--dh-color-text-primary);
  font-size: var(--dh-font-size-body-large);
  line-height: var(--dh-line-height-body-large);
}
.demo-typography__small {
  color: var(--dh-color-text-secondary);
  font-size: var(--dh-font-size-auxiliary);
  line-height: var(--dh-line-height-auxiliary);
}
.demo-typography__aux {
  color: var(--dh-color-text-placeholder);
  font-size: var(--dh-font-size-auxiliary);
  line-height: var(--dh-line-height-auxiliary);
}
</style>

API

PC 字阶

应用场景字号行高字重
运营标题-大56px64px400 / 500
运营标题-中48px56px400 / 500
运营标题-小36px42px400 / 500
标题-大24px30px400 / 500
标题-中20px28px400 / 500
标题、正文-常规-小16px24px400 / 500
正文-常规-大14px22px400 / 500
辅助文案、标签文字12px20px400 / 500

移动端字阶

应用场景字号行高字重
大标题22px30px500
重点标题 / 标题20px28px400 / 500
重点强调 / 强调内容18px26px400 / 500
正文、一级 tab16px24px400 / 500
二级正文、二级 tab14px22px400 / 500
三级文字、三级 tab13px21px400 / 500
辅助文字12px20px400 / 500
底 bar 文字11px19px400 / 500
小标签文字10px18px400

Element Plus 字号映射

名称默认值
--el-font-size-extra-large24px
--el-font-size-large20px
--el-font-size-medium16px
--el-font-size-base14px
--el-font-size-small12px
--el-font-size-extra-small12px

字重 CSS 变量

名称默认值
--el-font-weight-primary500
--dh-font-weight-regular400
--dh-font-weight-medium500
--dh-font-weight-semibold600

行高 CSS 变量

名称默认值
--el-font-line-height-primary24px
--el-font-line-height-secondary20px
--dh-line-height-display-large64px
--dh-line-height-display-medium56px
--dh-line-height-display-small42px
--dh-line-height-title-large30px
--dh-line-height-title-medium28px
--dh-line-height-title-small24px
--dh-line-height-body-large22px
--dh-line-height-auxiliary20px

字体颜色

类型色值使用场景
主要文字rgba(0, 0, 0, 0.9)正文内容
次要文字rgba(0, 0, 0, 0.68)辅助说明
辅助文字rgba(0, 0, 0, 0.48)提示信息
禁用文字rgba(0, 0, 0, 0.2)禁用状态

更多细节见 Element Plus Typography 文档。