Should we standardize a pseudo-CSS property for "reverse video"?

There are a few different projects at this point that combine modern CSS with the legacy Z-machine styling system: in particular, I’m thinking of Parchment, Dialog, and a proposed Glk extension.

The Z-machine basically provides four independent style properties, each of which can be on or off: bold, italic, monospace, and reverse-video.[1] The first three of these already have standard CSS names: font-style: italic, font-weight: bold, and font-family: monospace, monospace.[2]

The fourth one, though, hasn’t really been mainstream since the 80s, so I don’t expect it to ever be in proper CSS. At this point it seems like each system has a different way to mark it:

  • Parchment uses reverse: 1
  • Dialog uses text-decoration: reverse
  • Dan Fabulich proposes --glk-reverse: 1

And I think it would be prudent to pick one and only one of these to proceed with. (This just came up in Dialog because of the new Apple II support; the Commodore 64 can’t easily do reverse-video, but on the Apple II it’s basically the only styling it does support, so it needs to be added to the 6502 interpreter.)

For reverse: 1, it’s easy to read and makes it clear exactly what’s going on. Using 1 like this is also clearly not standard CSS, which could be a pro (marking this as an extension) or a con (it clashes with the rest).

For text-decoration: reverse, it uses an existing CSS property with a nonexisting value, which is explicitly not an error in CSS (so browsers won’t care about it), but such a value could possibly be defined in the future (but if it was, I think it would mean exactly what we’re using it to mean!). This means it looks like standard CSS, even though it isn’t.

For --glk-reverse: 1, the two dashes mark it as a custom property according to the spec, so it’s guaranteed to never clash with anything. But this is also not what custom properties are supposed to do—they’re meant to be read with the var() function, renderers aren’t supposed to care about them directly. I also don’t love tying it to Glk explicitly, because Dialog doesn’t know or care about Glk; it just knows CSS and the Z-machine.

What do people think? Any big issues I’m overlooking? Dialog can easily implement any of them; I just want to make sure we settle on something that both @Dannii and I can work with. What Dialog fundamentally needs is a property that can take values meaning “explicitly reversed”, “explicitly not reversed”, and “inherit from parent”.


  1. Plus color and background color which are handled separately. ↩︎

  2. For the third, Dialog actually looks for the name monospace anywhere inside a font-family declaration, so you can use font-family: Cartography Mono, monospace if you want—the intent is that you can compile the same source code for Z-machine or for a more capable backend, which might allow arbitrary fonts. That’s less relevant for Glk. ↩︎

1 Like

A standard way would be very useful I think.

Reverse video is something which fonts themselves could provide, so font-style and font-family are other possibilities.

Out of the three proposed options, my preference is for the Dialog one using text-decoration.

1 Like

So far it’s been no problem for Dialog to do things its own way, but now that there’s talk of formalizing it into Glk and baking it into the 6502 interpreter, it seems like it’s about to become much harder to change. So might as well get this figured out now!

Making it slightly more “official” is a good idea, at least in that it means if more people are thinking about it then we’re less likely to decide on something that’s unimplementable on another platform.

In general I think we shouldn’t use an existing CSS property, so text-decoration is out. Using the official CSS way of doing custom CSS properties --prop makes sense. Even though an implementation will probably need to filter it out before it gets processed by a real CSS engine.

The garglk_set_reversevideo function is not able to negate the reverse mode set with glk_stylehint_set. Though that doesn’t mean that we couldn’t have an explicit-not-reverse option, it’s just not something currently in use.

Just to throw a curveball, would it make more sense to standardise a classname? Because that’s how this ultimately gets implemented: AsyncGlk adds styles for the reverse class, which swap the colours. This allows the interpreter’s default stylesheet to define its own reverse colours (for example dark mode’s reverse is still offwhite text on a dark background, just less dark than usual.) If you define custom colours then it swaps the colours for the reverse class. If you only define one colour then the default colour will also be used (define only a fg, and the default bg will be used as the reverse fg, etc.)

That said, my inclination is to just stick with CSS as the interface, while the classname can be an implementation detail.

This seems best. If it is ever implemented by browsers it will likely mean the same thing.

edit: It also inherits correctly

1 Like

A class name won’t work very well for Dialog, since Dialog’s styling system involves authors writing their own CSS directly. A property would be ideal (which is why it’ll also need “yes”, “no”, and “inherit” values).

How about --text-color: reverse or normal?

1 Like

I also vote against unprefixed text-decoration: reverse. Something should distinguish this as custom, whether it’s a custom property name (--whatever) or a custom value (var(--whatever)).

What if we standardized on CSS variable names? Today, AsyncGlk’s actual implementation of reverse looks like this:

.BufferLine span.reverse {
    background: var(--glkote-buffer-reverse-bg);
    color: var(--glkote-buffer-reverse-fg);
}

.GridWindow span.reverse {
    background: var(--glkote-grid-reverse-bg);
    color: var(--glkote-grid-reverse-fg);
}

If the CSS looked like this:

.BufferLine {
    --current-color: var(--glkote-buffer-fg)
    --current-background-color: var(--glkote-buffer-bg)
}

.GridWindow {
    --current-color: var(--glkote-grid-fg)
    --current-background-color: var(--glkote-grid-bg)  
}

Then, we could eliminate the .reverse class, and write this in inline CSS styles, regardless of whether we’re reversing a buffer or a grid:

background-color: var(--current-color); color: var(--current-background-color);

(Note that you might be tempted to use currentColor for this, but we can’t, partly because there’s no currentBackgroundColor, but also because setting color immediately changes currentColor, so the colors wouldn’t actually swap.)

Ranking options from my most favorite to least favorite:

  1. background-color: var(--current-color); color: var(--current-background-color); (most favorite)
  2. --text-color: reverse | normal | inherit
  3. text-decoration: var(--reverse-video)
  4. text-decoration: reverse (least favorite)

I don’t like this one, because it’s a false affordance on Z-machine (normal CSS variables don’t work there in any other context) and prevents it from being combined with any other values of color and background-color. It’s also a very long magic string for the compiler to be watching for. I imagine the same is true for the Glk extension.

I also don’t like this one, for the same reason. Dialog for Z-machine only supports a subset of CSS; including variables in that subset implies it’s much larger than it really is. I believe the same is true for the Glk extension.

I can live with this one, if it comes down to it, but backend engines like Gargoyle or Dialog aren’t supposed to actually respond to CSS variables—they’re supposed to leave those for users. I’ll need to make sure nothing on the Å-machine uses --text-color as the name of a variable, for example, because it would conflict with this.

I prefer this one, for the reasons I’ve already said. I’m also fine with reverse: reverse or something like that (i.e. not an actual property, but looking like one).

If we want to cleave to the standard, I believe the official way for a particular backend to implement a custom property is with a vendor prefix. Something like reverse is for W3C to specify, --reverse is for end users to specify, but -glk-reverse is for the glk backend to specify. I don’t love tying this property so specifically to Glk, but it causes less problems in my eyes than hijacking CSS variables.

So my preference order would be:

  1. text-decoration: reverse (custom value)
  2. reverse: reverse (custom property)
  3. -glk-reverse: reverse or -x-reverse: reverse (vendor property)
  4. --reverse: reverse (magic variable name)
  5. Anything involving magic variable names in the property value (as opposed to the property name)

I really don’t want to overload text-decoration. It would make detecting and parsing it more complex, and I don’t know what all the browsers would do it a stray reverse made it through to the actual renderer. It really should be a new custom property.

This is more of an implementation detail than I thought people would be interested in standardising. I also wouldn’t want to be too locked into a scheme.

Note that AsyncGlkOte doesn’t just swap the colours, it uses a theme specific reverse colour set. In particular, this means that dark mode doesn’t do use white backgrounds.

I could switch it to a glkote-reverse class or something to reduce the risk of class collisions.

I can agree with -someprefix instead of --someprefix. It seems like we’re all liking reverse | normal | inherit as values.

Possible vendor prefixes:

  • -iftf-
  • -if-
  • -garglk-
  • -glk-
  • -x-

Possible suffixes:

  • text-color
  • reverse
  • reverse-video

I like text-color better than reverse or reverse-video, because -x-reverse: normal sounds like it is reversed, when, in fact, it’s not reversed.

So, how do you like the look of this:

-iftf-text-color: reverse | normal | inherit
1 Like

My only reservation about that is that it’s not necessarily clear how -iftf-text-color differs from color. I would prefer:

-iftf-reverse: reversed | unreversed | inherit

Or:

-iftf-reverse-video: reversed | unreversed | inherit

To be explicit about which one means “everything is normal”.

But that’s a much smaller objection than I had to the ones involving variables. I can work with -iftf-text-color if that’s what we go with.

I think none fits in CSS better than unreversed…?

-iftf-reverse-video: reverse | none | inherit
1 Like

I like that!

I guess for completeness we should also support initial as a value (Dialog has that built in already) but I don’t see that being needed very often.

1 Like

iftf seems a little weird as this doesn’t really have anything to do with an IFTF project. But I’d be happy with

-if-reverse-video: reverse | none | inherit

I meant it as something we worked out on this forum. (And, let’s face it, we’ve all got something to do with IFTF.)

-if- sounds like a conditional if rather than “IF” interactive fiction. If we did -if-, I’d write it as -IF-reverse-video (even though the capitalization is meaningless) just to make it clearer what we meant.

Other prefixes in that vein:

  • -ific-
  • -ifiction- (I think this sounds too much like the iFiction standard)
  • -intfiction-

-intfiction-reverse-video: reverse | none | inherit?

One thing to keep in mind with the text-decoration property is that unknown values on CSS properties are safe, valid, and future proof. It is kind of how CSS was made to be extended. Prefixes are really supposed to be in the domain of browser vendors. It is actually part of the standard to not do that. If we are being hypothetical then there is much more danger of colliding with a future vendor than some of the other choices. The choices with variables of course require well known variables. Variables require default values. What is “reverse” anyway? It is a style.

1 Like

That’s why I went for text-decoration in the first place, so I’m still going to quietly advocate for that option, but I don’t see the prefix as violating the standard either—the Dialog compiler or the Glk library are the ones interpreting the CSS to render it, so any special properties they recognize beyond the W3C specification are vendor-specific, right?

Seems right, and it seems to align with prefixes if it has dialog or glk in it that decorate it. It is just that prefixes are usually in the domain of the vendor. webkit, o (opera), etc. If the concern is about introducing an unknown to a css property, then the same thoughts should be applied to vendor prefixes as well.

OK, I think I’ve got an argument that will settle it in favor of -someprefix-reverse-video.

In the CSS Basic proposal, we’re proposing that text-decoration: underline be supported.

If we support text-decoration: reverse, then we’d have to support text-decoration: underline reverse, which browsers do not support.

<!DOCTYPE html>
<head>
<style>
    body {
        text-decoration: underline reverse;
    }
</style>
</head>
<body>
    hello
</body>

In browsers, the entire text-decoration rule is skipped when an unrecognized term appears, so, in this example, “hello” appears without underline. The use of reverse broke the whole rule.

(It doesn’t matter whether you call it reverse or -intfiction-reverse-video; any unrecognized term skips the whole rule.)

Whereas if we use a custom property, the underlining works as expected in browsers. The unrecognized rule is skipped, but the recognized rule is not skipped.

text-decoration: underline;
-intfiction-reverse-video: reverse;

So, those prefixes:

  • -if- (or -IF-…?)
  • -iftf-
  • -intfiction-
2 Likes