axe-core
axe-core copied to clipboard
"Element midpoint exceeds the grid bounds"
Product
axe-core
Product Version
4.8.1
Latest Version
- [X] I have tested the issue with the latest version of the product
Issue Description
Expectation
Axe runs without errors on the following site: https://nefa-crypto-page.vercel.app/
Actual
When testing the desktop form factor, Axe throws a Element midpoint exceeds the grid bounds error for the color-contrast check.
How to Reproduce
Run axe-core on https://nefa-crypto-page.vercel.app/ with color-contrast enabled.
Additional context
https://github.com/GoogleChrome/lighthouse/issues/15619
Thanks for the issue. I'm unable to reproduce with Lighthouse in Chrome Devtools using Desktop device. I'm also unable to reproduce on any form factor running axe-core directly on the page. The only incomplete for axe-core I get are for background gradients.
{
"lighthouseVersion": "11.1.0",
"requestedUrl": "https://nefa-crypto-page.vercel.app/",
"mainDocumentUrl": "https://nefa-crypto-page.vercel.app/",
"finalDisplayedUrl": "https://nefa-crypto-page.vercel.app/",
"finalUrl": "https://nefa-crypto-page.vercel.app/",
"fetchTime": "2023-11-21T20:23:52.809Z",
"gatherMode": "navigation",
"runWarnings": [],
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
"environment": {
"networkUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36",
"hostUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
"benchmarkIndex": 2961,
"credits": {
"axe-core": "4.8.0"
}
},
"audits": {
"color-contrast": {
"id": "color-contrast",
"title": "Background and foreground colors do not have a sufficient contrast ratio.",
"description": "Low-contrast text is difficult or impossible for many users to read. [Learn how to provide sufficient color contrast](https://dequeuniversity.com/rules/axe/4.8/color-contrast).",
"score": 0,
"scoreDisplayMode": "binary",
"details": {
"type": "table",
"headings": [
{
"key": "node",
"valueType": "node",
"subItemsHeading": {
"key": "relatedNode",
"valueType": "node"
},
"label": "Failing Elements"
}
],
"items": [
{
"node": {
"type": "node",
"lhId": "1-0-BUTTON",
"path": "1,HTML,1,BODY,0,DIV,0,HEADER,0,NAV,1,DIV,0,BUTTON",
"selector": "header.fixed > nav.flex > div.hidden > button.border",
"boundingRect": {
"top": 27,
"bottom": 92,
"left": 536,
"right": 680,
"width": 144,
"height": 65
},
"snippet": "<button type=\"button\" class=\"border border-primary text-primary hover:bg-primary hover:text-white trans…\">",
"nodeLabel": "Log In",
"explanation": "Fix any of the following:\n Element has insufficient color contrast of 3.06 (foreground color: #468ef9, background color: #f6f9ff, font size: 13.5pt (18px), font weight: normal). Expected contrast ratio of 4.5:1"
},
"subItems": {
"type": "subitems",
"items": [
{
"relatedNode": {
"type": "node",
"lhId": "1-1-SECTION",
"path": "1,HTML,1,BODY,0,DIV,1,MAIN,0,SECTION",
"selector": "body > div#__next > main.overflow-hidden > section.bg-primary",
"boundingRect": {
"top": 0,
"bottom": 1134,
"left": 0,
"right": 1079,
"width": 1079,
"height": 1134
},
"snippet": "<section class=\"bg-primary bg-opacity-5 relative px-32 pt-72 pb-24\">",
"nodeLabel": "SIGN UP TODAY\nThe World’s\nFastest Growing\nCrypto Web App\n\nBuy and sell 200+ cry…"
}
}
]
}
},
{
"node": {
"type": "node",
"lhId": "1-2-BUTTON",
"path": "1,HTML,1,BODY,0,DIV,1,MAIN,0,SECTION,0,DIV,0,ARTICLE,4,DIV,1,DIV,0,BUTTON",
"selector": "article.static > div.col-span-2 > div.relative > button.border",
"boundingRect": {
"top": 900,
"bottom": 965,
"left": 372,
"right": 623,
"width": 251,
"height": 65
},
"snippet": "<button type=\"button\" class=\"border border-primary text-primary hover:bg-primary hover:text-white trans…\">",
"nodeLabel": "Download App",
"explanation": "Fix any of the following:\n Element has insufficient color contrast of 3.06 (foreground color: #468ef9, background color: #f6f9ff, font size: 13.5pt (18px), font weight: normal). Expected contrast ratio of 4.5:1"
},
"subItems": {
"type": "subitems",
"items": [
{
"relatedNode": {
"type": "node",
"lhId": "1-1-SECTION",
"path": "1,HTML,1,BODY,0,DIV,1,MAIN,0,SECTION",
"selector": "body > div#__next > main.overflow-hidden > section.bg-primary",
"boundingRect": {
"top": 0,
"bottom": 1134,
"left": 0,
"right": 1079,
"width": 1079,
"height": 1134
},
"snippet": "<section class=\"bg-primary bg-opacity-5 relative px-32 pt-72 pb-24\">",
"nodeLabel": "SIGN UP TODAY\nThe World’s\nFastest Growing\nCrypto Web App\n\nBuy and sell 200+ cry…"
}
}
]
}
},
{
"node": {
"type": "node",
"lhId": "1-3-A",
"path": "1,HTML,1,BODY,0,DIV,1,MAIN,1,SECTION,0,DIV,0,DIV,0,DIV,0,DIV,1,A",
"selector": "div.grid > div.px-5 > div.flex > a.text-primary",
"boundingRect": {
"top": 1080,
"bottom": 1112,
"left": 445,
"right": 517,
"width": 72,
"height": 32
},
"snippet": "<a class=\"text-primary cursor-pointer\" href=\"/#\">",
"nodeLabel": "More",
"explanation": "Fix any of the following:\n Element has insufficient color contrast of 3.23 (foreground color: #468ef9, background color: #ffffff, font size: 13.5pt (18px), font weight: normal). Expected contrast ratio of 4.5:1"
},
"subItems": {
"type": "subitems",
"items": [
{
"relatedNode": {
"type": "node",
"lhId": "1-4-DIV",
"path": "1,HTML,1,BODY,0,DIV,1,MAIN,1,SECTION,0,DIV",
"selector": "div#__next > main.overflow-hidden > section.-mt-20 > div.max-md:w-[max-content]",
"boundingRect": {
"top": 1044,
"bottom": 1943,
"left": 99,
"right": 980,
"width": 881,
"height": 899
},
"snippet": "<div class=\"max-md:w-[max-content] lg:container mx-auto rounded-3xl bg-white py-8 lg:p…\">",
"nodeLabel": "Trending\nMore\nName\nPrice\nChart\nBitcoin\n+\n$43,180.13\nEthereum\n-\n$3,480.65\nSolana…"
}
}
]
}
},
{
"node": {
"type": "node",
"lhId": "1-5-A",
"path": "1,HTML,1,BODY,0,DIV,1,MAIN,1,SECTION,0,DIV,0,DIV,1,DIV,0,DIV,1,A",
"selector": "div.grid > div.px-5 > div.flex > a.text-primary",
"boundingRect": {
"top": 1080,
"bottom": 1112,
"left": 868,
"right": 940,
"width": 72,
"height": 32
},
"snippet": "<a class=\"text-primary cursor-pointer\" href=\"/#\">",
"nodeLabel": "More",
"explanation": "Fix any of the following:\n Element has insufficient color contrast of 3.23 (foreground color: #468ef9, background color: #ffffff, font size: 13.5pt (18px), font weight: normal). Expected contrast ratio of 4.5:1"
},
"subItems": {
"type": "subitems",
"items": [
{
"relatedNode": {
"type": "node",
"lhId": "1-4-DIV",
"path": "1,HTML,1,BODY,0,DIV,1,MAIN,1,SECTION,0,DIV",
"selector": "div#__next > main.overflow-hidden > section.-mt-20 > div.max-md:w-[max-content]",
"boundingRect": {
"top": 1044,
"bottom": 1943,
"left": 99,
"right": 980,
"width": 881,
"height": 899
},
"snippet": "<div class=\"max-md:w-[max-content] lg:container mx-auto rounded-3xl bg-white py-8 lg:p…\">",
"nodeLabel": "Trending\nMore\nName\nPrice\nChart\nBitcoin\n+\n$43,180.13\nEthereum\n-\n$3,480.65\nSolana…"
}
}
]
}
},
{
"node": {
"type": "node",
"lhId": "1-6-A",
"path": "1,HTML,1,BODY,0,DIV,1,MAIN,1,SECTION,0,DIV,0,DIV,2,DIV,0,DIV,1,A",
"selector": "div.grid > div.px-5 > div.flex > a.text-primary",
"boundingRect": {
"top": 1493,
"bottom": 1524,
"left": 445,
"right": 517,
"width": 72,
"height": 32
},
"snippet": "<a class=\"text-primary cursor-pointer\" href=\"/#\">",
"nodeLabel": "More",
"explanation": "Fix any of the following:\n Element has insufficient color contrast of 3.23 (foreground color: #468ef9, background color: #ffffff, font size: 13.5pt (18px), font weight: normal). Expected contrast ratio of 4.5:1"
},
"subItems": {
"type": "subitems",
"items": [
{
"relatedNode": {
"type": "node",
"lhId": "1-4-DIV",
"path": "1,HTML,1,BODY,0,DIV,1,MAIN,1,SECTION,0,DIV",
"selector": "div#__next > main.overflow-hidden > section.-mt-20 > div.max-md:w-[max-content]",
"boundingRect": {
"top": 1044,
"bottom": 1943,
"left": 99,
"right": 980,
"width": 881,
"height": 899
},
"snippet": "<div class=\"max-md:w-[max-content] lg:container mx-auto rounded-3xl bg-white py-8 lg:p…\">",
"nodeLabel": "Trending\nMore\nName\nPrice\nChart\nBitcoin\n+\n$43,180.13\nEthereum\n-\n$3,480.65\nSolana…"
}
}
]
}
}
],
"debugData": {
"type": "debugdata",
"impact": "serious",
"tags": [
"cat.color",
"wcag2aa",
"wcag143",
"TTv5",
"TT13.c",
"EN-301-549",
"EN-9.1.4.3",
"ACT"
]
}
}
}
},
"configSettings": {
"output": "json",
"maxWaitForFcp": 30000,
"maxWaitForLoad": 45000,
"pauseAfterFcpMs": 1000,
"pauseAfterLoadMs": 1000,
"networkQuietThresholdMs": 1000,
"cpuQuietThresholdMs": 1000,
"formFactor": "desktop",
"throttling": {
"rttMs": 40,
"throughputKbps": 10240,
"requestLatencyMs": 0,
"downloadThroughputKbps": 0,
"uploadThroughputKbps": 0,
"cpuSlowdownMultiplier": 1
},
"throttlingMethod": "simulate",
"screenEmulation": {
"mobile": true,
"width": 412,
"height": 823,
"deviceScaleFactor": 1.75,
"disabled": true
},
"emulatedUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36",
"auditMode": false,
"gatherMode": false,
"disableStorageReset": false,
"debugNavigation": false,
"channel": "devtools",
"usePassiveGathering": false,
"disableFullPageScreenshot": false,
"skipAboutBlank": false,
"blankPage": "about:blank",
"budgets": null,
"locale": "en-US",
"blockedUrlPatterns": null,
"additionalTraceCategories": null,
"extraHeaders": null,
"precomputedLanternData": null,
"onlyAudits": null,
"onlyCategories": [
"accessibility"
],
"skipAudits": null
}
}
Interesting, I can no longer reproduce this as well :/
Will ping OP in the Lighthouse issue to see if the page content changed.
@straker I can reproduce this again, perhaps the issue is flaky somehow. Any chance you can try again?
@adamraine Still unable to reproduce. Do you know if the site has different content if loaded from different regions?
So I think different viewport sizes can lead to different results here. When running Lighthouse in DevTools while DevTools is docked, the viewport is narrower and the error does not appear. To get the error to appear, I needed to run Lighthouse in DevTools while it was undocked so the viewport occupies the entire Chrome window. Perhaps you're running into this same scenario?
For reference, the outer width x height of the Chrome window that would repro this for me is 1792 x 1032.
@adamraine You're right. I'm now able to reproduce when running at a screen size width >1540px.
So I found the issue, and it's a tricky one. At that screen size near the bottom of the page is a section titled "Get started in just a few minutes" which has 3 columns. The last column "Buy Crypto" is outside the content of the page. Once the element is scrolled into view, JavaScript (probably an intersection observer) kicks in and an animation plays to expand the content to fill the entire width of the page.
So when the element is in view there is no problem, but running axe at the top of the page with the element out of view causes color-contrast to throw since the element is outside the content of the page.
Note to self: I need to do some testing to figure out why the element is not considered offscreen when color-contrast is run. We should ignore the element as it is transformed outside the bounds of the screen/grid, so need to figure out why that is not happening.
@straker I've got the same error at this URL, reproducible on Lighthouse and pagespeed.web.dev: https://baseline-landing--beta-rvf19wtw.web.app/ (only on mobile, desktop works fine).
We have the same error, just for Mobile. It happens for a web component (cookie consent banner) which is used on many sites. Reproducible, e.g. on the demo page: https://dock.ui.bosch.tech/releases/4-latest/ or on https://www.boschrexroth.com/de/de/ and other sites as well. Note: Cookies have to be deleted before test, so consent dialog shows.
However, not all sites using the component (in the same version) get the error... @straker I'm happy to provide additional details via pm/mail if needed :)
I have already reported this issue a month back https://github.com/GoogleChrome/lighthouse/issues/15750.
This is happening for most of the pages. Here is a sample https://www.edureka.co/pmp-certification-exam-training
Let me know how to fix this!
Hi , I have raised similar issue, more details are added here - https://github.com/GoogleChrome/lighthouse/issues/15619#issuecomment-1927332918
Appreciate if you can take a look and suggest possible resolutions
So I found the issue, and it's a tricky one. At that screen size near the bottom of the page is a section titled "Get started in just a few minutes" which has 3 columns. The last column "Buy Crypto" is outside the content of the page. Once the element is scrolled into view, JavaScript (probably an intersection observer) kicks in and an animation plays to expand the content to fill the entire width of the page.
So when the element is in view there is no problem, but running axe at the top of the page with the element out of view causes color-contrast to throw since the element is outside the content of the page.
Why do we throw in this scenario and not just ignore the element?
@dylanb it was a conscious decision to throw as it reveals a flaw in our color-contrast code that would not be reported to us otherwise. Since our entire color-contrast algorithm is a custom elementsFromPoint alternative, we wanted to ensure it wasn't skipping things when it shouldn't. It's allowed us to fix issues in the past and sometimes the elements can be accurately reported on and sometimes they cannot be.
Hi, I have the same issue for mobile: https://bestdeal.shop/ I've tried to turn off / delay the cookie consent banner and nothing has worked. Any help would be much appreciated!
Hi everyone,
I'm facing the same issue. After isolating the cause, I was able to identify what was causing the failure. As you can see in the screenshot below, my slider has "overflow: visible", and its container has "overflow: hidden". This causes my text to be cut in half on the screen, even though this behavior is expected since it's a slider.
I've already tried a few ways to "bypass" this check by identifying Google's headers, or even only showing the overflow of the slide container when the mouse is over it. However, this is a palliative solution, as it's a UX-UI trend to make sliders this way. I will include some examples of large companies that have landing pages with this same feature.
My Project: https://github.com/TutorFx/vs-contabil
Benchmark:
@straker any update on this? It seems to affect a decent number of pages.
Experiencing the same issue on desktop only(mobile works fine). I'm only getting that on pagespeedinsights.. lighthouse test works fine https://www.pactzion.com/
Thanks for the all the affected pages, that'll be super helpful as I work on a solution. With axe-con over I'll now have time to work on this. I just need to wrap one other thing up first and then I can start looking at this bug.
Alright, I was able to determine the bug for the pages provided by the OP (https://nefa-crypto-page.vercel.app/) and @clouddevloper. The problem is the same for both sites so I think I've identified a fix.
Unfortunately I'm unable to reproduce the error for the websites from @nkalupahana (page no longer found) and from the following: @chmerk, @dylanrihan, @TutorFx, and @Hosea174 (for each I tried the page in various screen sizes, both from initial load without scrolling and after scrolling the page to load any lazy loaded content. I left the cookie consent modals open and didn't close them for the tests). For everyone whose pages I couldn't verify, if you wouldn't mind letting me know exactly how to reproduce it on the page (including screen size needed, etc.) that would be helpful.
A note to myself so I know what the issues is so far:
Elements with text content whose bounding box starts inside an overflow: hidden ancestor but whose text content starts outside the same ancestor will trigger this bug. The cause is from this line of the get-visible-child-text-rects where an empty array of content rects will return the containing boudning rect. But since the containing bounding rect's size is mostly outside the bounds of an overflow: hidden ancestor, when we try to get the center of the rect it falls outside the bounds of the grid.
Minimal test case:
<!doctype html>
<html>
<body>
<style>
html, body {
width: 200px;
overflow: hidden;
}
h1 {
margin-left: 190px;
padding-left: 20px;
width: 500px;
}
</style>
<h1>Hello World</h1>
</body>
</html>
Thanks @straker! I will check the solution and get back to you 👍
@straker sorry about that, it was a preview URL. I am still able to reproduce the error with Lighthouse (mobile) at https://getbaseline.app
@nkalupahana Thanks for the updated site. I'm able to reproduce and the issue is the same as the other two sites: DOM nodes which are visible inside an overflow: hidden ancestor but whose text content lies outside of it.