Search code examples
htmlcssscrollbarpre

CSS: container to show PRE tag with scroll bars


I have some server-side code that outputs stuff in html <pre></pre> tags and I would like to be able to put them in a container with scroll bars. (Specifically, table cells - with equal widths). Obviously I want to preserve the <pre> tag whitespace formatting.

(see this jsfiddle):

HTML:

<table>
<tr>
    <th>Col 1</th>
    <th>Col 2</th>
</tr>
    <tr>
        <td><pre>
function thisIsATest(bla){
    Testing 123456789 Testing 123456789 Testing 123456789
}
        </pre></td>
        <td><pre>
function thisIsATest(bla){
    Testing 123456789 Testing 123456789 Testing 123456789
}
        </pre></td>
    </tr>
</table>

CSS:

table { 
    width: 100%; 
    border: 1px solid red;
}
td { 
    width: 50%;
    overflow: scroll; 
    border: 1px solid blue;
}

enter image description here

(I am testing it in Firefox). What am I doing wrong? Thanks


Solution

  • Update

    The easiest way to fix this is to add: table-layout:fixed; (ironic) to the CSS for table

    Fiddle


    Original Answer:

    Using pre tags within table elements is notoriously problematic, namely due to issues with relative width calculations which throw scrolling and actual width setting right out. As such, I'd avoid a table based setup, not least of which because you're also not displaying tabulated data (aaah semantics!).

    I'd change your layout per the below:

    Demo Fiddle

    HTML

    <div class='container'>
        <div class='col'> <pre>
    function thisIsATest(bla){
        Testing 123456789 Testing 123456789 Testing 123456789
    }
            </pre>
    
        </div>
        <div class='col'> <pre>
    function thisIsATest(bla){
        Testing 123456789 Testing 123456789 Testing 123456789
    }
            </pre>
    
        </div>
    </div>
    

    CSS

    * {
        box-sizing:border-box;
    }
    html, body {
        margin:0;
        padding:0;
    }
    .container {
        border: 1px solid red;
        overflow:hidden;
    }
    .col {
        border: 1px solid blue;
        float:left;
        width:50%;
        overflow: auto;
    }
    

    Update

    To fake a multi-line (row) table layout, use div element with dislpay set as appropriate:

    Demo Fiddle

    HTML

    <div class='table'>
        <div class='row'>
            <div class='cell'> <pre>
    function thisIsATest(bla){
        Testing 123456789 Testing 123456789 Testing 123456789
    }
            </pre>
    
            </div>
            <div class='cell'> <pre>
    function thisIsATest(bla){
        Testing 123456789 Testing 123456789 Testing 123456789
    }
            </pre>
    
            </div>
        </div>
        <div class='row'>
            <div class='cell'> <pre>
    function thisIsATest(bla){
        Testing 123456789 Testing 123456789 Testing 123456789
    }
            </pre>
    
            </div>
            <div class='cell'> <pre>
    function thisIsATest(bla){
        Testing 123456789 Testing 123456789 Testing 123456789
    }
            </pre>
    
            </div>
        </div>
    </div>
    

    CSS

    * {
        box-sizing:border-box;
    }
    html, body {
        margin:0;
        padding:0;
    }
    .table {
        border: 1px solid red;
        display:table;
        table-layout:fixed;
        width:100%;
    }
    .cell {
        border: 1px solid blue;
        overflow: auto;
        display:table-cell;
    }
    .row {
        display:table-row;
    }