JSFiddle - React, Tailwind, and code Playground
by bodine30
HTML
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.3/normalize.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.css">
<table class="table-grid">
<thead>
<tr>
<th sort-field="id" class="sortable">Row 1</th>
<th sort-field="street" class="sortable">Title 2</th>
<th>Title 3</th>
</tr>
</thead>
<tbody>
<tr>
<td data-field="id">0</td>
<td><span class="label">custom styled column 0</span>
</td>
<td data-field="street">another lengthy column 0</td>
</tr>
<tr>
<td data-field="id">1</td>
<td><span class="label">custom styled column 1</span>
</td>
<td data-field="street">another lengthy column 1</td>
</tr>
<tr>
<td data-field="id">2</td>
<td><span class="label">custom styled column 2</span>
</td>
<td data-field="street">another lengthy column 2</td>
</tr>
</tbody>
</table>
CSS
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
*:before,
*:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
html {
font-size: 62.5%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
body {
font-family: "Segoe UI", "Open Sans", Arial, sans-serif;
font-size: 1.4rem;
line-height: 1.42857143;
color: #ffffff;
background-color: #424242;
}
table.table-grid {
width: 100%;
}
table.table-grid th, table.table-grid td {
padding: 4px 5px;
line-height: 20px;
text-align: center;
vertical-align: middle;
border-top: 1px solid #7ea4d3;
white-space: nowrap;
}
table.table-grid th {
font-weight: bold;
}
table.table-grid th.sortable {
cursor: pointer;
position: relative;
padding-right: 30px;
padding-left: 30px;
}
table.table-grid th.sortable::after {
transition: all 750ms cubic-bezier(0.23, 1, 0.32, 1) 800ms;
position: absolute;
right: 10px;
top: 0;
line-height: 2.8rem;
content:"\f0dc";
font-family:"FontAwesome";
font-size: 2rem;
opacity: 0;
transform: scale(0) rotateX(0deg);
}
table.table-grid th.sort-desc::after {
transform: rotateX(0deg);
content:"\f0dd";
opacity: 1;
transition: all 300ms cubic-bezier(0.23, 1, 0.32, 1);
}
table.table-grid th.sort-asc::after {
transform: rotateX(180deg);
content:"\f0dd";
opacity: 1;
transition: all 300ms cubic-bezier(0.23, 1, 0.32, 1);
}
table.table-grid tr:hover th.sortable:not(.sort-asc):not(.sort-desc)::after {
opacity: 0.4;
content:"\f0dc";
transition: all 750ms cubic-bezier(0.23, 1, 0.32, 1);
transform: scale(1) rotateX(0deg);
}
td::before {
content: "before";
}
td::after {
content: "after";
}
JavaScript
var sortAsc = document.getElementsByClassName('sort-asc');
var sortDesc = document.getElementsByClassName('sort-desc');
[].forEach.call(document.querySelectorAll('th.sortable'), function(el){
el.addEventListener('click', function(e){
var cl = e.target.classList, newSortDirection;
if(!cl.contains('sort-asc') && !cl.contains('sort-desc')) {
cleanClassNames();
cl.add('sort-asc');
} else {
if(cl.contains('sort-desc')) newSortDirection = 'sort-asc';
if(cl.contains('sort-asc')) newSortDirection = 'sort-desc';
cleanClassNames();
cl.add(newSortDirection);
}
});
});
function cleanClassNames(){
[].forEach.call([].concat.call([].slice.call(sortAsc), [].slice.call(sortDesc)), function(el){
el.classList.remove('sort-desc');
el.classList.remove('sort-asc');
});
}