切换语言为:繁体
 Tailwind CSS 响应式开发,实现用一套代码实现多终端的样式切换

Tailwind CSS 响应式开发,实现用一套代码实现多终端的样式切换

  • 爱糖宝
  • 2024-07-08
  • 2065
  • 0
  • 0

1. 前言

    本篇将会介绍 Tailwind CSS 的响应式开发,如何用一套代码实现多终端的样式切换。

    2. 媒体查询

    在以往,我们使用 CSS3 进行开发时会通过媒体查询来实现。比如有代码如下:

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <style>
          /* 样式代码 */
        </style>
      </head>
      <body>
        <div>
          <div id="app"></div>
        </div>
        <script>
          class App {
            constructor() {
              this.el = document.getElementById('app');
              this.init();
            }
            init() {
              this.render();
              this.watch();
            }
            render() {
              this.el.innerHTML = 'first render';
            }
            watch() {
              window.addEventListener('resize', () => {
                const width = window.innerWidth;
                this.el.innerHTML = `${width}px`;
              });
            }
          }
          const app = new App();
        </script>
      </body>
    </html>

    这是一个简单的 Demo,当用户调整浏览器宽度时就会更新宽度显示,而且在不同的宽度下背景颜色发生变化。

    2.1 @media

    样式代码是这样的:

    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    #app {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      background-color: #fff;
      font-size: 48px;
    }
    @media screen and (min-width: 640px) {
      #app {
        background-color: red;
      }
    }
    @media screen and (min-width: 768px) {
      #app {
        background-color: orange;
      }
    }
    @media screen and (min-width: 1024px) {
      #app {
        background-color: yellow;
      }
    }
    @media screen and (min-width: 1280px) {
      #app {
        background-color: green;
      }
    }
    @media screen and (min-width: 1536px) {
      #app {
        background-color: blue;
      }
    }

    上面用到了 CSS3 的一个特性:@mediascreen 表示设备类型为屏幕,通过 and 关键字来并列多个配置。min-width 表示最小宽度,如果按照一把直尺的刻度去理解,最小宽度就是一条线段的左侧较小值,往右,宽度大于这个值时就会应用对应的样式声明。

    2.2 断点

    上面的多个媒体查询定义决定了响应式的不同断点,这些断点被称为 breakpoints,这是每一个具备响应式系统的 UI 规范都要考虑的。上面的 5 个断点对应如下:

     Tailwind CSS 响应式开发,实现用一套代码实现多终端的样式切换

    • small:640px 起,横向模式显示状态的手机(640px 到下一个断点显示为红色)

    • medium:768px 起,平板(768px 到下一个断点显示为橙色)

    • large:1024px 起,电脑(1024px 到下一个断点显示为蛋心色)

    • x large:1280px 起,大型电脑(1280px 到下一个断点显示为绿色)

    • 2x large:1536px 起,更大型电脑(1536px 到下一个断点显示为蓝色)

    2.3 mobile first

    mobile first 是一个比较通用的概念——优先考虑移动设备,随着屏幕变大再去适应更大的设备宽度。这主要依靠上面所说的断点机制,下面来看在 Tailwind CSS 中如何使用响应式。

    3. Tailwind CSS 中的响应式系统

    在 Tailwind CSS 中不需要像上面那样写复杂的媒体查询声明代码了,而是通过提前预设好的 CSS 类名来定义元素的样式。

    3.1 断点

    Tailwind CSS 的断点和 2.2 中提到的断点一样,与类名的对应关系如下:

     Tailwind CSS 响应式开发,实现用一套代码实现多终端的样式切换

    3.2 断点前缀:类名

    通过 断点前缀:类名 的形式就能定义元素的响应式样式,下面是一个简单的使用案例:

    'use client';
    
    import useWindowWidth from '@/hooks/useWindowWidth';
    
    export default function Home() {
      const width = useWindowWidth();
    
      return (
        <main className="text-center sm:bg-red-300 md:bg-orange-300 lg:bg-yellow-300 xl:bg-green-300 2xl:bg-blue-300">
          <div>hello tailwind css</div>
          <div>current width: {width}px</div>
        </main>
      );
    }

    以 Next.js 中的 React 为例:

    • sm:bg-red-300 表示在 640px 以上时为红色

    • md:bg-orange-300 表示 768px 以上时为橙色

    其他依次类推,smmd 等都是断点前缀,冒号后面是想要定义的样式类名。

    最终效果如下所示:

     Tailwind CSS 响应式开发,实现用一套代码实现多终端的样式切换

    需要注意的是,没有加上断点前缀的类名默认是作用于所有设备大小的,比如上面代码中的 text-center ,可以看到在任何大小下都是文本居中对齐的。

    3.3 定义范围

    如果我只想在 smlg 的范围内应用背景颜色怎么办?显然只写 sm:bg-red-300 是不行的,因为它表示的是大于 640px 宽度都会应用到红色。

    解决办法是使用 *:max-** 表示断点前缀)为它定义一段范围:

    <main className="text-center sm:max-lg:bg-red-300">
      <div>hello tailwind css</div>
      <div>current width: {width}px</div>
    </main>

    • sm:max-lg:bg-red-300 表示在 smlg 这段范围内(640px~1024px)应用红色

    4. 自定义配置

    同样在 tailwind.config.ts 中来配置各种自定义的规则,对于响应式的部分则在 theme.screens 中去定义。

    4.1 覆盖默认值

    默认情况下断点前缀的配置如下所示:

    /** @type {import('tailwindcss').Config} */
    module.exports = {
      theme: {
        screens: {
          'sm': '640px',
          // => @media (min-width: 640px) { ... }
    
          'md': '768px',
          // => @media (min-width: 768px) { ... }
    
          'lg': '1024px',
          // => @media (min-width: 1024px) { ... }
    
          'xl': '1280px',
          // => @media (min-width: 1280px) { ... }
    
          '2xl': '1536px',
          // => @media (min-width: 1536px) { ... }
        }
      }
    }

    覆盖默认值的方法很简单,直接在 theme.screens 中替换掉原来的值即可,例如:

    theme: {
      screens: {
        sm: '576px',
        // => @media (min-width: 576px) { ... }
    
        md: '960px',
        // => @media (min-width: 960px) { ... }
    
        lg: '1440px',
        // => @media (min-width: 1440px) { ... }
      },
    },

    注意:默认值有 smmdlgxl2xl 等等,因此上面只写了 smmdlg 三种,实际上能应用的也就只有这三种。因此,这不是覆盖原来的某个断点,而是直接覆盖了 theme.screens 对象的所有值。

    4.2 覆盖原来值

    如果只是想覆盖掉某一个断点,只需要在 theme.extend.screens 中修改,比如我想覆盖 sm 断点:

    extend: {
      screens: {
        sm: '576px',
        // => @media (min-width: 576px) { ... }
      },
    }

    这样,sm 的值就从 640px 变为 576px,因此,从 576px 开始,背景颜色就是红色了:

     Tailwind CSS 响应式开发,实现用一套代码实现多终端的样式切换

    4.3 添加更大的断点

    theme.extend.screens 中也可以添加更大范围的断点:

    extend: {
      screens: {
        '3xl': '1600px',
        // => @media (min-width: 1600px) { ... }
      },
    }

    main 添加 3xl 的断点:

    <main className="text-center sm:bg-red-300 md:bg-orange-300 lg:bg-yellow-300 xl:bg-green-300 2xl:bg-blue-300 3xl:bg-slate-300">
      <div>hello tailwind css</div>
      <div>current width: {width}px</div>
    </main>

    效果如下:

     Tailwind CSS 响应式开发,实现用一套代码实现多终端的样式切换

    4.4 添加更小的断点

    虽然更大的断点可以通过 theme.extend.screens 来实现,但是更小的却不可以这么做,原因在于 extend 是向原来的内容进行追加,所以是在最后一位,而 tailwind 需要它们按照从小到大的顺序排序。

    tailwindcss 模块中有一个 defaultTheme 对象,这里存放着默认断点值,只要将默认值和自定义的更小范围断点结合在一起就可以实现了:

    import type { Config } from 'tailwindcss';
    import defaultTheme from 'tailwindcss/defaultTheme';
    
    const config: Config = {
      // ...
      theme: {
        screens: {
          xs: '475px',
          ...defaultTheme.screens,
        },
      },
    };
    export default config;

    之后就可以使用 xs 了:

    <main className="text-center xs:bg-purple-300 sm:bg-red-300 md:bg-orange-300 lg:bg-yellow-300 xl:bg-green-300 2xl:bg-blue-300 3xl:bg-slate-300">
      <div>hello tailwind css</div>
      <div>current width: {width}px</div>
    </main>

    • xs:bg-purple-300 表示 475px 起背景颜色为紫色

    效果如下:

     Tailwind CSS 响应式开发,实现用一套代码实现多终端的样式切换

    4.5 定义断点范围

    在 3.3 节通过 *:max-* 的方式实现了断点范围的控制,在配置文件中还提供了一种更加快捷的方案:

    theme: {
      screens: {
        sm: { min: '640px', max: '767px' },
        // => @media (min-width: 640px and max-width: 767px) { ... }
    
        md: { min: '768px', max: '1023px' },
        // => @media (min-width: 768px and max-width: 1023px) { ... }
    
        lg: { min: '1024px', max: '1279px' },
        // => @media (min-width: 1024px and max-width: 1279px) { ... }
    
        xl: { min: '1280px', max: '1535px' },
        // => @media (min-width: 1280px and max-width: 1535px) { ... }
    
        '2xl': { min: '1536px' },
        // => @media (min-width: 1536px) { ... }
      },
    }

    默认情况下的断点范围较大,比如 sm 表示 640px 起,这样一旦 md 等断点都没有去设置就会都应用 sm 的样式了。像上面这样的配置就控制了断点的范围使之更加符合响应式的本质。

    有下面代码:

    <main className="text-center sm:bg-red-300">
      <div>hello tailwind css</div>
      <div>current width: {width}px</div>
    </main>

    只有在屏幕宽度处于 640px ~ 767px 的范围下,背景颜色才表现为红色。

    5. 总结

    这篇文章主要讲解了传统响应式和 TailwindCSS 中的响应式,有了 Tailwind 就不用再去写媒体查询了,这对于开发者来说是一个喜讯。在开发响应式方面最值得关注的就是断点,控制好断点也就控制好了响应式。除了上述提到的配置特性,还有自定义名称、自定义多个范围、自定义查询等等,这类特性其实并不是开发必需的,只属于灵活性的范畴,如果需要可以自行查阅文档。

    0条评论

    您的电子邮件等信息不会被公开,以下所有项均必填

    OK! You can skip this field.