Report UI contrast bugs on Mac with color evidence
A useful contrast bug report separates what the screen rendered from the source colors that should be tested, then preserves the state and steps needed to reproduce both.
The short version: capture the exact UI state, record the source foreground and background when they are available, sample the rendered pixels as visual evidence, calculate the actual pair without rounding, name the WCAG criterion, and attach repeatable steps. If the question is only "does this sampled color work on white or black?", teenycolor can answer that quickly. If the real pair is custom, keep both values together and verify them in a pair checker.
This is narrower than a full accessibility audit. It is a bug-report workflow for the common Mac moment where someone says "this text is hard to read" or "this icon disappears in dark mode" and the next person needs proof of the rendered failure plus values that can be checked correctly.
Disclosure: I build teenycolor. The app is useful here because it samples rendered screen colors, copies values in practical formats, keeps local history, supports names and pins, and shows WCAG contrast badges against white and black. It does not replace testing every foreground/background pair in your design system.
Rendered evidence and conformance evidence
| Evidence | What it proves | Keep with it |
|---|---|---|
| Full-state screenshot | The observed mode, control state, scale, surrounding surface, and visual severity. | App build, macOS version, display context, and reproduction steps. |
| Rendered pixel samples | What appeared at selected interior pixels after compositing, color conversion, and rendering. | The exact UI role and a note that text-edge pixels are affected by anti-aliasing. |
| Source foreground and background | The color pair the author or user agent specifies for normal presentation. | Token, CSS, asset, or code reference plus alpha and underlying surface when relevant. |
| Unrounded ratio | Whether the specified pair meets the chosen numeric threshold. | The calculator, full input values, and criterion. |
| Role and criterion | Whether the issue concerns normal text, large text, an active control, a focus indicator, or meaningful graphics. | Text size and weight or the visual information the component must convey. |
01Capture the exact state before sampling
Contrast changes with state. Default, hover, pressed, selected, disabled, focused, warning, error, success, and loading states can all render different foreground or background colors. Light mode and dark mode add another split.
Take the screenshot before you start sampling. Apple's screenshot shortcuts are enough for this: capture the full screen when window, display, or mode context matters; capture a portion when the issue is local to a component. Name the file after the state, not the clock time. Record whether the capture came from a Retina display, an external monitor, or a scaled preview.
Open the screenshot at actual size before picking pixels. Sample a flat interior area for the foreground and background, not a text edge, drop shadow, or transparent blur. Apple's Digital Color Meter can reduce its aperture to a single pixel; a larger aperture averages every pixel inside it. The sampling choice belongs in the report when a one-pixel value and an averaged patch tell different stories.
02Sample foreground and background separately
A contrast ratio is a pair. If the report says only "#8E8EA0 fails", the reviewer still has to ask, "against what?" Include the text or icon color and the background color beneath it.
teenycolor uses macOS NSColorSampler, converts picked colors to sRGB, copies the selected format to the clipboard, and stores the pick in local history. That makes it fast to sample the foreground, sample the background, name both, and keep them ready for the issue comment.
Use names that survive handoff: "disabled label foreground", "settings card background", "warning icon", "selected row background". If the color uses opacity, blur, a gradient, or an image, the sampled pixel is the composited result. Also record the source value, alpha, and underlying surface when the developer needs to trace the cause.
If the color is a one-off sample, leave it in history. If it belongs in the bug report, pin it until the issue is resolved. TeenyColor history stores the sRGB components and alpha that the sampler returned, so a pinned pair is easier to recheck than two loose values in a chat.
03Use white and black badges as a first pass
TeenyColor's detail view shows contrast ratios against white and black. The Swift source calculates relative luminance, determines the badge from the unrounded ratio, and formats the visible ratio to one decimal place. That is useful for common cases: gray text on white, an accent used on black, or an icon that may need to work in both light and dark treatments.
Do not stretch that beyond what it is. If the real background is a card color, translucent material, gradient, image, selected row, or disabled surface, the white or black badge is only a fast warning. Sample the actual background and include the pair.
A good issue comment says both things: "TeenyColor shows this gray is Fail against white" and "the real sampled pair in the screenshot is foreground #8E8EA0 on background #FFFFFF." The first helps triage. The second makes the report reproducible. For a custom pair or a result close to a threshold, use a dedicated pair checker with the full input values.
04Separate observed pixels from conformance values
A rendered screenshot and a conformance calculation answer different questions. The screenshot proves what someone saw. The source foreground and background prove the pair the product specifies. W3C guidance says text contrast should be evaluated from the user agent or underlying markup and styles when those values are available because font smoothing and anti-aliasing can make edge pixels much fainter than the source color.
That does not make rendered sampling useless. A thin font can nominally pass from its source colors and still look faint in practice. Put both observations in the issue: the specified pair and ratio for the formal check, then the screenshot and interior samples for the visible failure. That gives the accessibility owner a valid calculation and gives the designer a reason to consider a stronger color or heavier type treatment.
Do not use a text-edge sample as the foreground input for the WCAG ratio. Anti-aliased edge pixels mix the text and background. If the source value is unavailable, label the screenshot sample as rendered evidence and ask the owner to confirm the actual token or style before calling it a conformance result.
05State the criterion and keep the full ratio
WCAG 2.2 Success Criterion 1.4.3 sets 4.5:1 for normal text and 3:1 for large-scale text at Level AA. Large-scale text is at least 18 point regular or 14 point bold, roughly 24 CSS pixels or 18.5 CSS pixels. Success Criterion 1.4.6 raises normal text to 7:1 for Level AAA. Non-text contrast has a separate 1.4.11 criterion for visual information needed to identify active controls, states, and meaningful graphics.
The report needs the role. "2.8:1" is not enough. Is it body text, large heading text, an active focus ring, a selected-state boundary, an inactive control, or a decorative icon? WCAG 1.4.3 exempts inactive interface components, so a disabled button is not the same claim as faint text in an active control.
Keep the calculator's full result. W3C treats 3:1 and 4.5:1 as thresholds and says not to round up: 4.499:1 does not meet 4.5:1. A one-decimal badge is useful for triage, but the bug report should keep the input colors and the calculator result used for the final decision.
For normal product bugs, keep the language plain: "Normal-size body text does not meet AA contrast in this state." The first job is to help the designer or developer reproduce and fix the state.
06Attach the repro and keep private UI local
A contrast report should not depend on an uploaded screenshot when the screen includes private customer data, unreleased UI, or internal dashboards. Sample locally, copy the values, and attach only the screenshot crop that the team is allowed to see.
Use this structure in the issue:
- Screen and state: Settings sidebar, dark mode, selected row.
- Repro: open Settings, switch to dark mode, select Team, hover the disabled Save button.
- Source pair: foreground and background tokens, CSS, asset, or code values when available.
- Rendered pair: interior foreground and background samples, labeled as observed pixels.
- Calculation: full input values, unrounded ratio, and checker used.
- Criterion: normal text AA, large text AA, AAA, or non-text contrast, including the UI role.
- Screenshot: cropped enough to prove the state.
- Expected result: readable text or visible control in that state.
For the broader cross-app evidence workflow, use the TeenyApps hub Mac bug report checklist for repro, evidence, and context.
If the contrast issue lives in a dashboard chart rather than an app control, use check dashboard chart colors on Mac so chart series, legends, labels, filter state, and screenshot evidence stay together.
If the contrast issue appears during a talk instead of inside an app bug report, use check presentation slide contrast on Mac. It separates source-pair conformance from rendered audience evidence and covers current PowerPoint checker limits.
Sources checked
- TeenyColor feature claims were checked against the TeenyColor homepage and local Swift source for
NSColorSampler, sRGB conversion, alpha storage, pasteboard copy, history, pinned colors, names, white/black contrast ratios, raw-ratio badge classification, and one-decimal ratio formatting. - Apple Support: Take a screenshot on Mac.
- Apple Support: Digital Color Meter User Guide for Mac for pixel selection, aperture averaging, color spaces, EDR values, and copy behavior.
- W3C: Understanding Success Criterion 1.4.3 Contrast (Minimum) for thresholds, source-color evaluation, anti-aliasing, unrounded ratios, and inactive-control exceptions.
- W3C: Understanding Success Criterion 1.4.11 Non-text Contrast.
- TeenyApps: Mac bug report checklist for the connected UI and performance evidence workflow.
FAQ
How do I report a UI contrast bug on Mac?
Capture the exact state, record the source foreground and background when available, sample the rendered colors as visual evidence, calculate the actual pair without rounding, name the WCAG criterion, and attach repeatable steps.
Can TeenyColor check every foreground and background pair?
TeenyColor shows WCAG contrast badges against white and black for each picked color. For arbitrary foreground and background pairs, sample both values and include the pair in the report.
Is a screenshot enough for a contrast bug?
No. A screenshot proves the observed rendering, but WCAG conformance should use the foreground and background colors defined by the user agent, markup, or styles when available because text anti-aliasing changes edge pixels.
Keep color evidence local.
teenycolor samples screen colors, copies nine formats, keeps local history, supports pins and names, and shows quick contrast badges against white and black.