James McDonald, a professional designer and Tailwind team member, made a painfully accurate observation that designing for dark mode is a bastard.
So is there any hope for developers like me? I've got a decent eye for aesthetics, and I read Refactoring UI as much as the next dev, but I most definitely don't have any formal design training.
Well, for what it's worth, I wrote down what I think is hard about dark design, and some solutions I've leaned on in the past.
In the "Reusable Components" course, Michael Thiessen teaches six levels of reusability for Vue components.
I started to understand these levels more deeply once I noticed that each level relies on a specific Vue feature to unlock new possibilities.
Here's a cheatsheet:
Level of Reusability | Description | Vue feature |
---|
I dig the recent CSS tricks article about giving fair criticism to utility class frameworks.
But one criticism stood out to me as something that might not be completely fair:
"...seeing 10-20 classes on div after div gets in the way of what I’m trying to do..."
This is a super common gripe about utility CSS, including Tailwind. Critics generally agree that Tailwind pages are stuffed with super long class lists. In my personal experience with Tailwind, though, it never struck me as much of a problem.
If your reactive side effects aren't properly timed in a Vue app, you'll see very confusing behavior.
To fully understand Vue effect timing, you'd have to learn about microtasks in browser-based JavaScript. That said, a deep understanding of microtasks and of the browser event loop is really only practical for framework authors—it's not practical knowledge for framework users.
Instead of trying to learn how Vue effect timing actually works under the hood, try learning the following:
- Simplified versions of effect timing concepts
- Some opinionated guidelines on how to use the two effect timing tools at your disposal in Vue 3: the
flush
option forwatch
andwatchEffect
, andnextTick
.
v-model
is one of my favorite Vue features. It makes two-way data binding—the most useful feature of any reactivity framework, in my opinion—elegant and concise.
<!-- Seamlessly capture values from different types of HTML inputs -->
<template>
<input type="number" v-model.number="year" />
<select name="Choose month" v-model="month">...</select>
Ever since the gap
property for flexbox got wide browser support, I've stopped using margin
in almost all cases, because in my opinion, whitespace is a concern of parent elements, not their children.
When you use margin
on an element inside a flex container, you're telling the element or a component how much whitespace it should have around itself.
<!--
The paragraph and blockquote are aware that they have
siblings, and aware that they need to create distance.
Sometimes, when you're using Tailwind, you'll end up with some pretty long, difficult-to-read class lists for complex styling cases.
Many times, the solution is to abstract a new component class using a custom plugin, like I did in this project.
But that's usually not the first solution I reach for. I very much prefer:
- Sorting/writing classes based on their category (more on that below)
- Splitting categories across multiple lines
<script lang="ts"> | |
import { useNavigable } from 'path/to/useNavigable' | |
export default { | |
setup () { | |
const myImages = [...] | |
const { location, next, previous } = useNavigable(myImages) | |
return { |