The trick with CSS in TiddlyWiki?

[data-tiddler-title=my-tiddler] table, 
[data-tiddler-title=my-tiddler] th, 
[data-tiddler-title=my-tiddler] td {
  property:property-value;
}

[data-tiddler-title^=prefix] div { ... } /* ^= starts-with */
[data-tiddler-title$=suffix] div { ... } /* $= ends-with */
[data-tiddler-title*=elloThe] div { ... } /* *= contains */
 

Thanks it looks like getting close.

So If I understand this just proceed the selector in the css with [data...] to target only the tiddlers meeting the condition?

Could the above be placed inside a style tag and then transcluded in the target tiddler, or directly in the target tiddler? ie no $:/tags/Stylesheet

Could we have data-tiddler-title=my-tiddler be data-tiddler-title=<<currentTiddler>> so as not to have to repeat entry?

Or should I use a tag or fieldname to have the styles able to apply to more than one tiddler (at a time) even if I start with one only?

1 Like

If you, on tiddlywiki.com, search for style you will see the tiddlers titled “Custom styles …” - you’ll see that you can style based on tags, title or class.

This technique is just a way to specify what to target and works because the rendered html code has these as attributes in the div by default, like so:

<div data-tiddler-title="HelloThere" data-tags="TableOfContents" ... >

I use this heavily and I believe we have @pmario to thank for its implementation.

BTW, recently there was an analogous addition to target tag pills with data-tag-title, i.e to style all, say, foo tag pills.

So, again, this is just a way to target something for css. You still need to put it in a stylesheet or in a styleblock… but there is a discrepancy that I just posted an issue about. I do typically get things to work after a while.

You can for example do the following:

tags: $:/tags/Stylesheet
type: (default - i.e not text/css)
text:
<$list filter='[[Hey there]]'>
[data-tiddler-title='{{!!title}}'] { border: 10px solid blue; }
</$list>
1 Like

Thanks all for the feedback.

@twMat so I could do this;

tags: $:/tags/Stylesheet
type: (default - i.e not text/css)
text:
<$list filter='[all[current]has[fieldname]]'>
[data-tiddler-title='{{!!title}}'] { border: 10px solid blue; }
</$list>

I am currently looking using three tiddlers to define a form for tiddlers than have a particular field value;

The Body template will not use the default but a tiddler of this basic structure.

A Layout tiddler, for the “myform”
$:/PSaT/forms/myform/layout

\import  $:/PSaT/forms/myform/macros
{{$:/PSaT/forms/myform/styles}}

then a set of html divs, spans section etc... containing as the content the various macros and with named classes (defined in the stylesheet.

As a result I have extended my use of styles to a set of named classes, so only these will have the styles applied. Also the macros used there in are not global but imported when needed.

so a tiddler with the conditions will transclude the the correct layout tiddler

Yes, that sounds doable. So to target things within the filtered tiddlers, you just “add” the targeting as usual in css e.g

[data-tiddler-title='{{!!title}}'] .tc-tiddler-body { border: 10px solid blue; }

1 Like

Here’s a neat css trick to shorten all of these css rules : using the :is selector :slight_smile:

[data-tiddler-title="{{!!title}}"] :is(table, th, td) {
  property:property-value;
}

:is([data-tiddler-title^=prefix],[data-tiddler-title$=suffix],[data-tiddler-title*=elloThe] 
) div{ 
... 
}
2 Likes

WHAT!!!? That was completely new to me and will be very useful! And accepted by basically all browsers. I thought such things were only possible in SASS and similar.


@TW_Tones - this issue discussion also has some good to know stuff. (Thank you Saq!)

2 Likes

Thanks @telumire.

Also, :not(), :where() and (soon) Cascade Layers (more here).

1 Like

I didnt knew about the layer at-rule, thanks ! Another CSS feature that I’m eager about is the CSS Container Queries, looks very promising

:is(), and :where() are almost identical except for the fact :is() raises specificity while :where() lowers it.

:not() is the inverse of :is().

Something else on the horizon is :has()

div:has(img) { ... }

Select (target) all divs that have img descendants.

1 Like

@layer the treatise: A Complete Guide to CSS Cascade Layers | CSS-Tricks - CSS-Tricks (@telumire)

2 Likes

CSS @scope rule allows CSS rules to be scoped to part of the document, here, in a tiddler body.

<parent-element>
  <style>
    @scope {
      .button {}
      .a {}
    }
  </style>
</parent-element>

It already works in Chrome and Safari:

https://caniuse.com/css-cascade-scope

Sadly, not Firefox. They are so slow! Plan is at the end of 2025:

https://connect.mozilla.org/t5/ideas/implement-css-scope-rule/idi-p/42479

Keep in mind there are a lot of methods already in TiddlyWiki to effectivly scope CSS to a tiddler, this includes the class field and CSS Data options.

They require prefix with a long class or data selector. @scope is like scss, can nest so they can be short.

@TW_Tones Do you know if style tag still take effect when tiddler is closed? Will it add to global stylesheet or just take effect when it shows?

NOT exactly correct. It will depend on the SPECIFICITY OF THE RULES.

The more targeted you want the CSS the more specific the rules need be.

It is easy to TARGET one Tiddler.

Several methods. Easiest one-off is rule > applied only-if.

@TW_Tones are you using those rules only once? https://youtu.be/gbbcei_CMok?feature=shared

Isn’t ONLY ONCEISM central to the SPECIAL HEFT of TW?
Meaning: Rules as needed. Broken as needed.

Easy-peasy.

TW re-renders. Unless a style sheet is designated persistent then, no.

The easiest way to limit a SS to be specific to one Tiddler is to use an overall ID or Class specific to it.

Or, maybe, use the TW field for that: class field.

1 Like

Yes, CSS defined within a tiddler using <style> html tags only opperate when that tiddler is rendered (in view mode) although it could be transcluded elsewhere as long as its rendered it works.

  • I suggest only using this when experimenting or designing CSS
  • There may be some fun tricks so once something opens it alters the look of the wiki but it can be hard to locate where it is comming from if you forget.

Of course, there is so many things that can go into a style tag or CSS definition but this specificity is all driven by that CSS.

  • If you are not using specificity it will be global.

We could document ways for adding specificity to the contents of the style tags to make it easier for people with less skills to be specific to the current tiddler, but I suggest this may not be very helpful because the styles only apply when the tiddler is open anyway.

  • Using the stylesheets and and other ways of using CSS is recomended.
  • Using the Class field on a tiddler is a good way to apply CSS to one or more specific tiddlers.
    • once you choose the class name to be used in the class field on tiddlers your CSS needs to keep refering to that class name to ensure specificity. I wonder if there is an easier way than I know to indicate a block of CSS only applies when a specific class is in use, or every items needs to name the class?

I am not sure here, but what I do know is CSS is all about cascading, and as you know tiddlywiki is also good at its own cascades, so you can cascade your CSS Cascades.

  • I think a lot of people with CSS skills forget tiddlywiki can alter how they cascade see the order of stylesheets
  • I think a lot of people with little CSS skills dont know how to leverage CSS Cascades.
  • There is also a difference between learning and experimenting and the best way to build robust solutions. Almost every case is different when we ask where is out CSS to be applied?

You can avoid having to repeat the .className part of the selector by using this syntax:

.className {
   & someselector { someattributes }
   & someselector { someattributes }
   etc.
}

This is equivalent to:

.className someselector { someattributes }
.className someselector { someattributes }
etc.

and can save a lot of typing, especially when there are lots of CSS rules that are using the same .className for specificity.

-e

5 Likes