Incorrect header width for scrollable table in IE11

Incorrect header width for scrollable table in IE11

VolodymyrKVolodymyrK Posts: 12Questions: 2Answers: 0

Hi,
After migrating from version 1.10.25 to version 1.11.3 I’m observing problems with column header width in Internet Explorer 11.

The related table are created using ‘scrollY: 200’. As result table header and body are two different tables in DOM and datatables provides some calculations to make header table and body table columns width equal.

But, after the migration I can see next:
Expected result
Header table columns and body table columns width should be equal.
Actual result
Corresponding columns from header and body table might have different width

Currently, it hard to me to reproduce it outside my environment but it seems that the issue depends on cell contents. For me it reproduced for some columns with icons or checkboxes(Perhaps it depends on inner content size, padding or other attributes).

By looking on datatables changes I would say that the current situations is triggered by next changes:

As we can see:

In version 1.10.25:
Column width has been calculated using **‘$(nSizer).css('width')’ **expression

In version 1.11.3
Column width is calculated using
‘window.getComputedStyle(nSizer).width’ expression if window.getComputedStyle is supported by browser or
using ‘$(nSizer).width()’ expression in other case.

Second expression is used for my case as window.getComputedStyle doesn’t implemented for IE11.

And from what I can see that the second ‘$(nSizer).width()’ might give different result than window.getComputedStyle method.
I’ve tried to debug results from old and two new expressions, and I see next results for my example for the column with width 39px:
1. Old expression ‘$(nSizer).css('width')’ gives 39px
2. window.getComputedStyle also gives 39px
3. But for ‘$(nSizer).width()’ gives 13px which isn’t correct value.
After that incorrect value is assigned to body table header:

And then it looks like header table use this incorrect value to adjust its width and it gives us the resulted behavior with different column size described above.

So, it looks that problem is in using ‘$(nSizer).width()’ expression which could return different result than window.getComputedStyle.
Hence this situation could affect any browser where window.getComputedStyle isn’t implemented.

So, for me it looks that width() method isn’t reliable enough her to use it for column width calculation.

Can we consider this situation as a regression bug?

Could this situation be fixed by using ‘$(nSizer).css('width')’ expression instead of the ‘$(nSizer).width()’ to return previous cross-browser behavior?

Cause, as I observe in my case ‘$(nSizer).css('width')’ and window.getComputedStyle always gives the same result but ‘$(nSizer).width()’ according to cell content might returns different result.
Or, perhaps you could suggest alternative solution.

Best Regards

Answers

  • allanallan Posts: 63,512Questions: 1Answers: 10,472 Site admin

    Thanks for flagging this up. getCompletedStyle is available in IE11. Are you getting errors in IE11 saying it isn't? Might you be using the browser in quirks or compatibility mode?

    Allan

  • VolodymyrKVolodymyrK Posts: 12Questions: 2Answers: 0

    Thanks for the answer Allan. Yes, you are right. Thanks for this catch. getCompletedStyle is implemented in IE11as you say. I wrongly described my test case with methods behavior for Chrome instead of IE11.
    The getCompletedStyleis implemented but anyway returns incorrect width.

    Here is correct exmple with all 3 methods in IE11 for the column that have actual width 539px:
    1. Old expression $(nSizer).css('width') gives 539px (Version 1.10.25)
    2. window.getComputedStyle gives 501.5px (Version 1.11.3)
    3.$(nSizer).width()gives 502px (Version 1.11.3)

    Hence it looks that both new methods might return width different that it was in version 1.10.25. So the problem is in getComputedStylemethod that returns unexpected width for IE11. And this seems to be the real cause of the described behavior.

  • allanallan Posts: 63,512Questions: 1Answers: 10,472 Site admin

    I've just tried this example in IE11 and it appears to be working okay. Does it for you? If not, can you give me a link to a page which is showing the is issue for you?

    I would expect getComputedStyle to be smaller and css('width'), depending on the box model of the table cells.

    Allan

  • VolodymyrKVolodymyrK Posts: 12Questions: 2Answers: 0

    Allan, your example works correct.

    But my case is more specyfic. I've prepared simplified example wher the issue is reproduced:

    Here is index.html

    <html>
        <header>
            <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
            <script type="text/javascript" src="main.js"></script>
            <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.11.3/js/jquery.dataTables.js"></script>
            <link rel="stylesheet" type="text/css" href="main.css">
        </header>
        <body>
            <p>Header</p>
            <table id="table_id" class="display">
                <thead>
                    <tr>
                        <th></th>
                        <th></th>
                        <th>Head3</th>
                        <th>Head4</th>
                        <th></th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td>text</td>
                        <td>text</td>
                        <td>text</td>
                        <td>text</td>
                        <td><img style="width: 50; height: 20; padding-left: 10px; padding-right: 10px;" alt="1" src="https://cdn-icons-png.flaticon.com/512/5110/5110429.png"></td>
                    </tr>
                    <tr>
                        <td>text</td>
                        <td>text</td>
                        <td>text</td>
                        <td>text</td>
                        <td>22222</td>
                    </tr>
                </tbody>
            </table>
        </body>
    </html>
    

    Here is main.js

    this.columns = [];
    this.columns.push({ width: '48px' });
    this.columns.push({ width: '52px' });
    this.columns.push(null);
    this.columns.push(null);
    this.columns.push({ width: '30px' });
    
    
    const config = {
        searching: false,
        scrollY: 200,
        scrollX: true,
        info: false,
        paging: false,
        lengthChange: false,
        jQueryUI: true,
        columns: this.columns,
        autoWidth: false
      };
    $(document).ready( function () {
        $('#table_id').DataTable(config);
    } );
    

    And here is main.css

     table {
        font-size: 12px;
        box-sizing: border-box;
        border-collapse: collapse;
        background-color: transparent;
        width: 684.333px;
     }
    
     td {
        box-sizing: border-box;
        padding: 0px 12px 0px 12px;
        border: 1px solid red;
        background-color: white !important;
        color: black;
     }
    
     th {
        box-sizing: border-box;
        border: 1px solid blue;
        height: 40px;
        padding: 0px 12px;
     }
    

    And this example using datatables 1.11.3 looks next in IE11:

    But if change version to 1.10.25 it will look next:

    It seems that problems comes from combination of using box-sizing: border-box; on th element and fixed size of columns added in table configuration.

    Removing box-sizing: border-box; from th element makes table looks correct.

    But, anyway version 1.10.25 doesn't have problem with this attribute but 1.11.3 does.
    Seems previously used approach for columns widht calculation looks more reliable for the described case.

  • allanallan Posts: 63,512Questions: 1Answers: 10,472 Site admin

    Could you give me a link to a test case showing the issue please? For example I don't know what is in your main.css and main.js. If our example is working correctly, then something on the page must be interacting with the table, which is why I'll need a test case to be able to take this any further.

    Allan

  • VolodymyrKVolodymyrK Posts: 12Questions: 2Answers: 0

    Hi , Allan

    I've include all required CSS and JS code to index.html file for convinience.

    See the complete index.html for this case below:

    <html>
        <header>
            <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
            <script type="text/javascript" src="main.js"></script>
            <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.11.3/js/jquery.dataTables.js"></script>
            <style type="text/css">
                table {
                    font-size: 12px;
                    box-sizing: border-box;
                    border-collapse: collapse;
                    background-color: transparent;
                    width: 684.333px;
                }
    
                td {
                    box-sizing: border-box;
                    padding: 0px 12px 0px 12px;
                    border: 1px solid red;
                    background-color: white !important;
                    color: black;
                }
    
                th {
                    box-sizing: border-box;
                    border: 1px solid blue;
                    height: 40px;
                    padding: 0px 12px;
                }
            </style>
        </header>
        <body>
            <p>Header</p>
            <table id="table_id" class="display">
                <thead>
                    <tr>
                        <th></th>
                        <th></th>
                        <th>Head3</th>
                        <th>Head4</th>
                        <th></th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td>text</td>
                        <td>text</td>
                        <td>text</td>
                        <td>text</td>
                        <td><img style="width: 50; height: 20; padding-left: 10px; padding-right: 10px;" alt="1" src="https://cdn-icons-png.flaticon.com/512/5110/5110429.png"></td>
                    </tr>
                    <tr>
                        <td>text</td>
                        <td>text</td>
                        <td>text</td>
                        <td>text</td>
                        <td>22222</td>
                    </tr>
                </tbody>
            </table>
        </body>
        <script>
            this.columns = [];
            this.columns.push({ width: '48px' });
            this.columns.push({ width: '52px' });
            this.columns.push(null);
            this.columns.push(null);
            this.columns.push({ width: '30px' });
    
    
            const config = {
                searching: false,
                scrollY: 200,
                scrollX: true,
                info: false,
                paging: false,
                lengthChange: false,
                jQueryUI: true,
                columns: this.columns,
                autoWidth: false
              };
            $(document).ready( function () {
                $('#table_id').DataTable(config);
            } );
        </script>
    </html>
    

    Just copy this content and create your own index.html. Then use the next test case:

    1) Open the attached index.html using IE11
    Expected result:

    Columns and headers size should be equal.

    Actual result:
    Column size is broken

    2) Edit the attached index.html and change datatables version from 1.11.3 to 1.10.25
    3) Open the attached index.html using IE11
    Actual result 2:
    Column size is ok

  • colincolin Posts: 15,240Questions: 1Answers: 2,599

    Could you create a test case that demonstrates the issue on http://live.datatables.net/ or jsfiddle please, seeing the problem would help us support you more effectively.

    Colin

  • VolodymyrKVolodymyrK Posts: 12Questions: 2Answers: 0

    Colin, sure

    Here is a live example:
    http://live.datatables.net/pocuqeta/1/edit

  • colincolin Posts: 15,240Questions: 1Answers: 2,599

    Thanks for the test case, but it's giving a syntax error on line 1. Please can you take a look and ensure it demonstrates the issue you want help with.

    Colin

  • VolodymyrKVolodymyrK Posts: 12Questions: 2Answers: 0

    Oh, missed it. Here is example without syntax error:

    http://live.datatables.net/hibusixe/1/edit

    Regards,
    Volodymyr

  • colincolin Posts: 15,240Questions: 1Answers: 2,599

    It's still not running: "Uncaught SyntaxError: Unexpected token '<'"

    Colin

  • VolodymyrKVolodymyrK Posts: 12Questions: 2Answers: 0

    Sorry, missed old <script> tag.
    Next example should be good:

    http://live.datatables.net/fupitege/1/edit

    And 'Run with JS should' be clicked to reproduce the issue.

  • colincolin Posts: 15,240Questions: 1Answers: 2,599

    Thanks for fixing that. It's the empty columns that's causing the issues. I found there are two ways to address it,

    1. Change columns: this.columns to be columnDefs: this.columns,
    2. Remove the two this.columns.push(null);

    Colin

  • VolodymyrKVolodymyrK Posts: 12Questions: 2Answers: 0

    Hi Colin, thanks for your suggestions.

    I’ve tried what you recommend but still have issues.

    1) About ‘Change columns: this.columns to be columnDefs: this.columns’

    If I do this this will be incorrect configuration as columnDefs expects array with objects like { targets: [0], width: ‘30px’} while here we have objects like { width: ‘30px’}.

    In addition to the column property options, columnDefs requires a targets property to be set in each definition object (columnDefs.targets).
    https://datatables.net/reference/option/columnDefs
    With this wrong configuration I’m getting "Script error. (line 0)"

    So, I’ve changed the example to have correct configuration, but problems persist. See updated example:
    http://live.datatables.net/canuleso/3/edit

    2) About ‘Remove the two this.columns.push(null);’
    By do this I’ll also get incorrect configuration as documentation says next:

    Note that if you use columns to define your columns, you must have an entry in the array for every single column that you have in your table (these can be null if you don't wish to specify any options).

    https://datatables.net/reference/option/columns
    So, by doing this I’ll have another getting "Script error. (line 0)"

    I still suppose that problems come from getCompletedStyle method which was introduced in 1.11.3.
    Looks this method isn’t full reliable to calculate column width in IE11. Previously used ``$(nSizer).css('width')works more stable in IE11 than window.getComputedStyle(nSizer).width

    I’m able to locally fix this case included to datatables code a fragment which checks browser type and use old method to calculate columns width if browser is IE. This returns an old behavior.
    But as we need to use an official version it is not an option.

    Perhaps, similar fix could be included in datatables if it is acceptable?
    Cause the new method looks problematic for IE11. Potentially it could cause another similar issue related to columns width for some another cases.

    Thanks in advance,
    Volodymyr

  • colincolin Posts: 15,240Questions: 1Answers: 2,599

    This is with the two lines commented out - http://live.datatables.net/fupitege/7/edit . The table is loading as expected for me in IE11. Is that not the case for you?

    Colin

  • VolodymyrKVolodymyrK Posts: 12Questions: 2Answers: 0

    Colin,
    Still having an error with your example and table width is default.

    Same problem as described in my previous comment.

    Volodymyr

  • colincolin Posts: 15,240Questions: 1Answers: 2,599

    Sorry, I apologise, I entirely missed that. I took a better look, and it appears the CSS is missing. Taking your test case under 1 above, I added the CSS file in and it's behaving as expected now in IE11 - see here. I guess the more modern browsers have different defaults that just mean it works.

    Can you take a look, please, and see if that's working for you.

    Colin

  • VolodymyrKVolodymyrK Posts: 12Questions: 2Answers: 0

    Hi Colin,
    Thanks for a new example.
    I’ve checked it but still there are some problem.

    1) Problem is still persisting after resizing
    After the example is opened header and body columns looks equal.
    See example when the right panel has 1000px width:

    But after resizing to 500px header width is broken again:

    So initially size might look good but any resizing breaks it again.

    2) Also, we are using custom CSS for datatables so adding official styles for datatables could be problematic as it could conflict with existing styles and makes the table looks different.

    For example, the initial table has fixed width and looked like this on 1000px width:

    For your example it looks next:

    As you see fixed width doesn’t work and table looks different.

    3) I also see a problem with headers when scrollX and scrollY are active simultaneously.
    By adding them to datatables basic example the initial table looks good with 500px right panel size:

    But after resizing to 1000px we will see next:

    I’m not sure if this is the same issue or related. This is reproduced for Chrome too.
    See live example for this:
    http://live.datatables.net/wuhuvobi/1/edit

    Best Regards,
    Volodymyr

Sign In or Register to comment.