Skip to content

文字

文字方向

  • writing-mode :定义了文本水平或垂直排布以及在块级元素中文本的行进方向
  • margin-block : 定义了元素的逻辑块首和块末外边距,并根据元素的书写模式、行内方向和文本朝向对应至实体外边距。
  • text-combine-upright : 字符组合设置为单个字符的间距。
雨霖铃·寒蝉凄切

宋·柳永 987~1053

寒蝉凄切,对长亭晚,骤雨初歇。

都门帐饮无绪,留恋处,兰舟催发。

执手相看泪眼,竟无语凝噎。

念去去,千里烟波,暮霭沉沉楚天阔。

多情自古伤离别,更那堪,冷落清秋节!

今宵酒醒何处?杨柳岸,晓风残月。

此去经年,应是良辰好景虚设。

便纵有千种风情,更与何人说?

尝试一下:

要点

  1. 具体年份数值应该是连续的。 text-combine-upright: all;
  2. 不能直接设置具体的外边距方向,而应该设置逻辑方向。 margin-block-start: 10px; margin-block-end: 10px;
完整代码
vue
<template>
  <div ref="container" class="container">
    <div class="title">雨霖铃·寒蝉凄切</div>
    <p class="author">
      <span> 宋·柳永 </span>
      <span class="year">987</span>
      <span class="year">~</span>
      <span class="year">1053</span>
    </p>
    <div>
      <p>寒蝉凄切,对长亭晚,骤雨初歇。</p>
      <p>都门帐饮无绪,留恋处,兰舟催发。</p>
      <p>执手相看泪眼,竟无语凝噎。</p>
      <p>念去去,千里烟波,暮霭沉沉楚天阔。</p>
      <p>多情自古伤离别,更那堪,冷落清秋节!</p>
      <p>今宵酒醒何处?杨柳岸,晓风残月。</p>
      <p>此去经年,应是良辰好景虚设。</p>
      <p>便纵有千种风情,更与何人说?</p>
    </div>
  </div>
  <div>
    <h3 style="margin-bottom: 20px">尝试一下:</h3>
    <div>
      <n-dropdown :options="writingMode" @select="handleWritingMode">
        <n-button>文字方向</n-button>
      </n-dropdown>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive } from 'vue';
import { NDropdown, NButton } from 'naive-ui';

// 文章容器
const container = ref();
// 文字方向选项
const writingMode = reactive([
  {
    label: 'horizontal-tb',
    key: 'horizontal-tb',
  },
  {
    label: 'vertical-lr',
    key: 'vertical-lr',
  },
  {
    label: 'vertical-rl',
    key: 'vertical-rl',
  },
  {
    label: 'sideways-lr',
    key: 'sideways-lr',
  },
  {
    label: 'sideways-rl',
    key: 'sideways-rl',
  },
]);

// 文字方向选择处理
const handleWritingMode = (key: string | number) => {
  container.value.style.writingMode = key;
};
</script>

<style lang="scss" scoped>
.container {
  width: 100%;
  height: fit-content;
  background-color: #333;
  color: #fff;
  .title {
    font-size: 1.5rem;
    margin: 10px 0;
  }
  .author {
    font-size: 0.8rem;
    font-weight: 600;
    margin-block-start: 10px;
    margin-block-end: 10px;
    .year {
      text-combine-upright: all;
    }
  }
}
</style>

文字边框

实现方式1:文字阴影

  • 缺点:
    1. 不能显示背景颜色。
    2. 仅8个方向有阴影,会产生锯齿。

Word Shadow

代码
vue
<template>
  <div class="container">
    <p class="word-shadow">Word Shadow</p>
  </div>
</template>

<style lang="scss" scoped>
.container {
  width: 100%;
  height: 200px;
  background-color: #333;
  display: flex;
  justify-content: center;
  align-items: center;
  .word-shadow {
    font-size: 5rem;
    // 设置文字跟背景颜色一致
    color: #333;
    // 设置8个方向的文字阴影
    text-shadow: #fff 1px 0, #fff 1px 1px, #fff 0 1px, #fff -1px 1px, #fff -1px 0, #fff -1px -1px, #fff 0 -1px, #fff 1px -1px;
  }
}
</style>

实现方式2:-webkit-text-stroke

  • 优点:文字可以显示背景颜色
  • 缺点:
    1. 兼容性问题
    2. 描边是居中描边,且无法更改。(可以使用::after 设置一样大小的文字内容去覆盖)

Word Shadow

代码
vue
<template>
  <div class="container">
    <p class="word-shadow" data-content="Word Shadow">Word Shadow</p>
  </div>
</template>

<style lang="scss" scoped>
.container {
  width: 100%;
  height: 200px;
  background: linear-gradient(to right, blue, pink);
  display: flex;
  justify-content: center;
  align-items: center;
  .word-shadow {
    font-size: 5rem;
    // 设置文字颜色为透明
    color: transparent;
    // 设置文字边框
    -webkit-text-stroke: 2px #fff;
    // 覆盖文字内容,防止文字变细
    &::after {
        content: attr(data-content);
        position: absolute;
        left: 0;
        top: 0;
        -webkit-text-stroke: 0;
    }
  }
}
</style>

文字阴影

缺点:放大后有锯齿,且不能旋转

Word Shadow

文字镂空

实现原理

  1. 蒙层覆盖容器,文字元素宽高撑满蒙层来实现下一步
  2. 蒙层中的 文字 背景与 容器 保持一致
  3. 将背景只显示到文本 background-clip
  4. 去除文字颜色 color: transparent;
点击查看代码
vue
<template>
  <!-- 容器 -->
  <div class="container">
    <!-- 蒙层 -->
    <div class="modal">
      <!-- 文字 -->
      <p>Astral</p>
    </div>
  </div>
</template>

<style scoped lang="scss">
.container {
  margin-top: 10px;
  width: 100%;
  height: 400px;
  display: flex;
  justify-content: center;
  align-items: center;
  background: url('/programmer/image/resource/astral.jpg') no-repeat center/100%;
}
.modal {
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.5);
  // 撑满父元素
  p {
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    margin: 0;
    font-size: 12vw;
    font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;
    // 文字描边
    -webkit-text-stroke: 1px #fff;
    // 背景与父元素保持一致
    background: url('/programmer/image/resource/astral.jpg') no-repeat center/100%;
    // 将背景只显示到文本
    background-clip: text;
    // 去除文字颜色
    color: transparent;
  }
}
</style>

文字下划线

原理:背景渐变实现下划线

滕王阁序

唐·王勃

嗟乎!时运不齐,命途多舛。冯唐易老,李广难封。屈贾谊于长沙,非无圣主;窜梁鸿于海曲,岂乏明时?所赖君子见机,达人知命。老当益壮,宁移白首之心?穷且益坚,不坠青云之志。
实现代码
vue
<template>
  <div class="container">
    <h3>滕王阁序</h3>
    <p>唐·王勃</p>
    <span>
      嗟乎!时运不齐,命途多舛。冯唐易老,李广难封。屈贾谊于长沙,非无圣主;
      窜梁鸿于海曲,岂乏明时?所赖君子见机,达人知命。
      老当益壮,宁移白首之心?穷且益坚,不坠青云之志。
    </span>
  </div>
</template>

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

<style lang="scss" scoped>
span {
  // 文字行距
  line-height: 2rem;
  // 文字大小
  font-size: 1.25rem;
  // 背景渐变 不重复 靠右 靠下
  background: linear-gradient(to right, #1f94cf, #d76ddf) no-repeat right bottom;
  // 背景大小 当为0的时候,不存在下划线,当为100%的时候,存在下划线
  background-size: 0 2px;
  // 设置过渡动画
  transition: background-size 1s;
  &:hover {
    // 背景大小 当为0的时候,不存在下划线,当为100%的时候,存在下划线
    background-size: 100% 2px;
    // 当鼠标移除时,反向回收下划线
    background-position: left bottom;
  }
}
</style>

文字视频特效

实现原理:mix-blend-mode

三国恋
当前模式:screen

提示

当color1为白色(255)时,mix-blend-mode为screen时,颜色一定为白色

当color1为黑色(0)时,mix-blend-mode为screen时,颜色一定为黑色

计算方式:

js
mix-blend-mode(color1, color2){
  // 分别返回 R G B A
  return 255 - (255-A)(255-B) / 255
}
实现代码
vue
<template>
  <div class="container">
    <video class="word-video" src="/video/flame.mkv?url" autoplay muted loop preload></video>
    <div class="word-text">三国恋</div>
  </div>
</template>
<style lang="scss" scoped>
.container {
  width: 100%;
  background-color: #333;
  position: relative;
  .word-video {
    width: 100%;
  }
  .word-text {
    font-size: 5rem;
    // 文字间距
    letter-spacing: 20px;
    color: #000000;
    font-weight: bold;
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    // 设置背景色
    background-color: rgba(255, 255, 255);
    // 混合
    mix-blend-mode: screen;
  }
}
</style>

Released under the MIT License.