Tuo kuvakaappaus on todellinen taideteos Meta-arkkitehtuurin hulluudesta
chat-kuplat ja tekstikentC$t hukkuvat tC$ysin pC$C$llekkC$in pinoutuvien
div-laatikoiden alle. Kun React-kehittC$jC$ keskittC$C$ yhden tekstin, siihen
kuluu usein viisi sisC$kkC$istC$ kC$C$rettC$, mikC$ tekee raa'asta
`div`-valitsimesta kC$yttC6kelvottoman.
Vaihda myC6s jatkossa `border` aina **`outline`**-ominaisuuteen. Border
kasvattaa elementin fyysistC$ kokoa, mikC$ rikkoo WhatsAppin herkC$n
flexbox-layoutin ja aiheuttaa kuvassa nC$kyvC$C$ elementtien puristumista.
Outline piirretC$C$n elementin pC$C$lle layoutia muuttamatta.
TC$ssC$ on kolme eri syvyyden strategiaa "haamudivien" karsimiseen:
**1. CSS `:has()` -valitsin (Leaf-node suodatus)**
Modernit selaimet tukevat `:has()`-pseudoluokkaa. Voimme kohdistaa tyylit vain
niihin `div`-elementteihin, jotka *eivC$t* sisC$llC$ toisia `div`-elementtejC$
(eli ns. lehtisolmuihin).
```python
valittu_sivu.add_style_tag(content="""
/* Kohdistetaan vain "pohjimmaisiin" diveihin ja interaktiivisiin
kontrolleihin */
div:not(:has(div)), button, input, textarea, a[role="button"] {
outline: 2px solid magenta !important;
outline-offset: -2px !important;
}
""")
```
**2. Semanttisten ARIA-roolien hyC6dyntC$minen (Tarkka-ampuja)**
WhatsApp on raskaasti saavutettavuusoptimoitu. Sen sijaan, ettC$ arvailemme
divejC$, voimme maalata suoraan ne elementit, joilla on oikea
kC$yttC6liittymC$merkitys. Esimerkiksi vasemman reunan chat-listaukset (kuten
"Triad Project") ja viestikentC$t on merkitty selkeillC$ rooleilla.
```python
valittu_sivu.add_style_tag(content="""
/* row = chat-rivit, textbox = syC6ttC6kentC$t, article = yksittC$iset
viestit */
[role="row"], [role="button"], [role="textbox"], [role="menuitem"],
[role="article"] {
outline: 2px solid magenta !important;
outline-offset: -2px !important;
}
""")
```
**3. JavaScript-suodatus tekstisisC$llC6n perusteella (ClykC$s injektio)**
Jos CSS ei riitC$ perkaamaan Metan loputtomia kC$C$reitC$, voimme ajaa
Playwrightin `page.evaluate()` -kutsulla pienen DOM-parserin juuri ennen
kaappausta. TC$mC$ maalaa vain ne elementit, joissa on oikeasti suoraa
tekstidataa (kuten tuo Triad Projectin tC$rkeC$ viesti CRM-rikastusmoottorista
ja `00_fetch_schools_db.py` -skriptistC$).
```python
# Aja tC$mC$ juuri ennen valittu_sivu.screenshot() -kutsua
valittu_sivu.evaluate("""
document.querySelectorAll('*').forEach(el => {
// HylC$tC$C$n scriptit, tyylit, SVG:t ja koko sivun kattavat
layout-divit
if (['SCRIPT', 'STYLE', 'SVG', 'PATH'].includes(el.tagName)) return;
// Tarkistetaan onko elementissC$ suoraa tekstidataa (ei vain
html-lapsia)
let hasDirectText = Array.from(el.childNodes).some(node =>
node.nodeType === Node.TEXT_NODE && node.nodeValue.trim().length >
0
);
// Maalataan elementti vain, jos siinC$ on tekstiC$ tai se on
interaktiivinen
if (hasDirectText || el.tagName === 'BUTTON' || el.tagName ===
'INPUT') {
el.style.outline = '2px solid magenta';
el.style.outlineOffset = '-2px';
}
});
""")
```