Components: Use Data tables columns padding following Material guidelines

Created on 28 Dec 2017  路  10Comments  路  Source: angular/components

Bug, feature request, or proposal:

Proposal. Current material style data table has no padding between columns, only at the start of the first column and the end of the last one (left and right padding at row level).

Material guidelines request a 56dp padding between all columns (Column padding section). I personally think 24dp is enough. Data tables are a better designed for desktop interaction, so 24dp sounds right for a non touch UI.

On the guidelines example there are some columns with 24dp padding (the checkbox and description columns) and the pure numeric columns use 56dp. Maybe a new column property to indicate small or large paddings could help.

What is the expected behavior?

Data table columns should have a default padding

What is the current behavior?

Data table columns doesn't have padding

What are the steps to reproduce?

https://stackblitz.com/edit/angular-sbmhet

What is the use-case or motivation for changing an existing behavior?

A better default for columns padding. Currently all tables should be CSS styled to set the proper paddings. If an input property is added, better, the designer could choose the two recommended column paddings at template level without CSS

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

Angular 5.1.0 and Material 5.0 as examples currently published on https://material.angular.io/components/table/overview

Is there anything else we should know?

Fixed in MDC P3 materiatable feature material spec

Most helpful comment

How often do the material specs change?

The padding for the first column should be 16px.
And the header row should have 48px height.
( https://material.io/design/components/data-tables.html#specs )

Angular materials uses 24px padding for the first column, and 56px header height.

Also the specs say _"By default, there is 56dp of padding between columns"_. But that's only half of the story. If you look at the provided screenshots, you'll see that sort arrows (angular sort arrow measures 12px width + 6px margin = 18px ) must be ignored in this calculation. I've done this using padding-left: 16px and padding-right: 40px, and then another style depending on [mat-sort-header] and wether [arrowposition="before"] is present ( 16px-18px=-2px 馃槥 => padding-left: 0px; ) or not ( 40px-18px=22px => padding-right: 22px; ).
I use padding-left: 16px and padding-right: 40px as default, because the first column should have padding-left: 16px, too. And in the specs there are some examples with a vertical divider which also has 16px padding.

I'm now using these styles:

.mat-table {

    .mat-header-row {
        height: 48px;
    }

    .mat-header-cell {
        padding-left: 16px;
        padding-right: 40px;

        &:first-of-type {
            padding-left: 16px;
        }

        &:last-of-type {
            padding-right: 16px;

            &[mat-sort-header]:not([arrowposition="before"]) {
                padding-right: 16px;
            }
        }

        &[mat-sort-header] {

            &[arrowposition="before"] {
                padding-left: 0px;
            }

            &:not([arrowposition="before"]) {
                padding-right: 22px;
            }

        }

        &>.mat-sort-header-container {
            display: inline-flex;
        }
    }

    .mat-cell {
        padding-left: 16px;
        padding-right: 40px;
        white-space: nowrap;

        &:first-of-type {
            padding-left: 16px;
        }

        &:last-of-type {
            padding-right: 16px;
        }
    }

    .mat-footer-cell {
        padding-left: 16px;
        padding-right: 40px;

        &:first-of-type {
            padding-left: 16px;
        }

        &:last-of-type {
            padding-right: 16px;
        }

        .mat-paginator {
            margin-left: -16px;
            margin-right: -16px;
        }
    }
}

Extra CSS for maximizing a column:

.mat-column-mymaximizedcolumn {
    width: 100%;
}

Extra CSS for checkbox columns:

.mat-column-select {
    width: 16px;

    &.mat-cell, &.mat-header-cell, &.mat-footer-cell {
        padding-right: 16px; // fix z-index issue when using sticky header / footer
        padding-left: 20px;
    }

    &.mat-cell:first-of-type, &.mat-header-cell:first-of-type, &.mat-footer-cell:first-of-type {
        padding-left: 20px;
    }

    +.mat-cell, +.mat-header-cell, +.mat-footer-cell {
        padding-left: 0; // fix z-index issue when using sticky header / footer
    }
}

Extra CSS for mat-icon-button columns:

.mat-column-actions {
    &.mat-cell {
        padding-left: 8px;
        padding-right: 32px;

        &:last-of-type {
            padding-left: 8px;
            padding-right: 8px;
        }
    }
}

It's still not 100% accurate, because angular material sort arrows use 12px + 6px margin, so I would have to use padding-left: -2px when arrowposition="before", which of course doesn't work. But this CSS is getting really close, I think.

Here you can see it in action: https://stackblitz.com/edit/components-issue-dfew2d

All 10 comments

Has this been updated yet? / Is there a way to add padding between cells?

I'm looking at the spec drawings in the same docs @robmv referenced:
https://material.io/design/components/data-tables.html#specs

The 56dp seems to refer to column headings only, not to table row cells.

The spec drawing shows a 12px padding between the checkbox of one column to the text of the next column. The checkbox is related to the text, so it may be closer for that reason.
It also shows a 16px padding between the columns (see left of column "Text column")

Part of the issue is the material spec doesn't consider tables to have long values in any columns. Is this implying that tables should only be simple values for simplicity, combined with another display format for extended views of data? I'm not sure that's practical in a data driven application, but it may be the intention.

We've solved this in an application with this css.

mat-cell, .mat-cell {
  display:block; // flex prevents padding from working
  min-height:auto; // overrides the 'inherit' that set the min height of the row
  padding: 12px 16px 12px 0;
}

This has been tested some, but not extensively. Try this out and report back how it works in your application.

Hi, @michael-lang!
Got your css but had to remove "display:block" as it was putting columns in rows.
Thanks for sharing it.

I've spent the last hour trying to make this work with layout layout-padding and flex to no avail before I found this. This is really important. Can we get an eta?

I could only get this to work with !important, as the mat- css is written into a style tag in the html and my styles.scss will not override otherwise. There must be a better way.

mat-cell,
.mat-cell,
mat-footer-cell,
.mat-footer-cell,
mat-header-cell .mat-header-cell {
  padding: 0.75rem !important;
}

I could only get this to work with !important, as the mat- css is written into a style tag in the html and my styles.scss will not override otherwise. There must be a better way.

mat-cell,
.mat-cell,
mat-footer-cell,
.mat-footer-cell,
mat-header-cell .mat-header-cell {
  padding: 0.75rem !important;
}

just a heads up, you're missing a comma between mat-header-cell and .mat-header-cell

Thanks though! I ended up just doing this for now.

Hi, @michael-lang!
Got your css but had to remove "display:block" as it was putting columns in rows.
Thanks for sharing it.

You can set

.mat-header-row, .mat-row {
    display: flex;
} 

and in this way everything looks fine

Hi, @michael-lang!
Got your css but had to remove "display:block" as it was putting columns in rows.
Thanks for sharing it.

You can set

.mat-header-row, .mat-row {
    display: flex;
} 

and in this way everything looks fine

But, I don't feel good here 馃敟 馃敟 馃敟

How often do the material specs change?

The padding for the first column should be 16px.
And the header row should have 48px height.
( https://material.io/design/components/data-tables.html#specs )

Angular materials uses 24px padding for the first column, and 56px header height.

Also the specs say _"By default, there is 56dp of padding between columns"_. But that's only half of the story. If you look at the provided screenshots, you'll see that sort arrows (angular sort arrow measures 12px width + 6px margin = 18px ) must be ignored in this calculation. I've done this using padding-left: 16px and padding-right: 40px, and then another style depending on [mat-sort-header] and wether [arrowposition="before"] is present ( 16px-18px=-2px 馃槥 => padding-left: 0px; ) or not ( 40px-18px=22px => padding-right: 22px; ).
I use padding-left: 16px and padding-right: 40px as default, because the first column should have padding-left: 16px, too. And in the specs there are some examples with a vertical divider which also has 16px padding.

I'm now using these styles:

.mat-table {

    .mat-header-row {
        height: 48px;
    }

    .mat-header-cell {
        padding-left: 16px;
        padding-right: 40px;

        &:first-of-type {
            padding-left: 16px;
        }

        &:last-of-type {
            padding-right: 16px;

            &[mat-sort-header]:not([arrowposition="before"]) {
                padding-right: 16px;
            }
        }

        &[mat-sort-header] {

            &[arrowposition="before"] {
                padding-left: 0px;
            }

            &:not([arrowposition="before"]) {
                padding-right: 22px;
            }

        }

        &>.mat-sort-header-container {
            display: inline-flex;
        }
    }

    .mat-cell {
        padding-left: 16px;
        padding-right: 40px;
        white-space: nowrap;

        &:first-of-type {
            padding-left: 16px;
        }

        &:last-of-type {
            padding-right: 16px;
        }
    }

    .mat-footer-cell {
        padding-left: 16px;
        padding-right: 40px;

        &:first-of-type {
            padding-left: 16px;
        }

        &:last-of-type {
            padding-right: 16px;
        }

        .mat-paginator {
            margin-left: -16px;
            margin-right: -16px;
        }
    }
}

Extra CSS for maximizing a column:

.mat-column-mymaximizedcolumn {
    width: 100%;
}

Extra CSS for checkbox columns:

.mat-column-select {
    width: 16px;

    &.mat-cell, &.mat-header-cell, &.mat-footer-cell {
        padding-right: 16px; // fix z-index issue when using sticky header / footer
        padding-left: 20px;
    }

    &.mat-cell:first-of-type, &.mat-header-cell:first-of-type, &.mat-footer-cell:first-of-type {
        padding-left: 20px;
    }

    +.mat-cell, +.mat-header-cell, +.mat-footer-cell {
        padding-left: 0; // fix z-index issue when using sticky header / footer
    }
}

Extra CSS for mat-icon-button columns:

.mat-column-actions {
    &.mat-cell {
        padding-left: 8px;
        padding-right: 32px;

        &:last-of-type {
            padding-left: 8px;
            padding-right: 8px;
        }
    }
}

It's still not 100% accurate, because angular material sort arrows use 12px + 6px margin, so I would have to use padding-left: -2px when arrowposition="before", which of course doesn't work. But this CSS is getting really close, I think.

Here you can see it in action: https://stackblitz.com/edit/components-issue-dfew2d

::ng-deep .mat-row{
padding : 25px;
}

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jelbourn picture jelbourn  路  3Comments

shlomiassaf picture shlomiassaf  路  3Comments

michaelb-01 picture michaelb-01  路  3Comments

constantinlucian picture constantinlucian  路  3Comments

julianobrasil picture julianobrasil  路  3Comments