SyntaxStudy
Sign Up
Tailwind CSS Dark Mode with Forms, Tables, and Charts
Tailwind CSS Beginner 1 min read

Dark Mode with Forms, Tables, and Charts

Forms require the most careful dark mode treatment because native form elements — inputs, selects, checkboxes, radios, textareas — have platform-specific default styles that may not respect custom CSS in all browsers. The @tailwindcss/forms plugin resets form element styles to a consistent baseline that is easy to customise, and it works well with dark mode since you control all the visual properties. Tables in dark mode follow the same surface layering principle: the table header uses a slightly different background from the body rows (bg-gray-700 vs bg-gray-800), alternating row backgrounds use even:bg-gray-800 and odd:bg-gray-750 (or rely on divide-y for row separation), and hover states use hover:bg-gray-700. The divide-y divide-gray-700 utility replaces border-bottom on individual rows, keeping the class list concise. When embedding third-party charts or visualisation libraries (Chart.js, D3, ApexCharts), you need to synchronise the dark mode state with the library's theme API. A common pattern is to observe changes to the html element's class list with a MutationObserver and update the chart configuration accordingly. For SVG-based illustrations inline in your HTML, replace hardcoded fill and stroke colors with currentColor so they inherit from the text-* utility and respond to dark mode automatically.
Example
<!-- Dark mode data table -->
<div class="overflow-x-auto rounded-xl border border-gray-200 dark:border-gray-700">
  <table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
    <thead class="bg-gray-50 dark:bg-gray-800">
      <tr>
        <th class="px-6 py-3 text-left text-xs font-semibold uppercase tracking-wider
                   text-gray-500 dark:text-gray-400">Name</th>
        <th class="px-6 py-3 text-left text-xs font-semibold uppercase tracking-wider
                   text-gray-500 dark:text-gray-400">Status</th>
        <th class="px-6 py-3 text-left text-xs font-semibold uppercase tracking-wider
                   text-gray-500 dark:text-gray-400">Amount</th>
      </tr>
    </thead>
    <tbody class="bg-white dark:bg-gray-900 divide-y divide-gray-100 dark:divide-gray-800">
      <tr class="hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors">
        <td class="px-6 py-4 text-sm text-gray-900 dark:text-gray-100">Alice</td>
        <td class="px-6 py-4">
          <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium
                       bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400">
            Active
          </span>
        </td>
        <td class="px-6 py-4 text-sm text-gray-900 dark:text-gray-100">$1,234</td>
      </tr>
      <tr class="hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors">
        <td class="px-6 py-4 text-sm text-gray-900 dark:text-gray-100">Bob</td>
        <td class="px-6 py-4">
          <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium
                       bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-400">
            Pending
          </span>
        </td>
        <td class="px-6 py-4 text-sm text-gray-900 dark:text-gray-100">$567</td>
      </tr>
    </tbody>
  </table>
</div>