[Discussion] Costs / Benefits of migrating to Tailwind #10988
Replies: 6 comments 8 replies
-
Starting it off... Benefits of Hydrogen:
Benefits of Tailwind
Important features of HydrogenThese are features of Hydrogen we already use, and I'd want them to be similarly easy to do in Tailwind before considering switching:
Open QuestionsI don't know the answers to these questions, but if we did they might sway us one way or the other:
Amount of WorkI don't know the answers to these questions either, and they're some of the most important. For reference, @esizer was investigating what it would be like to switch, and has an in-progress branch at https://github.com/GCTC-NTGC/gc-digital-talent/tree/tailwind-spike.
|
Beta Was this translation helpful? Give feedback.
-
Tailwind UpdatesSomething exciting is, tailwind is working on v4 with many nice improvements and aiming to be stable this summer (seems optimistic but would be nice).
Tools for tailwindcssThe nice thing is, tailwind is just class names so some of these tools are not tailwind specific but just make working with class names in component libraries easier. Editor/LintingThey have a prettier plugin (which also happens to work with other mentions here such as As well, there is an intellisense plugin that provides a lot of amazing features like autocomplete and hover previews of values. Utilities
I use these in combination to create a utility function to make working with classes much easier. This is a very common approach when developing with tailwind. Examplesimport { ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
const BaseComponent = ({ className, isActive }) => (
<div
className={
cn('bg-blue p-3 rounded', // Base styles
{ 'shadow': isActive }, // clsx will only apply this class if `isActive = true`
className // Allow overriding which will be merged with tw-merge
)}
/>
)
const ExtendedComponent = () => (
<div className="bg-red" isActive />
)
// Output
<div className="bg-red p-3 rounded shadow" /> VariantsThere are two options for handling variant components. However, neither is at v1 but, we could use Important FeaturesTheme supportTailwind has first party support for dark mode and it is very well documented. As far as themes go, while there is no first part support for it, it is trivial to implement with css variables (which will be even easier in v4 when they move to css first config). // Define your css vars
// NOTE: In v4 this will be the config so no need to duplicate in the standalone config file
@layer base {
:root {
--color-background: 245 248 253;
--color-primary: 155 71 255;
}
:root .dark {
--color-background: 47 49 61;
}
:root .iap {
--color-primary: 192 30 90;
}
} // Use them in the config
export default {
extend: {
colors: {
primary: `rgb(var(--color-primary) / <alpha-value>)`,
background: `rgb(var(--color-background) / <alpha-value>)`,
},
}
} StatesThey have full support for pseudo classes/elements (even list markers! 😁) <input className="invalid:border-error disabled:border-gray focus:border-blue" />
<ul clasName="marker:text-primary"> <!-- our markers are now our primary colour --> Child elementsPersonally, I prefer styling children directly. It makes it more explicit and puts the styles closer to where they are being applied. The main drawback of this is repeating the same classes but this is mainly mitigated via components. However, you can style children but also much, much more. Also, tailwind treats anything in brackets as plain css so you can write any selector you want (not that I encourage it 😅 ) // This abomination
<div class="[&>div[data-state="some-state"]:focus-visible:invalid]:bg-primary]" /> /* results in */
& > div[data-state="some-state"]:focus-visible:invalid {
background-color: var(--bg-primary);
} Open Questions
MigrationI don't think the effort the actual swap out the code would be that difficult. We could start by doing the The hardest part, as mentioned previously, the reviewing would not be fun and hopefully chromatic could save us a lot of headaches. |
Beta Was this translation helpful? Give feedback.
-
SyntaxHydrogen is more verbose, Tailwind is more concise. Hydrogen uses custom attributes, Tailwind uses classes. Hydrogen prioritizes using native CSS syntax where possible, while Tailwind has what is essentially its own abstracted language. Historically, as I understand it, our direction for nomenclature elsewhere in our code has been consistency and clarity over conciseness and convenience. Tailwind's approach arguably goes against this, as it requires us to learn its pseudo-language at the same time as abstracting class names away from being immediately obvious unless you're really familiar with Tailwind already. Tooling and utilitiesThis one is a no-brainer in favor of Tailwind, however it does also warrant discussion of the consequences of piling plugins onto Tailwind and what that actually looks like support-wise in practice. Hydrogen has a single point of failure right now, which is how quickly I can respond to a need or bug, whereas Tailwind + Merge + CSLX + PostCSS + the Vite plugin + whatever else we add on creates multiple points of failure and opportunities for bugs, delayed deployment of dependencies, etc. Theme support
This statement misunderstands the depth in how Hydrogen implements themes. If we use the IAP as an example, there are instances where our default Hydrogen on the other hand, let's you use your theme key as an override (this also applies to dark mode, and I'm not sure if Tailwind has something similar), where you can do something like This gets a lot more complicated when we get into custom hover/focus states per theme, or hiding/showing elements, etc. We need configurations for at minimum two themes, with both light and dark that behave slightly differently between them. Child elementsThis plays into both preference and practical file size and edit-ability. If you have to style the same Open questions
MigratingBeyond the dev work involved, we can't ignore the impact to the design team, as well as the design/dev handoff:
If there are any discrepancies, we'll need to be involved in figuring out the changes and what they affect - both because we then have to internalize that rule in Figma, and because we have to consider accessibility impacts. I'm not sure how the process would look, but we'd also need to review the PRs across modes and devices. Chromatic should catch a lot, but it definitely won't catch everything across modes, themes, and device sizes, so we'd need to be pretty thorough page-by-page, which is going to be time consuming. |
Beta Was this translation helpful? Give feedback.
-
@substrae Can you explain a bit more about these interlocked variables calculated by Hydrogen? |
Beta Was this translation helpful? Give feedback.
-
Nothing's been added here since last week, so here's how it seems to me.
In short, I think we should consider a migration to Tailwind to be in the backlog of debt work, but not a priority. We can revisit the idea after v4 releases, to start with. |
Beta Was this translation helpful? Give feedback.
-
Heard. Hydrogen support will stop, then, in the interim, unless critical bugs are found. Whether you are convinced of the collaboration impact of the framework or not, the points I've outlined above are still valid. As such, the requirements from the design team for the migration are as follows:
|
Beta Was this translation helpful? Give feedback.
-
I know there's been some interest in migrating from using Hydrogen as our design system to using Tailwind. I'm opening this up as a place to openly and frankly evaluate the potential reasons for moving to Tailwind, the reasons to keep using Hydrogen, and the amount of work it would take to switch.
Beta Was this translation helpful? Give feedback.
All reactions