How cookie banners nudge you
Why it matters Cookie banners are where you decide whether a site may track you, and many are designed so that "yes" is easy and "no" is hard. Once you can name the tricks, they lose most of their power, and you will click "Reject" in seconds instead of giving up.
Dark pattern: a design that steers you into a choice you would not make if the options were presented fairly. Think of a supermarket that puts sweets at child height by the till, but for clicks.
Cookie banner (consent banner): the box many sites show on your first visit, asking whether they may use cookies and trackers for things like ads and analytics.
Five tricks to spot
- Hidden reject: the first screen offers "Accept all" and "Manage options" or "Settings", but no "Reject". Saying no takes several more clicks.
- Uneven buttons: "Accept" is big, bright and button-shaped; "Reject" is small, grey, or looks like plain text.
- Pre-ticked boxes: inside the options, switches for ads or "partners" are already on, so doing nothing means yes.
- Guilt trip: the "no" option is worded to make you feel silly, such as "No thanks, I like paying full price".
- Loads before you choose: trackers start working the moment the page opens, while the banner is still asking.
The five practice banners
Before any code, mark these by eye. For each banner, write down which of the five tricks it uses. You can check your answers when you run the code.
| Banner | "Reject" on first screen? | Accept looks like | Reject looks like | Pre-ticked | Guilt-trip wording? | Trackers load before you choose? |
|---|---|---|---|---|---|---|
| shopa.example | No, only "Manage options" | big green button | small grey link | ads, analytics | No | Yes |
| news.example | Yes | big green button | plain text button | none | No | No |
| recipes.example | Yes: "No thanks, I like boring recipes" | plain button | plain button | personalised ads | Yes | No |
| games.example | No | flashing button | small grey link | ads, partners | Yes | Yes |
| library.example | Yes | plain button | plain button | none | No | No |
Notice that the last column is the one you cannot see on the banner itself. You would need the DevTools Network tab (from the third-party scripts lesson) to notice trackers loading before you answer.
Turning your marks into rules
Each trick becomes a simple yes-or-no rule. In Python, a banner is a dict (a set of labelled values, like a form: banner["guilt_trip"] reads the value labelled guilt_trip), the five banners sit in a list (a row of things in square brackets), and each rule is an if. For example, the hidden-reject rule reads "if Reject is not on the first screen, add hidden reject to the list":
found = []
if not banner["reject_on_first_screen"]:
found.append("hidden reject")A few pieces of Python you will need. not flips True and False. != means "is not equal to". len(a_list) > 0 is True when a list has something in it. found.append(x) adds x to the end of the list found. If you have not coded before, the starter has the first rule done for you, and the hints show the rest.
Try it Next time a banner appears on a real site, run through the five tricks in your head before you click. If there is no "Reject" on the first screen, look for "Manage options", untick everything that is not "strictly necessary", and save. It takes about ten seconds once you know where to look.
In other languages
The same rules in JavaScript, as a site's test suite might check its own banner:
function findDarkPatterns(banner) {
const found = [];
if (!banner.rejectOnFirstScreen) found.push("hidden reject");
if (banner.acceptStyle !== banner.rejectStyle) found.push("uneven buttons");
if (banner.preTicked.length > 0) found.push("pre-ticked boxes");
if (banner.guiltTrip) found.push("guilt trip");
if (banner.trackersBeforeChoice) found.push("loads before you choose");
return found;
}And in PHP, a common language for website back ends:
function find_dark_patterns(array $b): array {
$found = [];
if (!$b["reject_on_first_screen"]) $found[] = "hidden reject";
if ($b["accept_style"] !== $b["reject_style"]) $found[] = "uneven buttons";
if (count($b["pre_ticked"]) > 0) $found[] = "pre-ticked boxes";
if ($b["guilt_trip"]) $found[] = "guilt trip";
if ($b["trackers_before_choice"]) $found[] = "loads before you choose";
return $found;
}Recap
- Five common tricks: hidden reject, uneven buttons, pre-ticked boxes, guilt trips, and tracking before you choose.
- Each trick can be written as a simple yes-or-no rule.
- The worst trick is invisible on the banner: trackers loading before you answer.
- When "Reject" is missing, "Manage options" plus unticking everything usually gets you there.
Complete find_dark_patterns(banner) so it returns a list of the dark patterns a banner uses, using the exact names in PATTERNS: add "hidden reject" if reject_on_first_screen is False, "uneven buttons" if accept_style differs from reject_style, "pre-ticked boxes" if the pre_ticked list is not empty, "guilt trip" if guilt_trip is True, and "loads before you choose" if trackers_before_choice is True. Then complete worst_banner(banners) so it returns the name of the banner with the most patterns; if two tie, return the first one.
This lesson is locked
Lessons open one at a time. Finish the previous lesson to unlock this one.