Syllabus Lesson 28 of 156 · Consent, dark patterns and taking back control
Consent, dark patterns and taking back control

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 likeReject looks likePre-tickedGuilt-trip wording?Trackers load before you choose?
shopa.exampleNo, only "Manage options"big green buttonsmall grey linkads, analyticsNoYes
news.exampleYesbig green buttonplain text buttonnoneNoNo
recipes.exampleYes: "No thanks, I like boring recipes"plain buttonplain buttonpersonalised adsYesNo
games.exampleNoflashing buttonsmall grey linkads, partnersYesYes
library.exampleYesplain buttonplain buttonnoneNoNo

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.
Your turn

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.

Spotted a problem in this lesson? Report it

Code · runs in your browser
Output