# DataTable Width & Column Width

#### Default Width

By default, the table will expand to the width of its container. The width of the columns is determined automatically in order to accommodate the content in the cells.

    using Dash
    using OrderedCollections, DataFrames

    data = OrderedDict(
          "Date" => ["2015-01-01", "2015-10-24", "2016-05-10", "2017-01-10", "2018-05-10", "2018-08-15"],
          "Region" => ["Montreal", "Toronto", "New York City", "Miami", "San Francisco", "London"],
          "Temperature" => [1, -20, 3.512, 4, 10423, -441.2],
          "Humidity" => [10, 20, 30, 40, 50, 60],
          "Pressure" => [2, 10924, 3912, -10, 3591.2, 15],
    )

    df = DataFrame(data)

    app = dash()

    app.layout = dash_datatable(
        data = map(eachrow(df)) do r
          Dict(names(r) .=> values(r))
        end,
        columns=[Dict("name" =>c, "id" => c) for c in names(df)]
    )

    run_server(app, "0.0.0.0", debug=true)

Date | Region | Temperature | Humidity | Pressure
--- | --- | --- | --- | ---
2015-01-01 | Montreal | 1 | 10 | 2
2015-10-24 | Toronto | -20 | 20 | 10924
2016-05-10 | New York City | 3.512 | 30 | 3912
2017-01-10 | Miami | 4 | 40 | -10
2018-05-10 | San Francisco | 10423 | 50 | 3591.2
2018-08-15 | London | -441.2 | 60 | 15

The default styles work well for a small number of columns and short text. However, if you are rendering a large number of columns or cells with long contents, then you'll need to employ one of the following overflow strategies to keep the table within its container.

## Wrapping onto Multiple Lines

If your cells contain contain text with spaces, then you can overflow your content into multiple lines.

`style_cell` updates the styling for the data cells & the header cells. To specify header styles, use `style_header`. To specify data cell styles, use `style_data`.

This example keeps the header on a single line while wrapping the data cells.

    using Dash
    using OrderedCollections, DataFrames

    data_election = OrderedDict(
                "Date" =>
                [
                    "July 12th, 2013 - July 25th, 2013",
                    "July 12th, 2013 - August 25th, 2013",
                    "July 12th, 2014 - August 25th, 2014",
                ],
                "Election Polling Organization" =>
                ["The New York Times", "Pew Research", "The Washington Post"],

            "Rep" => [1, -20, 3.512],
            "Dem" => [10, 20, 30],
            "Ind" => [2, 10924, 3912],

                "Region" =>
                [
                    "Northern New York State to the Southern Appalachian Mountains",
                    "Canada",
                    "Southern Vermont",
                ],

    )

    df = DataFrame(data_election)

    app = dash()

    app.layout = dash_datatable(
        style_data=Dict(
            "whiteSpace" =>  "normal",
            "height" =>  "auto",
        ),
        data = map(eachrow(df)) do r
          Dict(names(r) .=> values(r))
        end,
        columns=[Dict("name" =>c, "id" => c) for c in names(df)],

    )

    run_server(app, "0.0.0.0", debug=true)

Date | Election Polling Organization | Rep | Dem | Ind | Region
--- | --- | --- | --- | --- | ---
July 12th, 2013 - July 25th, 2013 | The New York Times | 1 | 10 | 2 | Northern New York State to the Southern Appalachian Mountains
July 12th, 2013 - August 25th, 2013 | Pew Research | -20 | 20 | 10924 | Canada
July 12th, 2014 - August 25th, 2014 | The Washington Post | 3.512 | 30 | 3912 | Southern Vermont

### Denser Multi-Line Cells with Line-Height

If you are displaying lots of text in your cells, then you may want to make the text appear a little more dense by shortening up the line-height. By default (as above), it's around 22px. Here, it's 15px.

    using Dash
    using OrderedCollections, DataFrames

    data_election = OrderedDict(
                "Date" =>
                [
                    "July 12th, 2013 - July 25th, 2013",
                    "July 12th, 2013 - August 25th, 2013",
                    "July 12th, 2014 - August 25th, 2014",
                ],
                "Election Polling Organization" =>
                ["The New York Times", "Pew Research", "The Washington Post"],

            "Rep" => [1, -20, 3.512],
            "Dem" => [10, 20, 30],
            "Ind" => [2, 10924, 3912],

                "Region" =>
                [
                    "Northern New York State to the Southern Appalachian Mountains",
                    "Canada",
                    "Southern Vermont",
                ],

    )

    df = DataFrame(data_election)

    app = dash()

    app.layout = dash_datatable(
        style_data=Dict(
          "whiteSpace" => "normal",
          "height" => "auto",
          "lineHeight" => "15px"
        ),
        data = map(eachrow(df)) do r
          Dict(names(r) .=> values(r))
        end,
        columns=[Dict("name" =>c, "id" => c) for c in names(df)],

    )

    run_server(app, "0.0.0.0", debug=true)

Date | Election Polling Organization | Rep | Dem | Ind | Region
--- | --- | --- | --- | --- | ---
July 12th, 2013 - July 25th, 2013 | The New York Times | 1 | 10 | 2 | Northern New York State to the Southern Appalachian Mountains
July 12th, 2013 - August 25th, 2013 | Pew Research | -20 | 20 | 10924 | Canada
July 12th, 2014 - August 25th, 2014 | The Washington Post | 3.512 | 30 | 3912 | Southern Vermont

### Wrapping onto Multiple Lines while Constraining the Height of Cells

If your text is really long, then you can constrain the height of the cells and display a tooltip when hovering over the cell.

    using Dash
    using OrderedCollections, DataFrames

    moby_dick_text = [
        "Call me Ishmael. ",
        string(
            "Some years ago- never mind how long precisely- having little or no money ",
            "in my purse, and nothing particular to interest me on shore, ",
            "I thought I would sail about a little and see the watery part of the world. ",
        ),
        "It is a way I have of driving off the spleen and regulating the circulation."
    ]

    moby_dick = OrderedDict(
        "Sentence Number" => [i for i in 1:length(moby_dick_text)],
        "Text" => [i for i in moby_dick_text]
    )

    df = DataFrame(moby_dick)

    app = dash()

    app.layout = dash_datatable(
        style_data=Dict(
            "whiteSpace" =>  "normal",
        ),
        data = Dict.(pairs.(eachrow(df))),
        columns=[Dict("name" =>c, "id" => c) for c in names(df)],
        css=[Dict(
            "selector" =>  ".dash-spreadsheet td div",
            "rule" =>  """
                line-height :  15px;
                max-height :  30px; min-height :  30px; height :  30px;
                display :  block;
                overflow-y :  hidden;
            """
        )],
        tooltip_data=map(eachrow(df)) do r
          Dict(names(r) .=> string.(values(r)))
        end,
        tooltip_duration=nothing,
        style_cell=Dict("textAlign" =>  "left") # left align text in columns for readability

    )

    run_server(app, "0.0.0.0", debug=true)

Sentence Number | Text
--- | ---
1 | Call me Ishmael.
2 | Some years ago- never mind how long precisely- having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world.
3 | It is a way I have of driving off the spleen and regulating the circulation.

Hover over the cells to see the tooltip.

Why the `css`? Fixed height cells are tricky because, by CSS 2.1 rules, the height of a table cell is "the minimum height required by the content". So, here we are setting the height of the cell indirectly by setting the div within the cell.

In this example, we display two lines of data by setting the `line-height` to be 15px and the height of each cell to be 30px. The second sentence is cut off.

There are a few limitations with this method:

1. It is not possible to display ellipses with this method.
2. It is not possible to set a max-height. All of the cells need to be the same height.

Subscribe to plotly/dash-table#737 for updates or other workarounds on this issue.

## Overflowing Into Ellipses

Alternatively, you can keep the content on a single line but display a set of ellipses if the content is too long to fit into the cell.

Here, `max-width` is set to 0. It could be any number, the only important thing is that it is supplied. The behaviour will be the same whether it is 0 or 50.

If you want to just hide the content instead of displaying ellipses, then set `textOverflow` to `'clip'` instead of `'ellipsis'`.

    using Dash
    using OrderedCollections, DataFrames

    data_election = OrderedDict(
                "Date" =>
                [
                    "July 12th, 2013 - July 25th, 2013",
                    "July 12th, 2013 - August 25th, 2013",
                    "July 12th, 2014 - August 25th, 2014",
                ],
                "Election Polling Organization" =>
                ["The New York Times", "Pew Research", "The Washington Post"],

            "Rep" => [1, -20, 3.512],
            "Dem" => [10, 20, 30],
            "Ind" => [2, 10924, 3912],

                "Region" =>
                [
                    "Northern New York State to the Southern Appalachian Mountains",
                    "Canada",
                    "Southern Vermont",
                ],

    )

    df = DataFrame(data_election)

    app = dash()

    app.layout = dash_datatable(
        data = map(eachrow(df)) do r
          Dict(names(r) .=> values(r))
        end,
        columns=[Dict("name" =>c, "id" => c) for c in names(df)],
        style_cell=Dict(
            "overflow" => "hidden",
            "textOverflow" => "ellipsis",
            "maxWidth" => 0
        )

    )

    run_server(app, "0.0.0.0", debug=true)

Date | Election Polling Organization | Rep | Dem | Ind | Region
--- | --- | --- | --- | --- | ---
July 12th, 2013 - July 25th, 2013 | The New York Times | 1 | 10 | 2 | Northern New York State to the Southern Appalachian Mountains
July 12th, 2013 - August 25th, 2013 | Pew Research | -20 | 20 | 10924 | Canada
July 12th, 2014 - August 25th, 2014 | The Washington Post | 3.512 | 30 | 3912 | Southern Vermont

> In the example above, ellipsis are not displayed for the header. We consider this a bug, subscribe to plotly/dash-table#735 for updates.

### Ellipses & Tooltips

If you are display text data that is cut off by ellipses, then you can include tooltips so that the full text appears on hover.

By setting `tooltip_duration` to `None`, the tooltip will persist as long as the mouse pointer is above the cell, and it will disappear when the pointer moves away. You can override this by passing in a number in milliseconds (e.g. 2000 if you want it to disappear after two seconds).

    using Dash
    using OrderedCollections, DataFrames

    data_election = OrderedDict(
                "Date" =>
                [
                    "July 12th, 2013 - July 25th, 2013",
                    "July 12th, 2013 - August 25th, 2013",
                    "July 12th, 2014 - August 25th, 2014",
                ],
                "Election Polling Organization" =>
                ["The New York Times", "Pew Research", "The Washington Post"],

            "Rep" => [1, -20, 3.512],
            "Dem" => [10, 20, 30],
            "Ind" => [2, 10924, 3912],

                "Region" =>
                [
                    "Northern New York State to the Southern Appalachian Mountains",
                    "Canada",
                    "Southern Vermont",
                ],

    )

    df = DataFrame(data_election)

    app = dash()

    app.layout = dash_datatable(
        data = map(eachrow(df)) do r
          Dict(names(r) .=> values(r))
        end,
        columns=[Dict("name" =>c, "id" => c) for c in names(df)],
        style_cell=Dict(
            "overflow" => "hidden",
            "textOverflow" => "ellipsis",
            "maxWidth" => 0
        ),
        tooltip_data=map(eachrow(df)) do r
          Dict(names(r) .=> string.(values(r)))
        end,
        tooltip_duration=nothing

    )

    run_server(app, "0.0.0.0", debug=true)

Date | Election Polling Organization | Rep | Dem | Ind | Region
--- | --- | --- | --- | --- | ---
July 12th, 2013 - July 25th, 2013 | The New York Times | 1 | 10 | 2 | Northern New York State to the Southern Appalachian Mountains
July 12th, 2013 - August 25th, 2013 | Pew Research | -20 | 20 | 10924 | Canada
July 12th, 2014 - August 25th, 2014 | The Washington Post | 3.512 | 30 | 3912 | Southern Vermont

## Horizontal Scroll

Instead of trying to fit all of the content in the container, you could overflow the entire container into a scrollable container.

    using Dash
    using OrderedCollections, DataFrames

    data_election = OrderedDict(
                "Date" =>
                [
                    "July 12th, 2013 - July 25th, 2013",
                    "July 12th, 2013 - August 25th, 2013",
                    "July 12th, 2014 - August 25th, 2014",
                ],
                "Election Polling Organization" =>
                ["The New York Times", "Pew Research", "The Washington Post"],

            "Rep" => [1, -20, 3.512],
            "Dem" => [10, 20, 30],
            "Ind" => [2, 10924, 3912],

                "Region" =>
                [
                    "Northern New York State to the Southern Appalachian Mountains",
                    "Canada",
                    "Southern Vermont",
                ],

    )

    df = DataFrame(data_election)

    app = dash()

    app.layout = dash_datatable(
        data = map(eachrow(df)) do r
          Dict(names(r) .=> values(r))
        end,
        columns=[Dict("name" =>c, "id" => c) for c in names(df)],
        style_table=Dict("overflowX" => "auto"),

    )

    run_server(app, "0.0.0.0", debug=true)

Date | Election Polling Organization | Rep | Dem | Ind | Region
--- | --- | --- | --- | --- | ---
July 12th, 2013 - July 25th, 2013 | The New York Times | 1 | 10 | 2 | Northern New York State to the Southern Appalachian Mountains
July 12th, 2013 - August 25th, 2013 | Pew Research | -20 | 20 | 10924 | Canada
July 12th, 2014 - August 25th, 2014 | The Washington Post | 3.512 | 30 | 3912 | Southern Vermont

Note how we haven't explicitly set the width of the individual columns yet. The widths of the columns have been computed dynamically depending on the width of the table and the width of the cell's contents. In the example above, by providing a scrollbar, we're effectively giving the table as much width as it needs in order to fit the entire width of the cell contents on a single line.

### Horizontal Scroll with Fixed-Width Columns & Cell Wrapping

Alternatively, you can fix the width of each column by adding `width`. In this case, the column's width will be constant, even if its contents are shorter or wider.

    using Dash
    using OrderedCollections, DataFrames

    data_election = OrderedDict(
                "Date" =>
                [
                    "July 12th, 2013 - July 25th, 2013",
                    "July 12th, 2013 - August 25th, 2013",
                    "July 12th, 2014 - August 25th, 2014",
                ],
                "Election Polling Organization" =>
                ["The New York Times", "Pew Research", "The Washington Post"],

            "Rep" => [1, -20, 3.512],
            "Dem" => [10, 20, 30],
            "Ind" => [2, 10924, 3912],

                "Region" =>
                [
                    "Northern New York State to the Southern Appalachian Mountains",
                    "Canada",
                    "Southern Vermont",
                ],

    )

    df = DataFrame(data_election)

    app = dash()

    app.layout = dash_datatable(
        data = map(eachrow(df)) do r
          Dict(names(r) .=> values(r))
        end,
        columns=[Dict("name" =>c, "id" => c) for c in names(df)],
        style_table=Dict("overflowX" =>  "auto"),
        style_cell=Dict(
            "height" =>  "auto",
            # all three widths are needed
            "minWidth" =>  "180px", "width" =>  "180px", "maxWidth" =>  "180px",
            "whiteSpace" =>  "normal"
        ),

    )

    run_server(app, "0.0.0.0", debug=true)

Date | Election Polling Organization | Rep | Dem | Ind | Region
--- | --- | --- | --- | --- | ---
July 12th, 2013 - July 25th, 2013 | The New York Times | 1 | 10 | 2 | Northern New York State to the Southern Appalachian Mountains
July 12th, 2013 - August 25th, 2013 | Pew Research | -20 | 20 | 10924 | Canada
July 12th, 2014 - August 25th, 2014 | The Washington Post | 3.512 | 30 | 3912 | Southern Vermont

### Horizontal Scroll with Fixed-Width & Ellipses

    using Dash
    using OrderedCollections, DataFrames

    data_election = OrderedDict(
                "Date" =>
                [
                    "July 12th, 2013 - July 25th, 2013",
                    "July 12th, 2013 - August 25th, 2013",
                    "July 12th, 2014 - August 25th, 2014",
                ],
                "Election Polling Organization" =>
                ["The New York Times", "Pew Research", "The Washington Post"],

            "Rep" => [1, -20, 3.512],
            "Dem" => [10, 20, 30],
            "Ind" => [2, 10924, 3912],

                "Region" =>
                [
                    "Northern New York State to the Southern Appalachian Mountains",
                    "Canada",
                    "Southern Vermont",
                ],

    )

    df = DataFrame(data_election)

    app = dash()

    app.layout = dash_datatable(
        data = map(eachrow(df)) do r
          Dict(names(r) .=> values(r))
        end,
        columns=[Dict("name" =>c, "id" => c) for c in names(df)],
        style_table=Dict("overflowX" =>  "auto"),
        style_cell=Dict(
            # all three widths are needed
            "minWidth" =>  "180px", "width" =>  "180px", "maxWidth" =>  "180px",
            "overflow" =>  "hidden",
            "textOverflow" =>  "ellipsis",
        ),

    )

    run_server(app, "0.0.0.0", debug=true)

Date | Election Polling Organization | Rep | Dem | Ind | Region
--- | --- | --- | --- | --- | ---
July 12th, 2013 - July 25th, 2013 | The New York Times | 1 | 10 | 2 | Northern New York State to the Southern Appalachian Mountains
July 12th, 2013 - August 25th, 2013 | Pew Research | -20 | 20 | 10924 | Canada
July 12th, 2014 - August 25th, 2014 | The Washington Post | 3.512 | 30 | 3912 | Southern Vermont

### Horizontal Scrolling via Fixed Columns

You can also add a horizontal scrollbar to your table by fixing the leftmost columns with `fixed_columns`.

    using Dash
    using OrderedCollections, DataFrames

    data_election = OrderedDict(
                "Date" =>
                [
                    "July 12th, 2013 - July 25th, 2013",
                    "July 12th, 2013 - August 25th, 2013",
                    "July 12th, 2014 - August 25th, 2014",
                ],
                "Election Polling Organization" =>
                ["The New York Times", "Pew Research", "The Washington Post"],

            "Rep" => [1, -20, 3.512],
            "Dem" => [10, 20, 30],
            "Ind" => [2, 10924, 3912],

                "Region" =>
                [
                    "Northern New York State to the Southern Appalachian Mountains",
                    "Canada",
                    "Southern Vermont",
                ],

    )

    df = DataFrame(data_election)

    app = dash()

    app.layout = dash_datatable(
        data = map(eachrow(df)) do r
          Dict(names(r) .=> values(r))
        end,
        columns=[Dict("name" =>c, "id" => c) for c in names(df)],
        fixed_columns=Dict("headers" =>  true, "data" =>  1),
        style_table=Dict("minWidth" =>  "100%")

    )

    run_server(app, "0.0.0.0", debug=true)

Date |  |  |  |  |
--- | --- | --- | --- | --- | ---
July 12th, 2013 - July 25th, 2013 | The New York Times | 1 | 10 | 2 | Northern New York State to the Southern Appalachian Mountains
July 12th, 2013 - August 25th, 2013 | Pew Research | -20 | 20 | 10924 | Canada
July 12th, 2014 - August 25th, 2014 | The Washington Post | 3.512 | 30 | 3912 | Southern Vermont

| Election Polling Organization | Rep | Dem | Ind | Region
--- | --- | --- | --- | --- | ---
July 12th, 2013 - July 25th, 2013 | The New York Times | 1 | 10 | 2 | Northern New York State to the Southern Appalachian Mountains
July 12th, 2013 - August 25th, 2013 | Pew Research | -20 | 20 | 10924 | Canada
July 12th, 2014 - August 25th, 2014 | The Washington Post | 3.512 | 30 | 3912 | Southern Vermont

Here is the same example but with fixed-width cells & ellipses.

    using Dash
    using OrderedCollections, DataFrames

    data_election = OrderedDict(
                "Date" =>
                [
                    "July 12th, 2013 - July 25th, 2013",
                    "July 12th, 2013 - August 25th, 2013",
                    "July 12th, 2014 - August 25th, 2014",
                ],
                "Election Polling Organization" =>
                ["The New York Times", "Pew Research", "The Washington Post"],

            "Rep" => [1, -20, 3.512],
            "Dem" => [10, 20, 30],
            "Ind" => [2, 10924, 3912],

                "Region" =>
                [
                    "Northern New York State to the Southern Appalachian Mountains",
                    "Canada",
                    "Southern Vermont",
                ],

    )

    df = DataFrame(data_election)

    app = dash()

    app.layout = dash_datatable(
        data = map(eachrow(df)) do r
          Dict(names(r) .=> values(r))
        end,
        columns=[Dict("name" =>c, "id" => c) for c in names(df)],
        fixed_columns=Dict( "headers" =>  true, "data" =>  1 ),
        style_table=Dict("minWidth" =>  "100%"),
        style_cell=Dict(
            # all three widths are needed
            "minWidth" =>  "180px", "width" =>  "180px", "maxWidth" =>  "180px",
            "overflow" =>  "hidden",
            "textOverflow" =>  "ellipsis",
        )

    )

    run_server(app, "0.0.0.0", debug=true)

Date |  |  |  |  |
--- | --- | --- | --- | --- | ---
July 12th, 2013 - July 25th, 2013 | The New York Times | 1 | 10 | 2 | Northern New York State to the Southern Appalachian Mountains
July 12th, 2013 - August 25th, 2013 | Pew Research | -20 | 20 | 10924 | Canada
July 12th, 2014 - August 25th, 2014 | The Washington Post | 3.512 | 30 | 3912 | Southern Vermont

| Election Polling Organization | Rep | Dem | Ind | Region
--- | --- | --- | --- | --- | ---
July 12th, 2013 - July 25th, 2013 | The New York Times | 1 | 10 | 2 | Northern New York State to the Southern Appalachian Mountains
July 12th, 2013 - August 25th, 2013 | Pew Research | -20 | 20 | 10924 | Canada
July 12th, 2014 - August 25th, 2014 | The Washington Post | 3.512 | 30 | 3912 | Southern Vermont

## Setting Column Widths

### Percentage Based Widths

The widths of individual columns can be supplied through the `style_cell_conditional` property. These widths can be specified as percentages or fixed pixels.

    using Dash
    using OrderedCollections, DataFrames

    data = OrderedDict(
          "Date" => ["2015-01-01", "2015-10-24", "2016-05-10", "2017-01-10", "2018-05-10", "2018-08-15"],
          "Region" => ["Montreal", "Toronto", "New York City", "Miami", "San Francisco", "London"],
          "Temperature" => [1, -20, 3.512, 4, 10423, -441.2],
          "Humidity" => [10, 20, 30, 40, 50, 60],
          "Pressure" => [2, 10924, 3912, -10, 3591.2, 15],
    )

    df = DataFrame(data)

    app = dash()

    app.layout = dash_datatable(
        data = map(eachrow(df)) do r
          Dict(names(r) .=> values(r))
        end,
        columns=[Dict("name" =>c, "id" => c) for c in names(df)],
        style_cell_conditional=[
            Dict("if" =>  Dict("column_id" =>  "Date"),
             "width" =>  "30%"),
             Dict("if" =>  Dict("column_id" =>  "Region"),
             "width" =>  "30%"),
        ]

    )

    run_server(app, "0.0.0.0", debug=true)

Date | Region | Temperature | Humidity | Pressure
--- | --- | --- | --- | ---
2015-01-01 | Montreal | 1 | 10 | 2
2015-10-24 | Toronto | -20 | 20 | 10924
2016-05-10 | New York City | 3.512 | 30 | 3912
2017-01-10 | Miami | 4 | 40 | -10
2018-05-10 | San Francisco | 10423 | 50 | 3591.2
2018-08-15 | London | -441.2 | 60 | 15

    using Dash
    using OrderedCollections, DataFrames

    data = OrderedDict(
          "Date" => ["2015-01-01", "2015-10-24", "2016-05-10", "2017-01-10", "2018-05-10", "2018-08-15"],
          "Region" => ["Montreal", "Toronto", "New York City", "Miami", "San Francisco", "London"],
          "Temperature" => [1, -20, 3.512, 4, 10423, -441.2],
          "Humidity" => [10, 20, 30, 40, 50, 60],
          "Pressure" => [2, 10924, 3912, -10, 3591.2, 15],
    )

    df = DataFrame(data)

    app = dash()

    app.layout = dash_datatable(
        data = map(eachrow(df)) do r
          Dict(names(r) .=> values(r))
        end,
        columns=[Dict("name" =>c, "id" => c) for c in names(df)],
        style_cell_conditional=[
            Dict("if" =>  Dict("column_id" =>  "Date"),
             "width" =>  "30%"),
             Dict("if" =>  Dict("column_id" =>  "Region"),
             "width" =>  "30%"),
        ]

    )

    run_server(app, "0.0.0.0", debug=true)

Date | Region | Temperature | Humidity | Pressure
--- | --- | --- | --- | ---
2015-01-01 | Montreal | 1 | 10 | 2
2015-10-24 | Toronto | -20 | 20 | 10924
2016-05-10 | New York City | 3.512 | 30 | 3912
2017-01-10 | Miami | 4 | 40 | -10
2018-05-10 | San Francisco | 10423 | 50 | 3591.2
2018-08-15 | London | -441.2 | 60 | 15

By default, the column width is the maximum of the percentage given and the width of the content. So, if the content in the column is wide, the column may be wider than the percentage given. This prevents overflow.

In the example below, note the first column is actually wider than 10%; if it were shorter, the text "New York City" would overflow.

    using Dash
    using OrderedCollections, DataFrames

    data = OrderedDict(
          "Date" => ["2015-01-01", "2015-10-24", "2016-05-10", "2017-01-10", "2018-05-10", "2018-08-15"],
          "Region" => ["Montreal", "Toronto", "New York City", "Miami", "San Francisco", "London"],
          "Temperature" => [1, -20, 3.512, 4, 10423, -441.2],
          "Humidity" => [10, 20, 30, 40, 50, 60],
          "Pressure" => [2, 10924, 3912, -10, 3591.2, 15],
    )

    df = DataFrame(data)

    df = select!(df, Not(:Date))

    app = dash()

    app.layout = dash_datatable(
        data = map(eachrow(df)) do r
          Dict(names(r) .=> values(r))
        end,
        columns=[Dict("name" =>c, "id" => c) for c in names(df)],
        style_cell_conditional=[
                Dict("if" =>  Dict("column_id" =>  "Region"),
                 "width" =>  "10%")
            ]

    )

    run_server(app, "0.0.0.0", debug=true)

10%

Region | Temperature | Humidity | Pressure
--- | --- | --- | ---
Montreal | 1 | 10 | 2
Toronto | -20 | 20 | 10924
New York City | 3.512 | 30 | 3912
Miami | 4 | 40 | -10
San Francisco | 10423 | 50 | 3591.2
London | -441.2 | 60 | 15

To force columns to be a certain width (even if that causes overflow) use `table-layout: fixed`.

### Percentage Based Widths and `table-layout: fixed`

If you want all columns to have the same percentage-based width, use `style_data` and `table-layout: fixed`.

    using Dash
    using OrderedCollections, DataFrames

    data_election = OrderedDict(
                "Date" =>
                [
                    "July 12th, 2013 - July 25th, 2013",
                    "July 12th, 2013 - August 25th, 2013",
                    "July 12th, 2014 - August 25th, 2014",
                ],
                "Election Polling Organization" =>
                ["The New York Times", "Pew Research", "The Washington Post"],

            "Rep" => [1, -20, 3.512],
            "Dem" => [10, 20, 30],
            "Ind" => [2, 10924, 3912],

                "Region" =>
                [
                    "Northern New York State to the Southern Appalachian Mountains",
                    "Canada",
                    "Southern Vermont",
                ],

    )

    df = DataFrame(data_election)

    app = dash()

    app.layout = dash_datatable(
        data = map(eachrow(df)) do r
          Dict(names(r) .=> values(r))
        end,
        columns=[Dict("name" =>c, "id" => c) for c in names(df)],
        css=[Dict("selector" =>  "table", "rule" =>  "table-layout =>  fixed")],
        style_cell=Dict(
            "width" =>  "$(ncol(df))%",
            "textOverflow" =>  "ellipsis",
            "overflow" =>  "hidden"
        )

    )

    run_server(app, "0.0.0.0", debug=true)

Date | Region | Temperature | Humidity | Pressure
--- | --- | --- | --- | ---
2015-01-01 | Montreal | 1 | 10 | 2
2015-10-24 | Toronto | -20 | 20 | 10924
2016-05-10 | New York City | 3.512 | 30 | 3912
2017-01-10 | Miami | 4 | 40 | -10
2018-05-10 | San Francisco | 10423 | 50 | 3591.2
2018-08-15 | London | -441.2 | 60 | 15

Setting consistent percentage-based widths is a good option if you are using `virtualization`, sorting (`sort_action`), or `filtering` (`filter_action`). Without fixed column widths, the table will dynamically resize the columns depending on the width of the data that is displayed.

Limitations

1. Percentage-based widths is not available with `fixed_rows` & `table-layout: fixed`. See plotly/dash-table#745
2. Percentage-based widths with `fixed_rows` and without `table-layout: fixed` has some issues when resizing the window. See plotly/dash-table#747

### Individual Column Widths with Pixels

In this example, we set three columns to have fixed-widths. The remaining two columns will be take up the remaining space.

    using Dash
    using OrderedCollections, DataFrames

    data = OrderedDict(
          "Date" => ["2015-01-01", "2015-10-24", "2016-05-10", "2017-01-10", "2018-05-10", "2018-08-15"],
          "Region" => ["Montreal", "Toronto", "New York City", "Miami", "San Francisco", "London"],
          "Temperature" => [1, -20, 3.512, 4, 10423, -441.2],
          "Humidity" => [10, 20, 30, 40, 50, 60],
          "Pressure" => [2, 10924, 3912, -10, 3591.2, 15],
    )

    df = DataFrame(data)

    app = dash()

    app.layout = dash_datatable(
        data = map(eachrow(df)) do r
          Dict(names(r) .=> values(r))
        end,
        columns=[Dict("name" =>c, "id" => c) for c in names(df)],
        style_cell_conditional=[
            Dict("if" =>  Dict("column_id" =>  "Temperature"),
             "width" =>  "130px"),
            Dict("if" =>  Dict("column_id" =>  "Humidity"),
             "width" =>  "130px"),
            Dict("if" =>  Dict("column_id" =>  "Pressure"),
             "width" =>  "130px"),
        ]

    )

    run_server(app, "0.0.0.0", debug=true)

Date | Region | Temperature | Humidity | Pressure
--- | --- | --- | --- | ---
2015-01-01 | Montreal | 1 | 10 | 2
2015-10-24 | Toronto | -20 | 20 | 10924
2016-05-10 | New York City | 3.512 | 30 | 3912
2017-01-10 | Miami | 4 | 40 | -10
2018-05-10 | San Francisco | 10423 | 50 | 3591.2
2018-08-15 | London | -441.2 | 60 | 15

### Overriding a Single Column's Width

You can set the width of all of the columns with `style_data` and override a single column with `style_cell_conditional`.

    using Dash
    using OrderedCollections, DataFrames

    data = OrderedDict(
          "Date" => ["2015-01-01", "2015-10-24", "2016-05-10", "2017-01-10", "2018-05-10", "2018-08-15"],
          "Region" => ["Montreal", "Toronto", "New York City", "Miami", "San Francisco", "London"],
          "Temperature" => [1, -20, 3.512, 4, 10423, -441.2],
          "Humidity" => [10, 20, 30, 40, 50, 60],
          "Pressure" => [2, 10924, 3912, -10, 3591.2, 15],
    )

    df = DataFrame(data)

    app = dash()

    app.layout = dash_datatable(
        data = map(eachrow(df)) do r
          Dict(names(r) .=> values(r))
        end,
        columns=[Dict("name" =>c, "id" => c) for c in names(df)],
        style_data=Dict(
            "width" =>  "100px",
            "maxWidth" =>  "100px",
            "minWidth" =>  "100px",
        ),
        style_cell_conditional=[
            Dict(
                "if" =>  ("column_id" =>  "Region"),
                "width" =>  "250px"
            ),
        ],
        style_table=Dict(
            "overflowX" =>  "auto"
        )

    )

    run_server(app, "0.0.0.0", debug=true)

Date | Region | Temperature | Humidity | Pressure
--- | --- | --- | --- | ---
2015-01-01 | Montreal | 1 | 10 | 2
2015-10-24 | Toronto | -20 | 20 | 10924
2016-05-10 | New York City | 3.512 | 30 | 3912
2017-01-10 | Miami | 4 | 40 | -10
2018-05-10 | San Francisco | 10423 | 50 | 3591.2
2018-08-15 | London | -441.2 | 60 | 15