Generate tints and shades on Mac from a hex color
TeenyTool mixes each RGB channel toward white or black in ten 10% steps. The output is predictable, but it is not HSL lightness, a perceptual scale, or an accessibility decision.
Paste a three- or six-digit hex color, then choose from ten tints and ten shades. For a tint, TeenyTool moves each red, green, and blue channel toward 255. For a shade, it moves each channel toward 0. Each row advances by 10%, and the last result is white or black.
Use the grid to produce candidates for one named UI state. Check the chosen foreground/background pair numerically, then inspect the rendered state. A monitor profile can change appearance, but it does not change the source hex values or the calculation.
Disclosure: I build teenytool. The behavior below comes from the current local Swift source for TintShadeView and ColorMath, not from a generic description of tint generators.
Quick answer
| Decision | Use a tint when... | Use a shade when... |
|---|---|---|
| Text or icon needs more lift | The color is too dark on a dark background. | The color is too bright on a light background. |
| Border or separator needs definition | The line is lost against a dark surface. | The line looks too loud against a light surface. |
| Hover or selected state needs hierarchy | The state needs to read as active without changing hue. | The state needs to feel pressed or receded. |
| Dark mode repair | A foreground value needs a lighter candidate. | A background or accent needs a darker candidate. |
01Replace the random starting color
A tint and shade pass should begin with a known color, not with a guess. Copy the value from the design token, the codebase, or a local screen sample. Write down the role before generating variants.
The Tint & Shade view seeds a random base color when it opens. Replace it before reviewing the grid. The shared parser accepts three- or six-digit hex with or without #; invalid input produces no generated values. Output uses uppercase six-digit hex with a # prefix.
If the value came from a rendered screen or screenshot, sample it first with TeenyColor. The related TeenyColor guide explains how to check dark mode colors from screenshots before you generate replacement candidates.
02Read the RGB interpolation rule
For a base channel c and step fraction f, a tint is round(c + (255 - c) × f). A shade is round(c × (1 - f)). TeenyTool applies the formula separately to all three channels for f = 0.1 through 1.0.
This is straight RGB interpolation. It does not rotate hue, set HSL lightness, preserve a perceptual distance between steps, or promise that adjacent swatches will look equally different. The simplicity is useful when the handoff needs repeatable math rather than a full palette system.
The 100% tint is #FFFFFF, and the 100% shade is #000000. Those endpoints usually prove the rule; they are rarely the right component token.
03Work through one hex example
For base color #33506B, TeenyTool produces these selected steps. The app also shows the omitted 20%, 40%, 60%, 80%, and 100% results.
| Mix | Tint toward white | Shade toward black |
|---|---|---|
| 10% | #47627A | #2E4860 |
| 30% | #708597 | #24384B |
| 50% | #99A8B5 | #1A2836 |
| 70% | #C2CBD3 | #0F1820 |
| 90% | #EBEEF0 | #05080B |
Recomputing one row is a useful acceptance check. At 50%, the red channel becomes round(51 + (255 - 51) × 0.5) = 153, or 99 in hex. The other two channels follow the same rule.
04Pick a candidate for one state
Do not solve every color problem at once. Pick one state: disabled label on dark card, hover background, selected row, warning icon, focus ring, subtle border, secondary button text.
Choose the tint or shade that solves that state with the smallest reasonable change. If a color only needs a little more separation, a nearby step is usually easier to defend than a dramatic jump.
For dark mode, this is especially important. A bright tint can pass contrast and still feel harsh in a dense interface. A deep shade can look polished and still fail to communicate state. Test the candidate in context.
05Check contrast before you call it fixed
Tints and shades are visual candidates. They are not accessibility evidence by themselves. If the candidate touches text, icons, borders, focus indicators, controls, or meaningful chart marks, check the actual foreground/background pair.
TeenyTool includes a local Contrast Checker for that next step. WCAG 2.2 sets Level AA text contrast at 4.5:1 for normal text and 3:1 for large text. Non-text UI components and graphical objects need their own check.
The companion guide on WCAG contrast ratios on Mac covers the thresholds. Use this tint and shade workflow to find candidates, then use the contrast workflow to reject weak ones.
06Send the reason with the value
A bare hex value is easy to misunderstand. Send the role, state, original value, candidate value, and reason for the change. That context keeps the review from turning into a palette debate.
A useful note looks like this: dark mode focus ring on settings card, original #33506B, candidate #5E82A8, chosen because the original disappears against #17202B. Contrast still needs approval in the final component.
The TeenyApps Mac color tools workflow separates source values, generated candidates, contrast math, and display appearance. Use it when the tint or shade is part of a handoff, not just a color exercise.
07Check display appearance separately
A generated hex value is the same source value on every screen, but it may not look the same. If the candidate appears washed out, too warm, or unexpectedly flat on one external monitor, record that monitor's active profile and picture mode before changing the token again.
The Mac external monitor color-profile guide covers the profile, ColorSync details, monitor controls, HDR, and connection path. Fixing a display mismatch and fixing a contrast failure are different jobs.
Mac tint and shade checklist
- Replace the random starting color with a known hex value from the source, design file, or rendered screen.
- Name the UI role and state before generating variants.
- Generate the ten RGB mixes toward white and the ten mixes toward black.
- Choose one candidate for one specific UI state.
- Copy the candidate hex value.
- Check contrast against the real foreground or background pair.
- Check the display profile separately if the same values look different by monitor.
- Send the role, state, original value, candidate value, method, and reason for the change.
- Let the design system or codebase own the final token.
Where tints and shades help
| Use case | Candidate to try | Still check |
|---|---|---|
| Dark mode label is too dim | A lighter tint of the current label color. | Text contrast against the exact background. |
| Focus ring gets lost | A brighter tint or more separated shade from the accent. | Non-text contrast and focus visibility around the component. |
| Hover state is too subtle | A nearby tint or shade that preserves the hue family. | Whether hover, selected, and disabled states remain distinct. |
| Border is too loud | A softer tint or shade that keeps separation without shouting. | Whether the border is decorative or meaningful. |
Sources checked
- TeenyTool claims were checked against the TeenyTool homepage and local Swift source for
TintShadeView.swift,ColorMath.swift,ContrastCheckerView.swift, and the color tool inventory. - Apple Human Interface Guidelines: Color.
- Apple Human Interface Guidelines: Dark Mode.
- W3C WCAG 2.2 Success Criterion 1.4.3 Contrast (Minimum).
- W3C WCAG 2.2 Success Criterion 1.4.11 Non-text Contrast.
- TeenyApps Mac color tools workflow for separating source values, generated candidates, contrast calculations, and display appearance.
- Apple Support: Change your Mac display's color profile for the separate display-appearance check.
- TeenyColor dark mode screenshot color guide for collecting the sampled base color first.
FAQ
How do you generate tints and shades from a hex color on Mac?
Use a local tint and shade generator, paste the base hex value, review lighter tints and darker shades, copy one candidate, then check it against the actual UI background before handoff.
What is the difference between a tint and a shade?
A tint moves a base color toward white. A shade moves a base color toward black. In UI work, both are candidates until they are tested in the real state.
Can a tint or shade fix a dark mode contrast problem?
Sometimes. A tint or shade can produce a better candidate, but the candidate still needs to be checked against the actual foreground or background pair and reviewed in context.
How does TeenyTool calculate tints and shades?
For each 10% step, TeenyTool linearly mixes every RGB channel toward 255 for a tint or toward 0 for a shade, rounds the channel values, and formats the result as uppercase hex. It does not adjust HSL lightness or create a perceptually uniform scale.
Generate one candidate, then prove where it works.
teenytool keeps tint and shade generation and contrast checking on the Mac. The design token, specified pair, and display context still own the decision.