Javascript sucks.
Example Sortable Table
What’s going on here?
More Examples
In an effort to eschew Javascript as much as possible but still have sortable tables, it requires a bit of CSS styling to get it to work. In addition there are some limitations. Using this as a starting guide, I adapted it to create these type of labels and stylings dynamically using Liquid.
Example Sortable Table
“Conditions for CSS Variables”2016-10-2110368Controlling the Specificity2016-12-212431Counters and Stones2018-01-044463Flexible Overflow2017-11-286585Keyboard-Only Focus2017-06-274597Label-to-Input States2017-05-312829
Limitations:
Sort Only One Table at a Time: Clicking sort on one table causes the other to revert back to the original order.
Can’t Sort Strings: There could be some hack using Liquid to get all the strings and sort them somehow, but it’s too complicated for now.
Can’t Sort Scientific Notation: Sorting scientific notation floating point numbers does not work. CSS does not interpret the scientific notation floats as numbers.
Styling looks Crummy: At the moment, styling the columns to fit the content better is an issue. At the moment, I’m styling them as 1fr that is 1 fractional unit.
Confuses screen readers: Sorting does not modify the DOM, so it can confuse screen readers as the DOM order is not the displayed order.
What’s going on here?
Data is loaded from a .yaml file and the subsequent data is used to populate <style> tags and fill out the html table. Here’s what the data looks like:
Yaml Data
headers:
name:
name: Name
sortable: False
type: string
text_align: left
published:
name: Published
sortable: True
type: date
text_align: center
views:
name: Views
sortable: True
type: value
text_align: right
rows:
– name: <a href=”/”>”Conditions for CSS Variables”</a>
published: 2016-10-21
views: 10368
– name: <a href=”https://kizu.ru/en/fun/controlling-the-specificity/”>Controlling the Specificity</a>
published: 2016-12-21
views: 2431
– name: <a href=”https://kizu.ru/en/blog/counters-and-stones/”>Counters and Stones</a>
published: 2018-01-04
views: 4463
– name: <a href=”https://kizu.ru/en/blog/flexible-overflow/”>Flexible Overflow</a>
published: 2017-11-28
views: 6585
– name: <a href=”https://kizu.ru/en/blog/keyboard-only-focus/”>Keyboard-Only Focus</a>
published: 2017-06-27
views: 4597
– name: <a href=”https://kizu.ru/en/blog/label-to-input/”>Label-to-Input States</a>
published: 2017-05-31
views: 2829
Jekyll Include file using Liquid Templating
Inside a page, the data is then fed to a Jekyll include. This file uses Liquid templating quite extensively. The include creates the CSS styling tags specific to this table, making sure that they don’t conflict with other tables on the same page with similar names or headers. Then the table is created and each row has the appropriate inline styling to tell CSS how to sort the table.
<style> generated specifically for the table
{%-capture table_name-%}{%-if include.id -%}id_{{include.id|handleize}}–{%-endif-%}table_{{table_data.name|handleize}}{%-endcapture-%}
#sort-ascending-{{table_name}}:checked + .table .table-orderer[for=sort-ascending-{{table_name}}],
#sort-ascending-{{table_name}}:not(:checked) + .table .table-orderer[for=sort-descending-{{table_name}}] {
display: none !important;
}
{%for header_kv in table_data.headers %}
{%-assign header = header_kv[1]-%}
{%-capture name-%}{{table_name}}-header_{{header_kv[0]|handleize}}{%-endcapture-%}
{%-if header.hidden-%}{%-continue-%}{%-endif-%}
.table-col-{{name}} {
text-align:{%-if header.text_align and header.text_align!=empty-%}{{header.text_align}}{%-else-%}inherit{%-endif-%};
}
{%-unless header.sortable-%}{%-continue-%}{%-endunless-%}
#sort-by-{{name}}:checked ~ .table > .table-body > .table-row {
–order: var(–order-by-{{name}})
}
#sort-by-{{name}}:checked ~ .table .table-sorter[for=sort-by-{{name}}] ~ .table-orderer {
display: inline;
}
{%endfor%}
#sort-ascending-{{table_name}}:checked + .table {
–sort-order: 1;
}
HTML div generated for the table
{%-for header_kv in table_data.headers -%}
{%-assign header = header_kv[1]-%}
{%-if header.hidden-%}{%-continue-%}{%-endif-%}
{%-unless header.sortable-%}{%-continue-%}{%-endunless-%}
{%-capture name-%}{{table_name}}-header_{{header_kv[0]|handleize}}{%-endcapture-%}
<input type=“radio” name=“sort” id=“sort-by-{{name}}” checked=“checked” />
{%-endfor-%}
<input type=“radio” name=“sort-order” id=“sort-descending-{{table_name}}” checked=“checked” />
<input type=“radio” name=“sort-order” id=“sort-ascending-{{table_name}}” />
<table class=“table”>
<thead class=“table-head”>
<tr class=“table-row” style=“text-align: center;”>
{%-for header_kv in table_data.headers -%}
{%-assign header = header_kv[1]-%}
{%-if header.hidden-%}{%-continue-%}{%-endif-%}
{%-capture name-%}{{table_name}}-header_{{header_kv[0]|handleize}}{%-endcapture-%}
<th class=“table-cell” style=“text-align: center;”>
<label class=“table-sorter” for=“sort-by-{{name}}”>
{{header.name}}
</label>
<label class=“table-orderer” for=“sort-ascending-{{table_name}}”>
↓
</label>
<label class=“table-orderer” for=“sort-descending-{{table_name}}”>
↑
</label>
</th>
{%-endfor-%}
</tr>
</thead>
<tbody class=“table-body”>
{%-for row in table_data.rows-%}
{%-capture row_style-%}
{%-for item_kv in row-%}
{%-assign item_name = item_kv[0]-%}
{%-assign header = table_data.headers[item_name]-%}
{%-if header.hidden-%}{%-continue-%}{%-endif-%}
{%-unless header.sortable-%}{%-continue-%}{%-endunless-%}
{%-capture order_by -%}
{% case header.type %}
{% when ‘value’ %}
{{item_kv[1]}}
{% when ‘date’ %}
{{item_kv[1] | date: “%s” }}
{% else %}
0
{% endcase %}
{%-endcapture-%}
{%-capture name-%}{{table_name}}-header_{{item_name|handleize}}{%-endcapture-%}
–order-by-{{name}}: {{order_by}};
{%-endfor-%}
{%-endcapture-%}
<tr class=“table-row” style=“{{row_style}}”>
{%-for item_kv in row-%}
{%-assign header_key = item_kv[0]-%}
{%-assign header = table_data.headers[header_key]-%}
{%-if header.hidden-%}{%-continue-%}{%-endif-%}
{%-capture name-%}{{table_name}}-header_{{header_key|handleize}}{%-endcapture-%}
<td class=“table-cell table-col-{{name}}”>{{item_kv[1]}}</td>
{%-endfor-%}
</tr>
{%-endfor-%}
</tbody>
</table>
</div>
More Examples
Example Table Duplicates
This table is here to show that the same table doesn’t confuse the CSS sorting of the other table. However sorting one table does remove focus from the other table column header. This could probably be fixed using some CSS magic, however CSS is not my strong suit.
“Conditions for CSS Variables”2016-10-2110368Controlling the Specificity2016-12-212431Counters and Stones2018-01-044463Flexible Overflow2017-11-286585Keyboard-Only Focus2017-06-274597Label-to-Input States2017-05-312829
Duplicate Table
“Conditions for CSS Variables”2016-10-2110368Controlling the Specificity2016-12-212431Counters and Stones2018-01-044463Flexible Overflow2017-11-286585Keyboard-Only Focus2017-06-274597Label-to-Input States2017-05-312829
Table of Chemical Elements
This is more of a stress test for the table sorting using CSS. Note that unfortunately, the CSS does not sort the scientific notation values properly (see Abundance column).
1HHydrogen8.988e-0514.0114.30414002HeHelium0.0001785—5.1930.0083LiLithium0.534453.693.582204BeBeryllium1.8515601.8252.85BBoron2.3423491.026106CCarbon2.267>4000 (pressure dependent)0.7092007NNitrogen0.001250663.151.04198OOxygen0.00142954.360.9184610009FFluorine0.00169653.530.82458510NeNeon0.000899924.561.030.00511NaSodium0.971370.871.2282360012MgMagnesium1.7389231.0232330013AlAluminium2.698933.470.8978230014SiSilicon2.329616870.70528200015PPhosphorus1.82317.30.769105016SSulfur2.067388.360.7135017ClChlorine0.003214171.60.47914518ArArgon0.001783783.80.523.519KPotassium0.862336.530.7572090020CaCalcium1.5411150.6474150021ScScandium2.98918140.5682222TiTitanium4.5419410.523565023VVanadium6.1121830.48912024CrChromium7.1521800.44910225MnManganese7.4415190.47995026FeIron7.87418110.4495630027CoCobalt8.8617680.4212528NiNickel8.91217280.4448429CuCopper8.961357.770.3856030ZnZinc7.134692.880.3887031GaGallium5.907302.91460.3711932GeGermanium5.3231211.40.321.533AsArsenic5.77610900.3291.834SeSelenium4.8094530.3210.0535BrBromine3.122265.80.4742.436KrKrypton0.003733115.790.2481e−437RbRubidium1.532312.460.3639038SrStrontium2.6410500.30137039YYttrium4.46917990.2983340ZrZirconium6.50621280.27816541NbNiobium8.5727500.2652042MoMolybdenum10.2228960.2511.243TcTechnetium11.52430–3e−944RuRuthenium12.3726070.2380.00145RhRhodium12.4122370.2430.00146PdPalladium12.021828.050.2440.01547AgSilver10.5011234.930.2350.07548CdCadmium8.69594.220.2320.15949InIndium7.31429.750.2330.2550SnTin7.287505.080.2282.351SbAntimony6.685903.780.2070.252TeTellurium6.232722.660.2020.00153IIodine4.93386.850.2140.4554XeXenon0.005887161.40.1583e−555CsCaesium1.873301.590.242356BaBarium3.59410000.20442557LaLanthanum6.14511930.1953958CeCerium6.7710680.19266.559PrPraseodymium6.77312080.1939.260NdNeodymium7.00712970.1941.561PmPromethium7.261315–2e−1962SmSamarium7.5213450.1977.0563EuEuropium5.24310990.182264GdGadolinium7.89515850.2366.265TbTerbium8.22916290.1821.266DyDysprosium8.5516800.175.267HoHolmium8.79517340.1651.368ErErbium9.06618020.1683.569TmThulium9.32118180.160.5270YbYtterbium6.96510970.1553.271LuLutetium9.8419250.1540.872HfHafnium13.3125060.144373TaTantalum16.65432900.14274WTungsten19.2536950.1321.375ReRhenium21.0234590.1377e−476OsOsmium22.5933060.130.00277IrIridium22.5627190.1310.00178PtPlatinum21.462041.40.1330.00579AuGold19.2821337.330.1290.00480HgMercury13.5336234.430.140.08581TlThallium11.855770.1290.8582PbLead11.342600.610.1291483BiBismuth9.807544.70.1220.00984PoPolonium9.32527–2e−1085AtAstatine7575–3e−2086RnRadon0.009732020.0944e−1387FrFrancium1.87281–1e−1888RaRadium5.59730.0949e−789AcActinium10.0713230.125.5e−1090ThThorium11.7221150.1139.691PaProtactinium15.371841–1.4e−692UUranium18.951405.30.1162.793NpNeptunium20.45917–3e−1294PuPlutonium19.85912.5–3e−1195AmAmericium13.691449–096CmCurium13.511613–097BkBerkelium14.791259–098CfCalifornium15.11173–099EsEinsteinium8.841133–0100FmFermium9.71125–0101MdMendelevium10.31100–0102falseNobelium9.91100–0103LrLawrencium15.61900–0104RfRutherfordium23.22400–0105DbDubnium29.3––0106SgSeaborgium35.0––0107BhBohrium37.1––0108HsHassium40.7––0109MtMeitnerium37.4––0110DsDarmstadtium34.8––0111RgRoentgenium28.7––0112CnCopernicium14.0283–0113NhNihonium16700–0114FlFlerovium9.928200–0115McMoscovium13.5700–0116LvLivermorium12.9700–0117TsTennessine7.2700–0118OgOganesson7325–0
Interactive, sortable table using only HTML and CSS
css, webdev
Rickifact.com