10

I want to embed a Monaco Editor in a page under some fixed texts, I want the height of the Monaco Editor to fill exactly the rest of the page. People gave me an answer here: JSBin:

<html>
    <style>
        html, body, .rb {
            margin: 0;
            height: 100%;
        }

        .rb {
            display: table;
            width: 100%;
            border-collapse: collapse;
        }

        .top, .myME {
            display: table-row;
        }

        .buffer {
            display: table-cell;
        }

        .top .buffer {
            background: lightblue;
            height:1%;
        }

        .myME .buffer {
            background: tomato;
        }

        #container {
            position:relative;
        }

        #container > * {
            overflow:auto;
            max-width:100%;
            max-height:100%;
        }
    </style>
    <body>
        <div class="rb">
            <div class="top">
                <div class="buffer">
                1<br/>2<br/>3<br/>4<br/>
                </div>
            </div>
            <div class="myME">
                <div class="buffer" id="container">
                </div>
            </div>
        </div>
    <script src="https://www.matrixlead.com/monaco-editor/min/vs/loader.js"></script>
    <script>
        require.config({ paths: { 'vs': 'https://www.matrixlead.com/monaco-editor/min/vs' }})

        require(["vs/editor/editor.main"], function () {
          var editor = monaco.editor.create(document.getElementById('container'), {
            value: 'function x() {\n\tconsole.log("Hello world!");\n}',
            language: 'javascript',
            minimap: { enabled: false },
            automaticLayout: true,
            scrollBeyondLastLine: false
          });
        });
    </script>
    </body>
</html>

It works perfectly in Chrome, but it does not display the editor in Safari because of max-height:100% of #container > *. If we set it to max-height:100vh or height: 100vh, it works more or less in Safari (with a little bit flashing when the focus reaches the bottom of the editor), whereas it shows a scroller while scrolling up and down in Chrome.

Does anyone have a solution that works both in Chrome and Safari? Otherwise, is it possible to set specific rule for Chrome or Safari only?

SoftTimur
  • 5,630
  • 38
  • 140
  • 292

3 Answers3

3

You can use vh and flex-grow together:

.rb {
    display: flex;
    flex-direction: column;
    height: 100vh;
    margin: 0;
}

.rb #container {
    flex-grow: 1; 
}

Edit: Aha - Monico Editor has a fixedOverflowWidgets: true that can be set. Here is the final functional thing: https://jsfiddle.net/pa8y2fzy/3/

require.config({
  paths: {
    'vs': 'https://www.matrixlead.com/monaco-editor/min/vs'
  }
})

require(["vs/editor/editor.main"], function() {
  var editor = monaco.editor.create(document.getElementById('container'), {
    value: [
      'function x() {',
      '\tconsole.log("Hello world!");',
      '}'
    ].join('\n'),
    language: 'javascript',
    fixedOverflowWidgets: true
  });
});

Edit: As I mentioned in the comments, I don't have access to Safari, but here is a page with Safari CSS hacks: is there a css hack for safari only NOT chrome?

Jonathan
  • 6,507
  • 5
  • 37
  • 47
  • can you make a working JSBin? My tests show that this setting has a total overflow... – SoftTimur Aug 11 '17 at 02:04
  • The fixed texts and the editor together have an overflow... You can scroll down and see it... – SoftTimur Aug 11 '17 at 02:05
  • I haven't ever worked with Monico Editor. Do you have any clue what the `overflowingContentWidgets` are for? If we hide those, it's easy to get it working. https://jsfiddle.net/pa8y2fzy/1/ – Jonathan Aug 11 '17 at 02:31
  • 1
    Never mind that last comment, I found out that there is another property you can set when initiating the Monico Editor. See the updated answer. – Jonathan Aug 11 '17 at 02:38
  • Thank you for this... It works well in Chrome, but it does not work in Safari: the height is too much in Safari... – SoftTimur Aug 11 '17 at 02:42
  • Hmm... It seems to work OK in FireFox, too. I'm using Linux so unfortunately I can't test Safari. The best I could suggest would be a `overflow:hidden;` on the body: https://jsfiddle.net/pa8y2fzy/4/ Kindof a hack, but when it's just one browser... – Jonathan Aug 11 '17 at 02:54
  • well, `overflow:hidden` and the new jsfiddle do not work well in Safari... Actually, previously I did look for [a solution](https://stackoverflow.com/questions/45394245/make-the-code-mirror-block-fill-the-rest-of-the-page-in-safari/45467716#45467716) that works cross-browser for CodeMirror (and it was quite hard), now I should do this for Monaco Editor... – SoftTimur Aug 11 '17 at 02:59
  • 1
    I have found some threads about auto resizes: [1](https://github.com/Microsoft/monaco-editor/issues/28), [2](https://github.com/Microsoft/monaco-editor/issues/71), [3](https://github.com/Microsoft/monaco-editor/issues/103)... Maybe that is the direction to go for Monaco Editor... – SoftTimur Aug 11 '17 at 03:01
  • It's worth a try. – Jonathan Aug 11 '17 at 03:03
2

Finally, in Chrome and Safari, the following code does not create any scroll bar while scrolling up and down, there are no lines hidden in the bottom when the code is long, the footer is always at the bottom regardless of resizing. Additionally, it is important to test it in an independent html file rather than in JSBin.

<html>
    <style>
    .rb {
        height: 100%;
        display: flex;
        flex-direction: column;
    }

    .myME {
        flex:1;
        overflow: hidden;
    }

    .footer {
        flex-shrink: 0; 
        background:#f8f8f8;
        border-top: 1px solid #e7e7e7
    }
    </style>
    <body>
        <div class="rb">
            <div class="top">1<br/>2<br/>3<br/>4<br/></div>
            <div class="myME" id="container"></div>
            <div class="footer">haha</div>
        </div>
    <script src="https://www.matrixlead.com/monaco-editor/min/vs/loader.js"></script>
    <script>
        require.config({ paths: { 'vs': 'https://www.matrixlead.com/monaco-editor/min/vs' }})

        require(["vs/editor/editor.main"], function () {
          var editor = monaco.editor.create(document.getElementById('container'), {
            value: 'function x() {\n\tconsole.log("Hello world!");\n}\nfunction x() {\n\tconsole.log("Hello world!");\n}\nfunction x() {\n\tconsole.log("Hello world!");\n}',
            language: 'javascript',
            minimap: { enabled: false },
            automaticLayout: true,
            scrollBeyondLastLine: false
          });
        });
    </script>
    </body>
</html>
SoftTimur
  • 5,630
  • 38
  • 140
  • 292
0

I cannot test in Safari but I don't see any reason to use max-height/width when you always want it to be 100% relative to the container. Try simply using

#container > * {
    overflow:auto;
    width:100%;
    height:100%;
}
inarilo
  • 804
  • 1
  • 9
  • 14