Skip to content
Build your own tools

← Build guide

Tables and numbers

The tool shows rows of data or does arithmetic the user will quote.

Section 6 Plain text (.md)

Most of these tools are, at heart, a table plus a number. Get both right and the tool is credible.

Markup

<div class="fm-table-scroll">
  <table class="fm-table fm-table--zebra">
    <thead>
      <tr><th>Ansatz</th><th class="fm-table__num">2025</th><th class="fm-table__num">2026</th></tr>
    </thead>
    <tbody id="rows"></tbody>
    <tfoot>
      <tr><th>Summe</th><td class="fm-table__num" id="sum25"></td><td class="fm-table__num" id="sum26"></td></tr>
    </tfoot>
  </table>
</div>

fm-table__num right-aligns and switches on tabular figures so digits line up in columns. fm-table-scroll keeps a wide table scrolling inside itself instead of breaking the page on a phone. fm-table--compact and --dense exist for data-heavy views.

Formatting numbers

Never print a raw float at an Austrian or German audience.

var euro = new Intl.NumberFormat('de-AT', {
  style: 'currency', currency: 'EUR', maximumFractionDigits: 0
});
var num = new Intl.NumberFormat('de-AT');

euro.format(1234567.8);   // "1.234.568 €"
num.format(0.385);        // "0,385"

Reading them back is the mirror problem: "1.234,50" must become 1234.5, not NaN and not 1.234. Strip thousands separators, then swap the decimal comma.

Arithmetic that survives scrutiny

Sorting and filtering

Plain JavaScript. No grid library — for a few thousand rows it is unnecessary weight, and it fights the design system.

rows.sort(function (a, b) { return b.betrag - a.betrag; });

Use localeCompare('de') for text so umlauts sort correctly. Above roughly 5,000 rows, render only what is visible or paginate; below that, just redraw the <tbody>.

Make the active sort and filter visible in the UI. A filtered table that looks like a complete one is how wrong numbers end up in a council meeting.