Scrollbar position jumps when selecting closing bracket on mobile #1499

Open
opened 2025-01-04 14:13:48 +01:00 by MannoSutisnaDev · 5 comments
MannoSutisnaDev commented 2025-01-04 14:13:48 +01:00 (Migrated from github.com)

Describe the issue

When I place a code mirror text editor on my page completely at the top, there is no problem when it comes to the scrollbar position jumping.

https://github.com/user-attachments/assets/10ac8308-bcd0-409d-ae45-1a47c9cdaea3

However when I give element that code mirror is attached to a any margin-top, the scrollbar position jumps somewhere above when selecting the last closing bracket of the code inside the code mirror element.

https://github.com/user-attachments/assets/5c5d5a3a-ca77-4390-8e93-8767ed0831a2

In the example above the code mirror element was given a margin-top of 20px. Below there is another example where the code mirror element was given a margin-top of 100px.

https://github.com/user-attachments/assets/8123764d-787a-4514-8e1d-9edd57f58400

In the video examples that I gave I was running code mirror in a Vue application and the exact code that I used is as follows:

<script lang="ts" setup>
import { EditorState } from "@codemirror/state";
import { EditorView } from "@codemirror/view";
import { basicSetup } from "codemirror";
import { oneDark } from "@codemirror/theme-one-dark";

const editorRef = ref<HTMLDivElement>();
onMounted(() => {
  const editorElement = editorRef.value;
  if (!editorElement) {
    return;
  }
  const state = EditorState.create({
    extensions: [basicSetup, oneDark],
    doc: JSON.stringify(
      {
        compilerOptions: {
          target: "ESNext",
          useDefineForClassFields: true,
          module: "ESNext",
          moduleResolution: "Node",
          strict: false,
          jsx: "preserve",
          resolveJsonModule: true,
          isolatedModules: true,
          esModuleInterop: true,
          lib: ["ESNext", "DOM"],
          skipLibCheck: true,
          noEmit: true,
        },
        include: [
          "src/**/*.ts",
          "src/**/*.d.ts",
          "src/**/*.tsx",
          "src/**/*.vue",
        ],
        references: [{ path: "./tsconfig.node.json" }],
      },
      null,
      2,
    ),
  });
  new EditorView({
    parent: editorElement,
    state,
  });
});
</script>

Browser and platform

Samsung S22 Ultra, Android 14, Chrome 131.0.06778.200

No response

### Describe the issue When I place a code mirror text editor on my page completely at the top, there is no problem when it comes to the scrollbar position jumping. https://github.com/user-attachments/assets/10ac8308-bcd0-409d-ae45-1a47c9cdaea3 However when I give element that code mirror is attached to a any margin-top, the scrollbar position jumps somewhere above when selecting the last closing bracket of the code inside the code mirror element. https://github.com/user-attachments/assets/5c5d5a3a-ca77-4390-8e93-8767ed0831a2 In the example above the code mirror element was given a margin-top of 20px. Below there is another example where the code mirror element was given a margin-top of 100px. https://github.com/user-attachments/assets/8123764d-787a-4514-8e1d-9edd57f58400 In the video examples that I gave I was running code mirror in a Vue application and the exact code that I used is as follows: ``` <script lang="ts" setup> import { EditorState } from "@codemirror/state"; import { EditorView } from "@codemirror/view"; import { basicSetup } from "codemirror"; import { oneDark } from "@codemirror/theme-one-dark"; const editorRef = ref<HTMLDivElement>(); onMounted(() => { const editorElement = editorRef.value; if (!editorElement) { return; } const state = EditorState.create({ extensions: [basicSetup, oneDark], doc: JSON.stringify( { compilerOptions: { target: "ESNext", useDefineForClassFields: true, module: "ESNext", moduleResolution: "Node", strict: false, jsx: "preserve", resolveJsonModule: true, isolatedModules: true, esModuleInterop: true, lib: ["ESNext", "DOM"], skipLibCheck: true, noEmit: true, }, include: [ "src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", ], references: [{ path: "./tsconfig.node.json" }], }, null, 2, ), }); new EditorView({ parent: editorElement, state, }); }); </script> ``` ### Browser and platform Samsung S22 Ultra, Android 14, Chrome 131.0.06778.200 ### Reproduction link _No response_
marijnh commented 2025-01-06 17:21:01 +01:00 (Migrated from github.com)

I can reproduce this. It only happens with bracket matching enabled. The scroll position jump seems to happen a little after CodeMirror finishes updating the DOM (not even in the same frame). This suggests the browser is doing something on its own timeline, though I'm not sure what. I'd guess the browser somehow decides it needs to scroll the DOM change caused by highlighting the bracket at the start into view, but since it doesn't generally do this for all changes (for example the removing of the highlighting doesn't cause a similar issue) I suppose there's more going on.

I can reproduce this. It only happens with bracket matching enabled. The scroll position jump seems to happen a little after CodeMirror finishes updating the DOM (not even in the same frame). This suggests the browser is doing _something_ on its own timeline, though I'm not sure what. I'd guess the browser somehow decides it needs to scroll the DOM change caused by highlighting the bracket at the start into view, but since it doesn't generally do this for all changes (for example the removing of the highlighting doesn't cause a similar issue) I suppose there's more going on.
marijnh commented 2025-01-07 11:36:08 +01:00 (Migrated from github.com)

Looking into this some more, I'm rather certain it's a bug in Chrome (none of the CodeMirror code is initiating a scroll, and the way the resulting scroll position depends on the margin makes no sense). I wasn't able to set up a self-contained script that reproduces it though, so I don't really have a way to report it to the Chrome team.

Looking into this some more, I'm rather certain it's a bug in Chrome (none of the CodeMirror code is initiating a scroll, and the way the resulting scroll position depends on the margin makes no sense). I wasn't able to set up a self-contained script that reproduces it though, so I don't really have a way to report it to the Chrome team.
MannoSutisnaDev commented 2025-01-07 11:56:31 +01:00 (Migrated from github.com)

@marijnh is there a way to disable bracket matching?

@marijnh is there a way to disable bracket matching?
marijnh commented 2025-01-07 12:58:17 +01:00 (Migrated from github.com)

Yes—don't include the matchBrackets extension.

Yes—don't include the `matchBrackets` extension.
peasneovoyager2banana2 commented 2025-10-11 12:45:35 +02:00 (Migrated from github.com)
<img width="484" height="117" alt="Image" src="https://github.com/user-attachments/assets/a165d105-6c06-4133-962e-59d96764d903" /> ### Chrome https://github.com/user-attachments/assets/3bb27028-2d02-4f46-b46d-8d6b52d7e072 ### Firefox https://github.com/user-attachments/assets/ab2ac8ae-ea20-484d-81b3-0dbca399db9f
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
codemirror/dev#1499
No description provided.