Tip: Scoped Styling

The WikiText has a quick way to add styles using the @@ syntax. Though this is nice it does become unwieldy with more complex styles like flex and grid, etc.

Another, syntax is the @@.class syntax but that requires defining your class in a StyleSheet tiddler. And it does get a little persnickety working with block level containers.

And these solutions lack the ability to scope styles to a specific tiddler.

I propose the following which is now wildly available in all modern browsers. Each tiddler is rendered with data-tiddler-title and data-tags attributes which means you can select style rules by these attributes.

<style>
[data-tiddler-title="My Tiddler Title"] {
  .container {
    display: grid;
  }

  img {
    width: 32px;
    height: 32px;
  }
}
</style>

<div class="container">

{{image1}}

{{image2}}

</div>

You can even use [data-tiddler-title="{{!!title}}"]. For tags you can use use the ~= which will find the tag in a list of space separated values: [data-tags~="MyTag"].

Why this helps is that it will scope styles to a specific tiddler or tiddler tagged with. It nests rules allowing for more expressive selections of rules while remaining scoped. The style only applies when the tiddler is visible (rendered) and the rules are removed when the tiddler is removed.

CSS is so cool.

4 Likes

Thank you for your tip!

Yes, I use that on those (fairly rare) occasions where I want specific styling for an individual tiddler. I don’t remember where I first saw it, but it was surely in these forums.

However, I think TW could do better. Imagine having a field, perhaps _local_style, which held this information and rendered an inline stylesheet with its contents, automatically generating the CSS data-tiddler-title wrapper.

Actually, this sounds like it could easily be handled by a ViewTemplate and perhaps a FieldEditor. Maybe when life settles down (not until after November’s election day here in my little town), I will try building this. But feel free to do it yourself. It strikes me as quite useful.

3 Likes

thanks for the tip. to be comprehensive we need to remember also we can create a class field on a tiddler listing one or more class names, to apply to that tiddler.

  • I will add more details here soon about how the classes are applied.

It’s already possible to add a class field to a tiddler, which is added automatically to the tc-tiddler-frame.
So you can activate it using a CSS like this:

.tc-tiddler-frame.asdf {
  outline: 1px solid blue
}

1 Like

Lets us consider what the tc-tiddler-frame relates to, thus it’s real scope. The tc-tiddler-frame is a tiddlywiki Class “tc” along with others set on the div element, for the display of each tiddler in the story.

Using the browser inspect we see tc-tiddler-frame is one of a number of class assignments in a long list of div tags, one for each tiddler in the story. Of note the div is also assigned role="article", which makes the div behave as if it were an <article> tag which is meaningfull to screen readers.

On further investigation we see that the div tag which includes tc-tiddler-frame and [{!!class}] is encoded in $:/core/ui/ViewTemplate.

The class statement on this div tag is extencive and introduces other features;

  • Styling for different kinds of tiddlers eg; exists, missing, shadow, overidden shadow, system
    • I am currently researching how to make use of these known classes to conditionaly display content in a tiddler.
  • The aformentioned class field
  • a class for each tag on the current tiddler (the tag name prefixed with tc-tagged-)
    • These classes are not defined in CSS until you do so, so you can apply a css class directly via a nominated tag.

[Note:] The core also includes classes defined using the tag SystemTag: $:/tags/ClassFilters/TiddlerTemplate

  • This is not overly well documented, no use case detailed and not used on tiddlywiki.com
1 Like

Right, and that’s quite useful. My suggestion (and the thought of doing it in userland would, I now realize, only be initial proof-of-concept) would allow us to apply local styles in an entirely portable manner, without cluttering the text field with a <style> tag.

The current mechanism lets us have single-tiddler portability or uncluttered text fields. My suggestion would allow both. This is not something I find essential, but it would be a nice touch, especially if we could work out a pleasing edit UI for it.

3 Likes

This might also be relevant:

https://caniuse.com/?search=css%20nesting