Scratch – tables

Continuing my incremental NetNewsWire theme build. Version 5 Scratch – footnotes styled NetNewsWire footnotes. Time for tables! And as a side mission an overflow indicator experiment.

Minimal tables

One size fits all table styling is always going to leave much to be desired. CSS alone provides no way to introspect the text in a cell, so responding to the type of data is not an option. We might otherwise want to alter the alignment or apply a suitable minimum cell width.

It’s on the to-do list, but I’m yet to cater for <caption>. Most tables ought to have one! Perhaps, when I’m feeling it, I’ll build a simple 11ty site to generate RSS feeds for the purpose of testing content including some table variants.

As it stands, my testing is constrained to a few tables in feeds I chanced upon that are sans-caption.

Table styling

The approach I’ve taken is not radically different to the default NetNewsWire theme. Borders are limited to between rows, using consistent text alignment and white space to hold the columns together.

As the values in the first column are often row labels they are aligned right to hug the row they are labelling. If these styles were for my tables, I would make this alignment exclusive to <th> within <tbody>. People seldom go to the trouble of designating their row headers, so I’m going with the flow.

Space units

Horizontal space tends to be constrained in tables, so padding is reserved for between cells to minimise width. For horizontal space I’ve used ch and ex for vertical space. So that the spacing might to respond to the proportions of the assigned typeface.

A more nuanced solution, for vertical space in particular, could involve a calc incorporating cap and perhaps lh to take into account the variety of white space different typefaces incorporate in their metrics.

For now I’m still looking at Times and perfection can wait.

table {
	border-collapse: collapse;
	font-size: inherit;
}

th,td {
	overflow-wrap: normal;
	border-style: none;
	border-block-end: var(--rule-width) solid var(--rule-color);
	text-align: left;
	
	&:first-child {
		text-align: right;
	}
	
	&:not(:last-child) {
		padding-inline-end: 2ch;
	}
	
	thead & {
		padding-block-end: 1ex;
		vertical-align: bottom;
	}
	
	tfoot &,
	tbody & {
		padding-block: 1ex;
		vertical-align: top;
	}
}

Overflow

Table layouts had a few years (too long) in the sun before mobile phones brought their particularly little screens to the web. There are a few approaches to making tables respond to a narrow viewport and most of them are overcomplicated and often harmful to accessibility. The simplest solution which NetNewsWire adopts remains the best. If a table is too wide, let it scroll horizontally.

NetNewsWire bakes in JavaScript to wrap tables in a div (with a class of nnw-overflow) to facilitate a horizontal scroll.

The cell content will wrap (to a possibly uncomfortable degree) before the table will create a scroll-bar. We could mitigate this by applying a minimum cell width. However, I choose the side of keeping data tables with short text values compact.

It is definitely worth overriding the earlier added overflow-wrap: anywhere;. Applied to squashed tables would cause the words to be smeared across lines.

The default table sizing algorithm assigns more width to columns with more text. In the circumstance where we have no control over the HTML it is best to avoid getting in the way by trying to guess widths.

Take this as your reminder that HTML tables are a poor choice for lots of text.

Reinventing overflow indicators

In addition to being too wide, tables are often too tall. One of the knock on effects of this is the indication that there is horizontal cropping occurring may not be visible until you’ve scrolled far enough to see the scroll-bar at the bottom of the table. Visibly cropped text is a good indicator, but it doesn’t help when the edge of a table column happens to fall aligned with the edge of the viewport.

The most popular, and wonderfully clever, solution to this problem is to apply a shadow to the edge of the overflowing content. With some crafty use of background-image and background-attachment (that I won’t explain here) no JavaScript is required to have the shadow only present when content is hidden.

However, this physical metaphor loses some intuitive immediacy in dark mode. I took this as excuse enough to experiment with an alternative.

Using the same overlapping backgrounds approach, instead of a shadow, I’m rendering an ellipsis like symbol (…) at the top of the overflowing container – above the corner of cropping side.

.nnw-overflow {
	padding-block-start: 0.5em;
	max-width: 100%;
	overflow-x: auto;
	overscroll-behavior-inline: none;
	--dot: radial-gradient(
		circle at center, 
		var(--text-color) 0, 
		var(--text-color) 70%,
		transparent 70%);
	--d-size: .3rem .3rem;
	background-image:
		/* Cover left */
		linear-gradient(
			to right, Canvas 50%, transparent
		),
		/* Cover right */
		linear-gradient(
			to left, Canvas 50%, transparent
		),
		/* Dots */
    	var(--dot),var(--dot),var(--dot),
    	var(--dot),var(--dot),var(--dot);
	background-size: 4rem 100%, 4rem 100%,
		var(--d-size), var(--d-size), var(--d-size),
		var(--d-size), var(--d-size), var(--d-size);
	background-position: left, right,
		top left, top left 0.5rem, top left 1rem,
		top right, top right 0.5rem, top right 1rem;
	background-repeat: no-repeat;
	background-attachment: local, local,
		scroll, scroll, scroll,
		scroll, scroll, scroll;
}

Worth mentioning the use of overscroll-behavior-inline. The over-scrolling bounce effect spoilt the magic somewhat by revealing the dots when scrolling beyond the extent of the content. This property specifically prevents the horizontal scroll bounce while allowing vertical scrolling to function normally.

These dots are not as familiar as a nice shadow. They are visually robust though – working equally well in and light and dark mode.

Whether or not people will intuitively read the dots as a scroll indicator remains to be seen. Keeping the dots tight to the content will hopefully help distinguish them from a menu button. Maybe within the context of a NetNewsWire theme I’ll get away with it. Let me know what you think.

I’m happy enough with the effect to apply it to pre tags too in Scratch.

Install

To enable a quick switch between different versions of this theme I’ve generated a zip of each version – incorporating the version number in the name:

Get the latest version on the Scratch project page.

Next up

I’ve been pondering a somewhat novel idea for handling heading hierarchy I’m keen to try.