tailwind1-3 Exercise 3: A Hero Banner, and the Overlay Trap
============================================================
The banner. The overlay is an empty element; the heading is a sibling, not a child, so it is not affected by the overlay's colour:
relative (on the section) makes it the reference box for the overlay
absolute inset-0 stretches the overlay over the whole section
bg-black/40 black at 40%: darkens the gradient without hiding it
relative (on the heading) a positioned element later in the page paints above the overlay; without it the overlay would cover the text
(measured: with relative the brightest pixel of the heading was pure white, 255,255,255; with the class removed it was
153,153,153, the overlay's grey, because the overlay was painted over the text)
Print the gradient and the overlay colour:
console.log(getComputedStyle(document.getElementById('hero')).backgroundImage);
console.log(getComputedStyle(document.getElementById('overlay')).backgroundColor);
Output (measured in headless Chrome):
linear-gradient(to right, oklch(0.715 0.143 215.221) 0%, oklch(0.623 0.214 259.815) 50%, oklch(0.511 0.262 276.966) 100%)
oklab(0 0 0 / 0.4)
The wrong overlay: the text sits INSIDE an element that is faded with opacity:
Hello
Computed values do not show the problem (the text's own opacity still reads 1), so measure the pixels. Two boxes on a white page, the same amber heading in each:
A: ... heading inside ...
B: ... heading inside ...
Take a screenshot and read the most common colour in each box (the background) and the most amber pixel (the text). With Python and Pillow:
from PIL import Image
im = Image.open('shot.png').convert('RGB')
def region(y0, y1):
px = [im.getpixel((x, y)) for y in range(y0, y1) for x in range(0, 600)]
return max(set(px), key=px.count), max(px, key=lambda p: p[0] + p[1] - p[2])
print('A', region(5, 120)); print('B', region(133, 250))
Output (measured):
A background (153, 153, 153) text (255, 210, 48)
B background (153, 153, 153) text (255, 236, 171)
WHY THIS WORKS AS AN ANSWER
---------------------------
bg-black/40 changes the alpha of one colour: the box background becomes 40% black, nothing else changes, and the text keeps its full amber (255, 210, 48).
opacity-40 changes the whole element as a group: the black background AND the heading are drawn together and then the result is made 40% opaque. The box ends up
the same grey (153, 153, 153) because 40% black over white is the same either way, but the text is now mixed 60% with the white page behind it, so a vivid amber
becomes a pale cream (255, 236, 171). For white text on a dark overlay the damage is less obvious, which is why this mistake survives; with any other colour it is
plain.
The rule: put the fade on a colour (the slash form) or on an empty overlay element, and keep text in a separate element that is painted above it.