ee.co.uk - Broken layout, elements missing or misaligned
Categories
(Web Compatibility :: Site Reports, defect, P1)
Tracking
(Webcompat Priority:P1, Webcompat Score:9, firefox155 unaffected, firefox156 affected, firefox157 affected)
| Tracking | Status | |
|---|---|---|
| firefox155 | --- | unaffected |
| firefox156 | --- | affected |
| firefox157 | --- | affected |
People
(Reporter: ctanase, Unassigned)
References
()
Details
(Keywords: webcompat:needs-diagnosis, webcompat:site-report, Whiteboard: [webcompat-source:product][autowebcompat:processed][autowebcompat:repro-success][webcompat:core])
User Story
autowebcompat-repro-status:success autowebcompat-repro-chrome-mask-fixed:false autowebcompat-repro-channels:nightly autowebcompat-repro-report-os:all autowebcompat-diagnosis-status:success platform:windows,mac,linux,android impact:site-broken configuration:general affects:all branch:release diagnosis-team:dom user-impact-score:2000
Attachments
(4 files)
Environment:
Operating system: Windows
Firefox version: Firefox 157.0a1 (nightly)
Preconditions:
- Clean profile
Steps to reproduce:
- Navigate to: https://ee.co.uk/
- Observe the page.
Expected Behavior:
Elements are displayed and aligned correctly.
Actual Behavior:
Elements are missing/misaligned.
Notes:
- Reproducible on the latest Firefox Beta and Nightly
- Reproducible regardless of the ETP setting
- Works as expected using Chrome and Firefox Release (155)
Created from webcompat-user-report:406ddd65-5a7c-48d7-845a-8535b0a2f8fd
Updated•2 months ago
|
Updated•2 months ago
|
Comment 1•2 months ago
|
||
On ee.co.uk the site header (<global-header>) renders unstyled in Firefox Nightly: the primary nav links (Phones, SIM-only, Broadband, TV & Sport, Gaming, Tech, Insurance, Brands) and the search/basket/account/menu icons stack vertically as full-width blocks instead of sitting in a horizontal bar, inflating the header and pushing the hero content far down the page. Chrome renders the same header correctly as a single compact horizontal row.
Comment 2•2 months ago
|
||
Updated•2 months ago
|
Updated•2 months ago
|
Updated•2 months ago
|
Updated•2 months ago
|
Updated•2 months ago
|
Updated•2 months ago
|
Comment 3•2 months ago
|
||
Root cause analysis generated by autowebcompat bot:
Firefox Nightly 157 wrongly matches the CSS :host pseudo-class against ordinary light-DOM elements when :host follows a combinator in a selector coming from a normal document stylesheet (one not in a shadow tree). Per CSS Scoping (https://drafts.csswg.org/css-scoping/#host-selector) :host matches only a shadow host, and only when its stylesheet is in a shadow tree; otherwise the rule is inert, as in Chrome and Firefox 155.
ee.co.uk loads https://ee.co.uk/exp/ge/global-elements.css via plain stylesheet links and the page uses no shadow DOM. That file contains the rule with selector "#global-elements-wrapper .global-nav-loop .global-nav-loop-v4 .lc-v4-24-0 :host" declaring display:block plus auto margins. In Firefox Nightly the trailing :host compound matches every element that is a descendant of .lc-v4-24-0, so all header elements get display:block at specificity 1 ID + 4 classes, which outranks the site's own unprefixed header rules .utility-bar, .nav-items__wrapper, .header-container and .primary-links (display:flex, 1 class). The header's flex containers therefore become block boxes: the nav links and icon buttons stack as full-width blocks and the header grows from ~194px to ~722px, pushing the hero content down. Rules in the same file that carry the full prefix (1 ID + 5 classes, e.g. .lc-Grid{display:flex}) still win, which is why only part of the header loses its layout.
The defect is confined to the styling path: Element.matches()/querySelectorAll() with the same selector return false/0 in Firefox, so CSSOM introspection disagrees with the computed style. A bare :host rule is correctly inert; only :host after a combinator (descendant, child, or the functional :host(.x) form) mis-matches. This is an engine regression, not UA sniffing: markup, stylesheets and network requests are identical in both browsers.
Evidence:
Live site at 1600x1000; identical DOM/classes and 80 stylesheets in both browsers, no console errors.
- Header height 722px in Firefox vs 194px in Chrome. Computed display of .utility-bar = block (FF) vs flex (Chrome); .nav-items__wrapper block vs flex. Yet align-items:center, justify-content:flex-end and padding 8px 0 12px from that same .utility-bar rule applied in both, so only
displaywas being overridden. - Recursive CSSOM enumeration (all 80 sheets, incl. media/import) of every rule matching .utility-bar returned an identical set in both browsers, whose only display declarations were display:flex (matching) and display:none in a non-matching max-width:1023px media query. No animations/transitions (getAnimations() empty), no inline style, no shadow root among ancestors, document.adoptedStyleSheets empty.
- Cascade probing in FF: injected selectors of 1 ID and of 1 ID + 8 types lost; 2 IDs, 1 ID + 5 classes, inline style and !important won — a hidden author-normal competitor near 1 ID + 4 classes was setting display:block. A fresh div.utility-bar computed flex in body but block inside the header.
- Offline reduction: local page with only the ancestor chain plus the real global-elements.css shows block in FF, flex in Chrome; delta-debugging its 1839 top-level rules isolated exactly "#global-elements-wrapper .global-nav-loop .global-nav-loop-v4 .lc-v4-24-0 :host { display:block; ... }".
- Live confirmation in FF: deleting the 4 rules whose selector contains :host changed header height 722px to 194px (exactly Chrome's), flipped .utility-bar to flex, and put nav links on one row (Phones x147 y126 w74, SIM-only x245, Broadband x351, TV & Sport x474) — the repro script's "working" state.
- FF probes: ".a :host", ".a > :host" and ".a :host(.b)" each restyle a plain light-DOM element; bare ":host", ".b:host" and ":host-context(.a)" do not; querySelectorAll for them returns 0.
- Reduced testcase /app/diagnosis/testcase=cqq4a1pl.html: Firefox Nightly 157 prints FAIL (computed display block, matches() false), Chrome prints PASS (display flex, children on one row).
Comment 4•2 months ago
|
||
Updated•2 months ago
|
Updated•2 months ago
|
Description
•