Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Element midpoint exceeds the grid bounds" #4253

Closed
1 task done
adamraine opened this issue Nov 21, 2023 · 23 comments · Fixed by #4357 · 4 remaining pull requests
Closed
1 task done

"Element midpoint exceeds the grid bounds" #4253

adamraine opened this issue Nov 21, 2023 · 23 comments · Fixed by #4357 · 4 remaining pull requests
Assignees
Labels
color contrast Color contrast issues fix Bug fixes

Comments

@adamraine
Copy link

Product

axe-core

Product Version

4.8.1

Latest Version

  • 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

GoogleChrome/lighthouse#15619

@adamraine adamraine added the ungroomed Ticket needs a maintainer to prioritize and label label Nov 21, 2023
@straker
Copy link
Contributor

straker commented Nov 21, 2023

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
  }
}

@adamraine
Copy link
Author

Interesting, I can no longer reproduce this as well :/

Will ping OP in the Lighthouse issue to see if the page content changed.

@adamraine
Copy link
Author

@straker I can reproduce this again, perhaps the issue is flaky somehow. Any chance you can try again?

@straker
Copy link
Contributor

straker commented Nov 28, 2023

@adamraine Still unable to reproduce. Do you know if the site has different content if loaded from different regions?

@adamraine
Copy link
Author

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.

@straker
Copy link
Contributor

straker commented Nov 28, 2023

@adamraine You're right. I'm now able to reproduce when running at a screen size width >1540px.

@straker
Copy link
Contributor

straker commented Nov 28, 2023

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.

@straker
Copy link
Contributor

straker commented Nov 29, 2023

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 straker added fix Bug fixes color contrast Color contrast issues and removed ungroomed Ticket needs a maintainer to prioritize and label labels Nov 29, 2023
@straker straker added this to the Axe-core 4.9 milestone Nov 29, 2023
@nkalupahana
Copy link

@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).

@chmerk
Copy link

chmerk commented Jan 22, 2024

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 :)

@clouddevloper
Copy link

I have already reported this issue a month back GoogleChrome/lighthouse#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!

@kmurugulla
Copy link

Hi , I have raised similar issue, more details are added here - GoogleChrome/lighthouse#15619 (comment)

Appreciate if you can take a look and suggest possible resolutions

@dylanb
Copy link
Contributor

dylanb commented Feb 6, 2024

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?

@straker
Copy link
Contributor

straker commented Feb 6, 2024

@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.

@dylanrihan
Copy link

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!

@TutorFx
Copy link

TutorFx commented Feb 20, 2024

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
image

Benchmark:

Example 1
Example 2

@adamraine
Copy link
Author

@straker any update on this? It seems to affect a decent number of pages.

@Hosea174
Copy link

Hosea174 commented Feb 26, 2024

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/

@straker
Copy link
Contributor

straker commented Feb 26, 2024

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.

@straker
Copy link
Contributor

straker commented Mar 4, 2024

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>

@clouddevloper
Copy link

Thanks @straker! I will check the solution and get back to you 👍

@nkalupahana
Copy link

nkalupahana commented Mar 5, 2024

@straker sorry about that, it was a preview URL. I am still able to reproduce the error with Lighthouse (mobile) at https://getbaseline.app

@straker
Copy link
Contributor

straker commented Mar 5, 2024

@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.

straker added a commit that referenced this issue Mar 12, 2024
…ncestor (#4357)

Closes: #4253

---------

Co-authored-by: Wilco Fiers <WilcoFiers@users.noreply.github.com>
WilcoFiers added a commit that referenced this issue Mar 25, 2024
##
[4.9.0](v4.8.4...v4.9.0)
(2024-03-25)

### Features

- adding the wcag131 tag to the aria-hidden-body rule
([#4349](#4349))
([dd4c3c3](dd4c3c3)),
closes [#4315](#4315)
- **checks:** deprecate aria-busy check
([#4356](#4356))
([be0b555](be0b555)),
closes [#4347](#4347)
[#4340](#4340)
- **color:** add color channel values and luminosity, saturation, clip
functions ([#4366](#4366))
([9e70199](9e70199)),
closes
[/github.com//pull/4365/files#r1517706612](https://github.com/dequelabs//github.com/dequelabs/axe-core/pull/4365/files/issues/r1517706612)
- **i18n:** add Greek Translations
([#3836](#3836))
([3ea9a48](3ea9a48))
- **i18n:** Add Italian translation
([#4344](#4344))
([de1baa9](de1baa9))
- **i18n:** Add Simplified Chinese translation
([#4379](#4379))
([bda7c8d](bda7c8d))
- **i18n:** Add Taiwanese Mandarin translation
([#4299](#4299))
([c5e11de](c5e11de))

### Bug Fixes

- Add LICENSE-3RD-PARTY.txt file
([#4304](#4304))
([daa0fe6](daa0fe6))
- add Object.values polyfill for node <=6
([#4274](#4274))
([5eb867b](5eb867b))
- **aria-required-children:** avoid confusing aria-busy message in
failures ([#4347](#4347))
([591607d](591607d)),
closes [#fail13](https://github.com/dequelabs/axe-core/issues/fail13)
[#4340](#4340)
- avoid reading element-specific node properties of non-element node
types ([#4317](#4317))
([b853b18](b853b18)),
closes [#4316](#4316)
[#4316](#4316)
- **color-contrast:** handle text that is outside `overflow: hidden`
ancestor ([#4357](#4357))
([bdb7300](bdb7300)),
closes [#4253](#4253)
- **color-contrast:** support color blend modes hue, saturation, color,
luminosity ([#4365](#4365))
([7ae4761](7ae4761))
- **d.ts:** RawNodesResult issues
([#4229](#4229))
([d660518](d660518))
- **d.ts:** RunOptions.reporter can be any string
([#4218](#4218))
([e53f5c5](e53f5c5))
- **i18n:** update Italian translations
([#4377](#4377))
([4d65d4b](4d65d4b))
- **listitem:** clarify roleNotValid message
([#4374](#4374))
([0f8a9af](0f8a9af))
- **scrollable-region-focusable:** missing wcag213 tag
([#4201](#4201))
([0080a72](0080a72))
- **target-size:** always pass 10x targets (avoid perf bottleneck)
([#4376](#4376))
([be327c4](be327c4))
- **target-size:** do not crash for nodes with many overlapping widgets
([#4373](#4373))
([1dbea83](1dbea83)),
closes [#4359](#4359)
[#4359](#4359)
[#4360](#4360)
- **utils/get-selector:** ignore 'xmlns' attribute when generating a
selector ([#4303](#4303))
([938b411](938b411))

This PR was opened by a robot 🤖 🎉
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment