发布于 2026-01-06 0 阅读
0

使用 TailwindCSS 实现移动响应式表格

使用 TailwindCSS 实现移动响应式表格

最近我和一位高级软件工程师结对编程,我们当时正在开发的一个项目是实现一个用户列表的设计,列表中会显示用户的相关数据。设计图大致如下:

图片描述

我们也知道我们希望它能够响应移动设备,尽管我们当时并没有任何相关的设计稿。

无障碍问题

我们最初尝试使用描述列表 dl来构建它dt,该列表定义了术语/名称,并对dd每个术语/名称进行了描述。实际上,我们用这种方法已经非常接近设计目标了,但随后我们使用屏幕阅读器来测试用户体验。结果充其量是繁琐,最坏的情况是根本无法使用。问题在于,这实际上是一个表格数据列表;即使从设计和缺少传统标题来看,它并不像表格数据。屏幕阅读器读取每个定义的方式是先读术语,再读描述。这意味着信息被分割开来,用户无法滚动浏览电子邮件列表,而是必须逐个阅读描述列表才能找到特定的电子邮件。而使用table标签时,屏幕阅读器可以逐列读取数据,用户体验要好得多。

搭建桌子

因此,我们放弃了描述列表,并使用 HTMLtable元素构建了它,这样既可以sr-only对视觉用户隐藏标题,又能为屏幕阅读器提供重要信息。

拿到表格数据后,我们开始设置每个单元格的样式td

  <table>
    <thead class="sr-only">
      <tr>
        <th>Name</th>
        <th>Email</th>
        <th>Company</th>
        <th>Status</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td class="px-4 py-3 text-gray-900 bg-gray-200 first:rounded-tl-lg first:rounded-bl-lg last:rounded-tr-lg last:rounded-br-lg">Frodo Baggins</td>
        <td class="px-4 py-3 text-gray-900 bg-gray-200 first:rounded-tl-lg first:rounded-bl-lg last:rounded-tr-lg last:rounded-br-lg">fbaggins@mail.com</td>
        <td class="px-4 py-3 text-gray-900 bg-gray-200 first:rounded-tl-lg first:rounded-bl-lg last:rounded-tr-lg last:rounded-br-lg">Fellowship of the Ring</td>
        <td class="px-4 py-3 text-gray-900 bg-gray-200 first:rounded-tl-lg first:rounded-bl-lg last:rounded-tr-lg last:rounded-br-lg">Active</td>
      </tr>
    </tbody>
  </table>
Enter fullscreen mode Exit fullscreen mode

我们的想法是,我们希望每个单元格都能重用这些类,所以我们使用 ` firstand`last修饰符来针对第一列的左上角和左下角以及最后一列的右上角来调整边框的圆角。

图片描述

要为“Active”添加类似标签的样式,我们将其包裹在 span 标签中:

<span class="float-right rounded-md bg-green-600/50 px-4 py-px text-xs font-semibold uppercase text-green-900 antialiased">Active</span>
Enter fullscreen mode Exit fullscreen mode

图片描述

此时我们想添加更多行,但不想继续重复使用已重用的类。我们当时正在开发一个 Phoenix LiveView 应用,所以创建了组件。为了专注于 Tailwind 框架,我将把已重用的类提取到 CSS 文件中并使用它们@apply

CSS:

@tailwind base;
@tailwind components;
@tailwind utilities;

.td-class {
  @apply px-4 py-3 text-gray-900 bg-gray-200 first:rounded-tl-lg first:rounded-bl-lg last:rounded-tr-lg last:rounded-br-lg
} 
Enter fullscreen mode Exit fullscreen mode

HTML:

<table class="">
  <thead class="sr-only">
    <tr>
      <th>Name</th>
      <th>Email</th>
      <th>Company</th>
      <th>Status</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td class="td-class">Frodo Baggins</td>
      <td class="td-class">fbaggins@mail.com</td>
      <td class="td-class">Fellowship of the Ring</td>
      <td class="td-class">
        <span class="float-right rounded-md bg-green-600/50 px-4 py-px text-xs font-semibold uppercase text-green-900 antialiased">Active</span>
      </td>
    </tr>
  </tbody>
</table>
Enter fullscreen mode Exit fullscreen mode

现在我们可以轻松添加更多行并开始设置表格样式。我们需要在每行之间添加一些间距,这可以使用 Tailwind 的表格边框间距属性来实现。我们还要将文本大小设置为默认的小号,并将表格包裹在一个 div 元素中,以便使用 flex 布局将其居中。

<div class="flex items-center justify-center">
  <table class="text-sm border-separate border-spacing-y-2">
    <thead class="sr-only">
      <tr>
        <th>Name</th>
        <th>Email</th>
        <th>Company</th>
        <th>Status</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td class="td-class">Frodo Baggins</td>
        <td class="td-class">fbaggins@mail.com</td>
        <td class="td-class">Fellowship of the Ring</td>
        <td class="td-class">
          <span class="float-right rounded-md bg-green-600/50 px-4 py-px text-xs font-semibold uppercase text-green-900 antialiased">Active</span>
        </td>
      </tr>

      <tr>
        <td class="td-class">Bilbo Baggins</td>
        <td class="td-class">bbaggins@mail.com</td>
        <td class="td-class">Thorin’s Fellowship</td>
        <td class="td-class">
          <span class="float-right rounded-md bg-green-600/50 px-4 py-px text-xs font-semibold uppercase text-green-900 antialiased">Active</span>
        </td>
      </tr>
    </tbody>
  </table>
</div>
Enter fullscreen mode Exit fullscreen mode

图片描述

我们还需要添加用户状态为“待定”或“已暂停”时的标签,所以让我们添加一些示例。

<div class="flex items-center justify-center">
  <table class="border-separate border-spacing-y-2 text-sm">
    <thead class="sr-only">
      <tr>
        <th>Name</th>
        <th>Email</th>
        <th>Company</th>
        <th>Status</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td class="td-class">Frodo Baggins</td>
        <td class="td-class">fbaggins@mail.com</td>
        <td class="td-class">Fellowship of the Ring</td>
        <td class="td-class">
          <span class="float-right rounded-md bg-green-600/50 px-4 py-px text-xs font-semibold uppercase text-green-900 antialiased">Active</span>
        </td>
      </tr>

      <tr>
        <td class="td-class">Peregrin Took</td>
        <td class="td-class">pippin@mail.com</td>
        <td class="td-class">Fellowship of the Ring</td>
        <td class="td-class">
          <span class="float-right rounded-md bg-green-600/50 px-4 py-px text-xs font-semibold uppercase text-green-900 antialiased">Active</span>
        </td>
      </tr>

      <tr>
        <td class="td-class">Bilbo Baggins</td>
        <td class="td-class">bbaggins@mail.com</td>
        <td class="td-class">Thorin’s Company</td>
        <td class="td-class">
          <span class="float-right rounded-md bg-yellow-600/50 px-4 py-px text-xs font-semibold uppercase text-yellow-900 antialiased">Pending</span>
        </td>
      </tr>
      <tr>
        <td class="td-class suspended-text">Boromir of Gondor</td>
        <td class="td-class suspended-text">boromir@mail.com</td>
        <td class="td-class suspended-text">Fellowship of the Ring</td>
        <td class="td-class">
          <span class="float-right rounded-md bg-red-600/50 px-4 py-px text-xs font-semibold uppercase text-red-100 antialiased">Suspended</span>
        </td>
      </tr>
    </tbody>
  </table>
</div>
Enter fullscreen mode Exit fullscreen mode
.suspended-text {
  @apply text-gray-500
}
Enter fullscreen mode Exit fullscreen mode

图片描述

对于状态为“已暂停”的行,文本颜色为较浅的灰色。由于当前颜色来自 CSS 文件,并且是 `<style>` 标签的一部分td-class,因此我们需要添加另一个类,以便在 CSS 编译时将其覆盖为“已暂停”的文本颜色。CSS 文件中的 CSS 会在内联实用类之后编译。因此,如果您尝试使用 `<style>` 标签td-class text-gray-500,它仍然会渲染为 `<style>` 标签text-gray-900。这就是为什么强烈建议您将重用的类组件化,而不是使用 `<style>` 标签的原因之一@apply

太棒了!这看起来和我们拿到的设计稿非常接近!但是,如果把它缩小到手机屏幕尺寸,效果就不太好,而且有些文字还会被截断。

图片描述

我们来解决这个问题!我们会简化界面,让每一行都更易于阅读。

使表格能够响应移动设备

为了防止文本在前面被截断,我们sm:justify-center给包含 div 添加一个断点和一些边距。

<div class="flex items-center sm:justify-center ml-4 sm:ml-0">
Enter fullscreen mode Exit fullscreen mode

我们class="tr-class"向表格的每一行添加元素,并将其设置为具有列方向的弹性容器,以便每张卡片内的信息可以彼此堆叠,并且每张卡片之间留有一定的边距。

.tr-class {
  @apply flex flex-col mb-4
}
Enter fullscreen mode Exit fullscreen mode

图片描述

td-class由于我们在第一版中实现的边框圆角,它看起来有点滑稽,我们需要针对移动设备尺寸调整圆角。

.td-class {
  @apply px-4 py-3 bg-gray-200 first:rounded-t-lg last:rounded-b-lg
} 
Enter fullscreen mode Exit fullscreen mode

图片描述

这样看起来好多了!但是如果调整到平板电脑或桌面尺寸,它仍然保持卡片式布局,而不是扩展成长行。我们需要sm:table-row在 `<div>` 标签中添加一个断点tr-class。这样就可以显示布局table-row,使其行为与添加 flex 属性之前一样。

.tr-class {
  @apply flex flex-col mb-4 sm:table-row
}
Enter fullscreen mode Exit fullscreen mode

现在它像以前一样扩展到了每一行!最后,我们需要重新实现表格边缘的圆角,这次使用断点。

顺便提一下,这就是为什么如果条件允许,强烈建议您先针对最小屏幕进行设计,然后再逐步增加屏幕尺寸。反过来做会稍微复杂一些,但由于我们只有一套设计稿,所以选择了这种方法。

sm我们首先在达到断点时移除顶部和底部的边框圆角sm:last:rounded-b-none sm:first:rounded-tl-lg。然后,我们再添加原来的圆角。

.td-class {
  @apply px-4 py-3 bg-gray-200 first:rounded-t-lg last:rounded-b-lg sm:first:rounded-t-none sm:last:rounded-b-none sm:first:rounded-tl-lg sm:first:rounded-bl-lg sm:last:rounded-tr-lg sm:last:rounded-br-lg
}
Enter fullscreen mode Exit fullscreen mode

图片描述

就这样!一个对屏幕阅读器友好且响应迅速的数据列表就完成了。要尝试不同的样式并查看最终的代码效果,您可以查看这个Tailwind Play 示例

资源

Tailwind 组件
Tailwind 文档

文章来源:https://dev.to/meksquest/mobile-responsive-table-with-tailwindcss-57db