Skip to Content
  • Website
Codsen
  • Home
  • Open Source
  • Articles
  • About

Styling the react-codemirror instances

by Roy Revelt   ·   posted on Monday, 18 July 2022   ·   metareactts

  • the top
  • OUTER LAYOUT
  • MAX HEIGHT VI…
  • DARK-LIGHT TH…
  • LINE WRAPPING
  • TAKEAWAY
  • SOURCES

When building the string-strip-html GUI, I wanted: line wrapping, full-screen flexbox layout, with scrollbars on Codemirror box only. That’s a common layout seen on code-oriented sites like Codepen or Stackblitz. I created a minimal proof-of-concept sandbox to prove it works.


For simplicity, we’ll be using @uiw/react-codemirroropens in a new tab, raw React and pure CSS:

Let me explain the non-trivial parts of this layout.

Outer layout

We have to ensure that every container, including <html> and <body>, expands to the 100% of the viewport height with the help of CSS vhopens in a new tab unit:

html,
body,
#root,
.playground-container {
  padding: 0;
  margin: 0;
  height: 100vh; /* <--- */
  background-color: #efefef;
}

The CSS vh unit is supported on all browser versions dated newer than 2013opens in a new tab.

Max height via CSS Flexbox

“To let the editor grow until it reaches a maximum height, and scroll from that point on, use max-height instead of height in a setup like the one above.”

—https://codemirror.net/examples/styling/#themesopens in a new tab

In CSS Flexbox layout, there’s no max-height, the container div, which holds the Codemirror instance, expands with the help of CSS style flex: 1.

I could only achieve it via flexbox and setting .cm-scroller to be absolutely positioned and glue its edges to the parent .cm-editor container:

.cm-editor {
  /* our container wrapper for Codemirror instance */
  flex: 1; /* expand to the maximum */
  height: 100%;
  position: relative; /* needed for child component .cm-scroller */
}

.cm-scroller {
  position: absolute !important;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  overflow-y: auto;
}

It took me a couple of hours to discover this setup. The absolute positioning seems to be the only way to impose scrollbars on Codemirror boxes when its height is unknown and set by CSS Flexbox.

Dark-light themes

If you’re happy with Codemirror default themes, just set the prop theme on the <CodeMirror/> component. Below, we’re using remix-themesopens in a new tab so theme comes from let [theme] = useTheme();:

import CodeMirror from "@uiw/react-codemirror";
import { html } from "@codemirror/lang-html";
import { EditorView } from "@codemirror/view";
...
<CodeMirror
  className="cm-outer-container"
  value={inputStr}
  extensions={[html(), EditorView.lineWrapping]}
  onChange={onChange}
  theme={theme || "dark"}
/>

Line wrapping

“To enable line wrapping, add the EditorView.lineWrapping extension to your configuration.”

—https://codemirror.net/examples/styling/#overflow-and-scrollingopens in a new tab

Another challenge is setting up this EditorView.lineWrapping extension. There are no code examples on the CodeMirror docs site showing how to import it and where to place it. For an answer, see the example in the previous section above.

To cause lines to wrap, I chose belt-and-braces: to use EditorView.lineWrapping (extensions prop) and to apply CSS directly onto Codemirror elements, as hinted by the documentation (“wrapping can be unreliable if you don’t also set overflow-wrap: anywhere”). By the way, that’s what CSS Codepen uses:

.cm-content {
  white-space: pre-wrap;
  word-break: normal;
  word-wrap: break-word;
}

Takeaway

Feel free to fork the sandbox and use that layout in your code-processing apps.

Sources

  • @uiw react-codemirror npm page https://www.npmjs.com/package/@uiw/react-codemirroropens in a new tab
  • @uiw react-codemirror GitHub page https://github.com/uiwjs/react-codemirroropens in a new tab
  • codemirror npm page https://www.npmjs.com/package/codemirroropens in a new tab
  • codemirrror v6 documentation https://codemirror.net/docs/opens in a new tab

↑ back to top
older newer

Copyright

All rights reserved © Roy Revelt 2026
All our open source packages are under MIT licenceopens in a new tab

Activities

🐛 See a bug? Raise an issueopens in a new tab
💘 Check out the Indiewebopens in a new tab and Libera manifestoopens in a new tab