Skip to content

Colored tables, prevent style leaks from nested tables & other table tweaks#26678

Closed
MartijnCuppens wants to merge 21 commits intotwbs:v4-devfrom
MartijnCuppens:tables
Closed

Colored tables, prevent style leaks from nested tables & other table tweaks#26678
MartijnCuppens wants to merge 21 commits intotwbs:v4-devfrom
MartijnCuppens:tables

Conversation

@MartijnCuppens
Copy link
Member

@MartijnCuppens MartijnCuppens commented Jun 6, 2018

Edit: I'm going to review this for v5

  • Border-color styles of table elements (thead, tbody, tfoot, tr, td & th) are inherited from their parent. This allows us to easily modify styles without the generation of a lot of css selectors.
  • Support for tfoot. There will always be a thicker line between thead, tbody & tfoot.
  • Nested .tables don't inherit styles anymore
  • Vertical alignment can be changed with $table-vertical-align
  • $table-colors sass map allows us to easily add or remove colored tables
  • .thead-light and .thead-dark are removed in favor of more universal .table-light and .table-dark (classes generated from $table-colors sass map)
  • Posibility to show/remove top/bottom table border with $table-show-border-top & $table-show-border-bottom
  • The text color of the colored tables is determined by color contrast function (color-yiq())
  • Striped and hover backgrounds are set with box-shadow instead of background-color. This way we don't have to generate all the background colors for colored striped tables and colored hoverable tables.
  • Table row hover states now have transitions (@transition mixin)
  • Striped and hover backgrounds of darker tables (determined by color-yiq()) have lighter rows, so that there is enough contrast.
  • I had to check if a color was dark or light so I added the is-light and is-dark functions. These might come in handy for other purposes in the future.
  • Documentation cleanup and explanation about how the colored tables work added. Copy might need some adjustments.
  • Didn't change anything with the responsive tables.

Known issue:

  • Darker tables use lighter striped and hover backgrounds, but this only works when the class is added to the table. No support for lighter striped and hover backgrounds on the elements inside the table, because too much css must be generated to achieve this.

Also made an interactive codepen demo:
https://codepen.io/MartijnCuppens/pen/jxRJPB

Documentation page:
http://martijncuppens.github.io/tables/docs/4.1/content/tables/

Closes #25842, closes #25685, closes #25675, closes #24529, closes #27312
Related PRs: #25864, #25755, #25677, #24660

@andresgalante
Copy link
Collaborator

Wow! this is a huge PR and at first glance it's pretty fantastic. Thanks a lot @MartijnCuppens

I'll make sure to find time this week to review it.

@MartijnCuppens
Copy link
Member Author

Thanks @andresgalante!

Yeah, I was working on a solution to prevent styles from leaking to nested tables, but this code also influenced the the theming of coloured tables. Before I knew it I was rewriting a lot. The only thing I kept my hands of was the responsive tables (because of #25813).

I think a rewrite like this is needed to make the bootstrap tables more consistent but if you have some improvement suggestions, let me know!

@ysds
Copy link
Contributor

ysds commented Jun 14, 2018

I am concerned about this increase many CSS.

Current:

.table td,
.table th {
  ...
}

After:

.table > thead > tr > td,
.table > thead > tr > th,
.table > tbody > tr > td,
.table > tbody > tr > th,
.table > tfoot > tr > td,
.table > tfoot > tr > th {
  ...
}

@mdo and many people may not like a universal selector for performance reason, but it is effective in this case?

.table > * > * > td,
.table > * > * > th {
  ...
}

@MartijnCuppens
Copy link
Member Author

MartijnCuppens commented Jun 14, 2018

This PR actually decreases the file size of the css files because of the flexible implementation of the coloured tables.

But indeed, using the universal selector would decrease the file size even more (I would keep the tr though). Not sure if there is much of a difference in performance because we still use the child combinator (>) and we're actually decreasing the number of selectors.

@MartijnCuppens
Copy link
Member Author

Some bundlesize stats:

v4 dev (June 14):
./dist/css/bootstrap.css: 22.19KB < maxSize 25KB gzip
./dist/css/bootstrap.min.css: 20.58KB < maxSize 21KB gzip

PR without universal selector:
./dist/css/bootstrap.css: 22.06KB < maxSize 25KB gzip
./dist/css/bootstrap.min.css: 20.45KB < maxSize 21KB gzip

PR with universal selector:
./dist/css/bootstrap.css: 21.98KB < maxSize 25KB gzip
./dist/css/bootstrap.min.css: 20.38KB < maxSize 21KB gzip

@MartijnCuppens
Copy link
Member Author

About the universal selector usage:
I'm quite sure there won't be a a performance drawback if we use this, on the contrary
we might even have a performance improvement. Browsers read selectors from right to left and the child combinator (>) is always used.

Let's analyse this case:

.table > thead > tr > td,
.table > thead > tr > th,
.table > tbody > tr > td,
.table > tbody > tr > th,
.table > tfoot > tr > td,
.table > tfoot > tr > th {
  ...
}

For the first line, the browser searches for all td elements and then checks if the parent is a tr, checks if the tr has a thead parent and checks if the thead has a .table parent. This happens analogously for all 6 lines.

This case:

.table > * > tr > td,
.table > * > tr > th {
  ...
}

For the first line, the browser searches for all td elements and then checks if the parent is a tr, checks if the tr has a parent and checks if that element has a .table parent. This happens analogously for the next line. This actually sounds like an improvement.

Original case:

.table td,
.table th {
  ...
}

For the first line, the browser searches for all td elements and then checks if the parent or a grandparent (not sure if this is the correct term) is a .table. This happens analogously for the next lines. The performance of this might be comparable to the universal selector implementation.

Source: https://www.youtube.com/watch?v=2Rn8an74khk&feature=youtu.be&t=14m28s

I just changed my PR and used the universal selector.

Copy link
Member

@mdo mdo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely appreciate the huge undertaking here, but I didn't get far into this diff—we can't change the selectors like this. It was an intentional change in v4 to simplify the table selectors. Perhaps remove that and let's see where we net out?

@MartijnCuppens
Copy link
Member Author

@mdo, do you want me to remove the child combinator (>) only from the .table or also from .table-sm, .table-bordered, .table-hover,…?

@MartijnCuppens
Copy link
Member Author

@mdo, you're right, this would mean every developer would need to add the .table class to nested tables if they want to update Bootstrap, so I changed the selectors for .table but kept it (for the time being) for .table-sm, .table-bordered, .table-borderless, .table-striped and .table-hover.

For .table-sm, I could understand why we would leak the padding. But for .table-bordered & .table-borderless, there is a problem. We can't add a bordered table inside a borderless table, because .table-borderless overwrites the bordered styling if we don't work with the child combinator (this might be an edge case).

Nested .table-hover may also look weird and this styling can not easily be overwritten. Same for nested .table-striped.

What do you think?

@mdo mdo added v5 and removed v4 labels Mar 13, 2019
@mdo mdo mentioned this pull request Mar 13, 2019
@mdo
Copy link
Member

mdo commented Mar 13, 2019

Closing for now given conflicts and upcoming changes to v5. Opened #28480 to revisit for our next major release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants