GDPR Art. 4(11) requires consent to be 'freely given' — a standard the CNIL (FR), ICO (UK), and Belgian DPA have each applied to banner design, finding that visually suppressed reject buttons constitute coercive design that vitiates free choice. Dark patterns documented by regulators include: ghost-styled reject buttons next to primary-styled accept buttons, reject paths buried behind multi-step preference dialogs, and labels like 'I understand' that conflate dismissal with acceptance. Data collected via these patterns has been ruled to lack valid consent under ePrivacy Art. 5(3).
High because regulators in multiple EU jurisdictions have explicitly ruled that asymmetric button prominence constitutes a dark pattern that invalidates consent under GDPR Art. 7(4) and Art. 4(11).
Match accept and reject button styles exactly — same variant, same font weight, same padding. The reject action must also be reachable in the same number of clicks as accept.
// WRONG — different visual weight
<button className="bg-blue-600 text-white px-4 py-2 rounded font-semibold">Accept All</button>
<button className="text-gray-400 text-sm underline">Reject All</button>
// CORRECT — equal prominence
<button className="bg-blue-600 text-white px-4 py-2 rounded font-semibold">Accept All</button>
<button className="bg-white text-gray-900 border border-gray-300 px-4 py-2 rounded font-semibold">Reject All</button>
If 'Accept All' is a one-click button on the main banner, 'Reject All' must also be a one-click button on the main banner — not a path through 'Manage preferences → uncheck all → Save'.
ID: cookie-consent-compliance.banner-ux.no-dark-patterns
Severity: high
What to look for: Read the banner component's JSX/HTML and CSS. This check requires visual analysis of the rendered output — if you have access to a running instance or screenshot, compare button prominence directly. Look for these specific dark patterns in the code: (1) Accept button uses a prominent primary style (bg-blue-600, variant="default", bold text) while Reject uses a ghost, text-only, or secondary style (variant="ghost", text-gray-400, text-xs) — same label hierarchy but different visual weight, (2) Reject/Decline option is placed in a separate "Settings" panel that requires extra clicks to reach while Accept All is a single click, (3) reject-all path requires the user to navigate to a settings page and save, while accept-all is a one-click button on the main banner, (4) buttons are labeled deceptively (e.g., "I understand" instead of "Accept all," or "Continue" for accept while "Learn more" hides the reject path), (5) banner uses countdown timers implying consent expires if no action is taken. Regulators in the EU (CNIL, ICO) specifically enforce that the reject mechanism must be as easy as the accept mechanism — one click for accept means one click for reject.
Pass criteria: List all consent UI buttons and their visual styling. Accept and reject actions are equivalent in prominence, number of clicks, and visual weight. Button labels clearly describe the action. No visual manipulation that implies rejecting will break the site or is the "wrong" choice. No countdown timers or artificial urgency. The reject/decline button must be at least 80% the visual prominence of the accept button.
Fail criteria: Must not pass when the reject button is visually less prominent than the accept button (smaller, lighter, or hidden behind a "manage" link). Reject button is visually de-emphasized (ghost, smaller text, grey color) compared to a bold primary Accept button. Reject requires more clicks than accept (e.g., accept is a main-banner button; reject requires opening a preferences panel and unchecking and saving). Button labels are deceptive or misleading.
Skip (N/A) when: No consent banner exists (already failing at banner-first-visit).
Detail on fail: Specify the dark pattern found. Example: "Accept All uses primary button styling (bg-blue-600). Reject All uses ghost/text styling with no background. Different visual weights violate equal prominence requirement." or "Accept is a one-click button on the banner. Reject requires opening 'Manage preferences', unchecking categories, and clicking Save — three extra interactions.".
Remediation: Ensure accept and reject use identical button variant and sizing:
// WRONG — different visual prominence
<button className="bg-blue-600 text-white px-4 py-2 rounded font-semibold">
Accept All
</button>
<button className="text-gray-400 text-sm underline">
Reject All
</button>
// CORRECT — equal visual prominence
<button className="bg-blue-600 text-white px-4 py-2 rounded font-semibold">
Accept All
</button>
<button className="bg-white text-gray-900 border border-gray-300 px-4 py-2 rounded font-semibold">
Reject All
</button>
Both actions must be reachable in the same number of clicks from the banner's initial state. It is acceptable to show "Accept All" / "Reject All" / "Preferences" as three equally styled buttons on the banner. It is not acceptable to have "Accept All" as the only prominent banner button.