The site uses cookies that you may not want. Continued use means acceptance. For more information see our privacy policy.

TT-RSS Grid CSS

A DIY style improvement for the feedreader I use.

I’m a big believer in RSS feeds. My vehicle for consuming them is TT-RSS on Debian. And while I liked the UI well enough, on some days I’d see the flood of feed items in the list and found myself tending toward reading aversion, where I didn’t want to look at each item and would mark a lot as seen even though I hadn’t actually paid much attention.

That’s good and bad. If I don’t have the bandwidth for it today, I doubt I’ll find the extra bandwidth to go back through older items tomorrow, so wiping the slate is for the best. On the other hand, over longer terms if I’m not consuming feeds, it’s better to stop receiving them (or filter them more heavily (trim the fat)). That’s a calculus and decision of its own, for another day.

But I also thought the interface might be part of the issue. A big list with each item squished between other items tends to be harder for me to scan for keywords, to pick out the parts I want. So I decided to try the new-fangled grid-related styles to make the interface look a little different, and I could see if it made a difference in my ability to consume my RSS feeds.

As you can see from the comparison image, this does trade off compactness for the layout, but I find it easier to scroll and have less visible at once. It’s probably slightly worse in terms of picking what to read next from starred items, because you can’t see them all at once, but if you’re planning to read them all anyway, perhaps the order isn’t as important.

Because I do all of my modifications in Stylus, it is easy for me to swap between my grid style and my older style. Anyway, here’s the code for the grid part. Note that you may need to change some settings for TT-RSS to use this, particularly the “Group by feed” option. (It may work without it, and certainly a modified version could, but I didn’t test any variety of configurations, only what I use.)

Ahem, the code:

/* The main headline area.*/
#headlines-frame {
    display: grid !important;
    /* Use 5 columns; could be tweaked depending on your screen. */
    grid-template-columns: repeat(5, 1fr) !important;
    grid-auto-rows: min-content !important;
    column-gap: 0px !important;
    align-items: start !important;
    justify-content: space-around !important;
    row-gap: 2rem !important;
    margin-block-start: 1rem !important;
}

/* If you include .feed-title in this selector, it will make the feed group act as a horizontal divider.
    You should also enable it for the next one, which makes sure it doesn't take up too much space. */
/*.feed-title,*/
.whiteBox,
#headlines-spacer {
    grid-column: 1 / -1 !important;
}

/*.feed-title,*/
#headlines-spacer {
    max-height: 2em !important;
}

div.feed-title {
    border-width: 1px 1px 1px 1px !important;
    margin-inline: 1rem !important;
}

/* You'd disable these if you enable .feed-title above. */
.feed-title {
    /* You could span more than one, in which case it will stick out in the grid.
        Disabling the grid-column rule would treat the .feed-title as a .hl (headline),
        placing it in the next available grid slot. */
    grid-column: 1 / span 1 !important;
    padding-inline-end: 1.4rem !important;
    display: grid !important;
    grid-template-columns: 1fr auto !important;
    grid-template-rows: auto 1fr !important;
    height: 100% !important;
}

/* Positions the feed's icon in the center of the grid cell. */
.feed-title div:first-child {
    display: grid !important;
    grid-area: 2 / 1 / -1 / -1 !important;
    align-self: center !important;
    justify-self: center !important;
    justify-content: space-around !important;
    align-content: space-around !important;
    vertical-align: middle !important;
    height: 150px !important;
}

.feed-title .icon {
    vertical-align: middle !important;
}

/* Place the title in the upper-left of the cell. */
.feed-title .title {
    grid-area: 1 / 1 / 1 / 2 !important;
}

/* Place the catchup button in the top-right of the cell. */
.feed-title .catchup {
    grid-area: 1 / 2 / 1 / -1 !important;
}

/* The headlines rule.
    It defines its own grid to position the contents.
    The default (light.css and night.css) themes only give it a bottom border.
*/
div.hl {
    grid-column: auto !important;
    display: grid !important;
    height: 100% !important;
    width: 90% !important;
    grid-template-columns: 1fr 1fr 2rem !important;
    grid-template-rows: 1fr auto !important;
    column-gap: 1em !important;
    place-items: start start !important;
    margin: 0 0.25em !important;
    padding: 0.25em !important;
    border-radius: 6px !important;
    border-width: 1px 1px 1px 1px !important;
}

/* Positioning for the item's headline, author, and tags, which are members of this element. */
div.hl > div.title {
    grid-column: 1 / -2 !important;
    /* Setting the height to 100% helps to maximize the clickable link area of the cell. */
    height: 100% !important;
}

/* The headline buttons are positioned in top-right (like the catchup for the feed title).  */
.hl > .left {
    display: grid !important;
    /* Make it a vertical-axis grid. Perhaps should include auto, in case the number of buttons changes (see .pub-pic below.) */
    grid-template-rows: repeat(2, 1fr);
    height: 4rem !important;
    /* First row, third column. */
    grid-row: 1 / 1 !important;
    grid-column: 3 / -1 !important;
    align-items: stretch !important;
    align-content: space-between !important;
}

/* Remove to show the feed button in grid tiles. I don't currently use it, so I hide it. */
.pub-pic {
    display: none !important;
}

/* I prefer the star to be the top item and the checkbox to be under it. */
.hl > .left > .marked-pic {
    order: -1 !important;
}

/*  */
span.hl-content {
    display: grid !important;
    grid-template-columns: 1fr !important;
    grid-template-rows: 1fr auto !important;
    row-gap: 1em !important;
}

/* Show the title which can be multiline.
    The width bit should be removed for more general use. */
span.hl-content > .title {
    display: inline-block !important;
    word-wrap: normal !important;
    white-space: normal !important;
    width: 10em !important;
    grid-row-start: 1 !important;
    grid-row-end: 1 !important;
}

/* Show the full author which can be multiline.
    This style rule goes a bit further than it should, mixing
    with some of my personal style stuff, so may need to be tweaked
    for more general use. (width, line height, particularly.) */
span.hl-content > span.author {
    display: inline-block !important;
    grid-row-start: 2 !important;
    grid-row-end: 2 !important;
    row-gap: 1em !important;
    width: 14em !important;
    line-height: 1em !important;
    word-wrap: normal !important;
    white-space: normal !important;
}

/* Place the score icon and feed icon in the bottom right. */
.hl > .right {
    grid-column: 3 / -1 !important;
    justify-self: end !important;
}

/* Hide these items if they don't contain anything. They are a content preview and the labels. */
span.preview:empty,
span[class^="HLLCTR-"]:empty {
    display: none !important;
}

It’s worth noting I didn’t spend a ton of time cleaning this up, either when I made it or when I decided to post about it, so it may have some rough edges. It didn’t take very long to go from idea to implementation, perhaps a couple of hours, which is a sign of how much easier and more useful CSS has become with things like the grid here. Now, there are things it’s still hard to do with the grid.

For example, without changes to markup, I couldn’t come up with an easy way to make the .feed-title elements fill the rest of the row when there aren’t enough items to do so. I’m pretty sure that could be done if there were separate divs for each feed’s contents, and perhaps it could be done if the grid had pseudo-classes (e.g., :first-row-member), but otherwise I’m not sure how you could do it. (I don’t know if it would have looked better anyway.)

So far I judge it a worthwhile change, as I have found it easier to scan the feeds even if I don’t see all the items at once. It’s more natural for my eyes to jump from item to item, and each one taking up more space gives the illusion that I’m making more progress by looking over each item.

The Itch for Attention in News Media

Don’t feed the delusional bears.

Take the art for this post. What is the truth? Is it two or three in the afternoon? The left clock says two. The right clock says three. Is it afternoon? Could this picture be from extreme latitudes during summer? Both could be wrong. Timekeeping is arbitrary. There could be a temporal anomaly and both could be right.

We often see media posturing to get things right. To get the correct answer. To ace the test. But the media isn’t graded by actual correctness. It’s graded based on viewer consensus—or really viewer consent. It’s graded by getting eyeballs to look at it. If the eyeballs show up, it’s got it right, hasn’t it?

And it mainly learns how to do that. Is it any wonder that the right-wing media often makes things up? It is less concerned with being the wrong clock in the picture, exactly because it is more comfortable with its true role of being a magnet for eyeballs. It is so unconcerned that parts of it often read and look more like a factitious disorder imposed by media.

What does that mean? You can see Wikipedia: “Factitious disorder imposed on another” for an overview, but basically it means the RWM often invents problems—CRT, Jade Helm, social media censorship—in order to draw attention. It shops some new fake symptoms around, some claim of calamity, some cry of wolf, until it finds another crack in the broader media to draw eyeballs in.

A crudely drawn wolf arm holding up a mirror with a cruder reflection of a wolf in it. Thought bubble reads, "Wolf! I've spied a WOLF!"
The RWM looks in a mirror.

This isn’t something exclusive to the RWM. The Times had a recent story about the Russian Federation engaging in the same kind of stuff via social media in 2017: (Paywall) The New York Times: 18 September 2022: Ellen Barry: “How Russian Trolls Helped Keep the Women’s March Out of Lock Step” (emphasis added):

At desks in bland offices in St. Petersburg, using models derived from advertising and public relations, copywriters were testing out social media messages critical of the Women’s March movement, adopting the personas of fictional Americans.

That part is key. The advertising industry (and factions of media generally) is known to impose on its consumers’ insecurities in order to make a sale. They’ll invent all sorts of problems for you if it means you’ll buy a product. It’s the same for political disinformation, of media meant to fabricate illness in society so that you’ll donate to their cause or you’ll vote for their lackey.

The RWM is locked into this kind of concocted illness drama. Them, with the Repub politicians, are in a kind of activated state of disinformation. Like an abuser, they have learned they are rewarded for disinformation, for faking the illnesses of America and causing a big hubbub.

They create false grievances for the business class to worry over. They basically put up a second clock with the wrong time and then want to fight about which one is right.

In order to combat this abuse, the rest of the media has to both point out the reality, point out the clock that is correct, but also minimize coverage of the argument. Two clocks disagreeing makes a funny picture, but it doesn’t make a useful argument. And once you know a clock is wrong, it doesn’t make sense to keep checking it. It’s wrong. It’s a Joseph McCarthy. It doesn’t serve the public interest to keep pretending it might be right when we know it won’t.

If you are eligible, you should consider visiting Vote.gov to find out about registering to vote.

Doing a Typography, Part II

Why is it so hard to make a curve look natural?!

Having been iterating on this font project awhile, I thought I’d mention some of the things I’ve noticed.

One of the big issues I’ve had on the few times I’ve tried to make typefaces is getting the weight right. I don’t know if there are solid rules, especially when some designs are meant to be thicker or thinner than usual. Given I’m trying to make a font to be used for text, rather than for display, a medium weight is best. But what the hell is that?

Looking at glyphs in FontForge can be deceiving. Your design needs to be thicker than you’d think (at least until your eyes adjust). While designing, you need the shapes to be big, to be able to work on them. You’re seeing them as they would be used for display. Display typefaces can get away with being thinner (or thicker) than text faces, because the eyes don’t have to work as hard to make out their features. But when you go to test or use the design as text, it looks quite different.

It’s still a tricky thing, and individual widths in a font will still require manual testing. I don’t know if there’s a good rule or way to decide on a number. The one I’m making uses roughly a tenth of the height as its standard width. Some of the fonts I’ve looked at seem to vary more than others, and I don’t know if the tenth is a good rule or not (for sans fonts; for serif fonts, there tends to be width variations on different strokes, so there are probably two or three widths that you’d need to balance between each other).

In order to test the weight (and other features) I went with LaTeX, which has a fontsmpl (font sample) package that helped a lot. I can make changes, generate the output font file, and re-render the PDF all with minimal effort (though I could write a shell script to make it even more minimal). That’s the second pain point: testing the font.

The main benefit of using a PDF to test is that I can guarantee the output is the current state of the generated font. Ideally I would do most of my testing in Firefox on the web. I do some of that, using a custom stylesheet I can toggle on and off, but Firefox does not reload the whole font every time it changes on disk. But it does, at some point, reload parts of it. So if you have Firefox open to a page using your font, and you change it, depending on how you change it, it may do some strange things with what it displays after some delay.

Showing improper rendering of a partially-reloaded font in Firefox.
A simple calendar page with the words “Hello world!” selected yet not visible (other than a weird artifact) at the top due to the weird font reload behavior with Firefox. Also, the fours disappeared.

I believe it has to do with Firefox reloading the shape data of glyphs, but not refreshing the glyph tables (or the equivalent for however the font files work internally). So if you add or remove glyphs and regenerate, Firefox will (after some unknown delay) load some of the new data, and how it does that can result in some weird garbled mess, including wrong characters, inverted rendering (where the bowl’s counter (or white-space) is filled), other stuff I forgot or suppressed the memory of.

To counter that, I try only to test out on Firefox once, and if I regenerate I either stop testing with it or reload the browser first. (You could generate the font with another name, and switch which name the browser is using, but I haven’t wanted to do all that.)

Shows the changes in the font between an early version and a recent one.
The third paragraph above, shown twice. On top is an early version, with the bottom showing the improvements made over about a month.

The other risk with testing in the browser is that this here web is full of typos (particularly social media). Errant spaces are the worst. You think you have an overlooked kerning issue, only to find out someone put a space there. You have to be skeptical when testing on social sites like Twitter. It may not be the font, it may well be the tweet. But social media yields solid variety in testing. People put words in all caps, you get good coverage on numbers, symbols.

One of the biggest mistakes I made was trying to do some things too soon. It helped in learning, but it also caused (and continues to cause) a lot of reworking. Leaving kerning tables alone, not trying to make an italic version, small caps, a bold version, and not worrying too much about composite glyphs/accented glyphs would have made the initial font creation a lot less interesting but after going back to fix things a few times, I’m trying not to mess with them until the basic version is more finalized.

Kerning by classes is great, but it takes some trial and error to figure out good classes. Also, Fontforge may overkern certain pairs if you use the automatic kerning. I haven’t disabled it, but that does mean going back and check everything. (In general, FontForge has a lot of things it can do for you semi-automatically, after which you’ll need to double-check and clean up or improve its results. In my experience this is a bit clumsy, yielding a mix of excellent and baffling results.)

One of the things I eventually learned was that it’s much easier to check the box in Glyph info that lets you create overlapped shapes. This lets you focus more on getting individual strokes looking good than trying to figure out how the combination should work. But you have to turn that setting—”Mark for Unlink, Remove Overlap before Generating”—on for each glyph that uses it, plus for any that reference an overlapping glyph. Even then, how they overlap may need tweaking to avoid problems with overlapping hints. (The quickest way to enable the mentioned glyph setting seems to be to use the context menu when it pops up validation errors during font file generation.)

In some cases, like A, you might only have an overlapping bar with an inverted V shape. But for others, like X, it’s easier to build from a pair of slanted lines for the main strokes, than to get their crossing right using a single crossed shape. If you want to change the width or angle of the strokes that you’d write by overlapping, it’s much less trouble if they’re two separate shapes than if they’re part of a more complex single.

And speaking of X, use a lot of guides. One for the x-height (the height of lowercase x; the dotted line on those grade-school handwriting forms), another at what I call the curved x-height (for lowercase letters like a, b, c, etc. that have curved tops, they should be slightly higher than the x-height (known as overshoot)). Another guide for the curved-bottom, and a third for curved-top for capitals. (The top of the normal bounding area is already marked with a built-in guide.) There are probably more I should use, like marking the en-width and em-width off? Shrug.

Wikipedia: “Typeface anatomy” is a good place to learn some of the terms used to describe various parts of glyphs. Hovering over a glyph in FontForge provides some useful information, including the Unicode indexes for related characters (and in the case of composites, the ones that it comprises).

But there’s too much to know and a lot of it is down to taste. My current goal is for it to be good enough to (eventually) use it on this site. (That will probably require subsetting it out in a separate file in order to save size for all the accented characters and so on that would otherwise go unused. We’ll see.)