Local stylesheet

I have a use case where I provede html example code with somme specific css code which is bounded to each example only.

I can’t use <style> within a tiddler as it is not where it may appear. I dn’t want to use the style attribute because my code rely on css class. So the only way is to write a custom stylesheet in its own tiddler and to tag it accordingly.

But this makes the stylesheet available to every tiddler, which is a recipe for future problems and headache. To mitigate this, I have to complexify the whole things, like putting al my code fragements in a weird-named <div> and prefix all my css rules accordingly (like div#weirdName span.active { stuff... } which is polluting my solutions.

Would it not be fine to have a <$stylesheet> widget instead, to be used like that :slight_smile:

<$stylesheet stylesheet="customStyle42">
(all my nice coding here)
</stylesheet>

where “customStyle42” would be a tiddler off css stylesheet type but NOT tagged as such. It would not apply everywhere but only within <$stylesheet> widget . This is the same idea than the <$include>` widget
for macro defined in tiddler not tagged as macros.

Keep in mind that if you do <style> inside a tiddler it still applies to all other tiddlers while this one tiddler is currently displayed.

I think the only way to satisfy this requirement would be for the <$stylesheet> widget to read the CSS from that stylesheet, dynamically modify it to add a randomly-generated ID to every selector and then wrap the contents in a div containing the same ID. It’s definitely doable and now you are making me want to write a JS widget to do just that :D. If only I had the time, though.

The ability to overcome the complexity of tiddlywiki being a single page wiki whilst treating individual tiddlers with a custom CSS treatment without resorting to specific selectors, is I believe a long standing issue. It is truthfully somewhat “against the grain” of CSS yet it would be wonderful if we could do it.

  • There are ways to do it but the stylesheet or the use of the resulting CSS is no longer “un-adulterated” but perhaps someone with better CSS knowledge can find a way, or at least to minimise it.
  • Perhaps there is a way using the body cascade to only apply the CSS to a specific tiddler? Somehow apply only to the body with a particular field/field value or tag?

This sounds like a job for Custom styles by data-tiddler-title

[data-tiddler-title=“Custom styles by data-tiddler-title”] {
border: 1px solid blue;
}

This could also be a use for the good old style IDs:

#customStyle1 { … }

#customStyle2 { … }

#customStyle3 { … }

1 Like

If you dont need tiddlywiki styling / functionality, you could use an iframe to sandbox your css and html:

<iframe srcdoc="""

<style>
span{
color:red;
}
</style>

<span>red</span>

"""
/>

@telumire Quite a nice trick indeed! It does my current job were my examples are pure html.

But for a more general aim, it is not the solution, as you told.

@Maurycy Yep! I was not thinking about the implication of <style> for the whole wiki!

My own coding so far tag the css tiddlers but I complexify both the css and the html eyample to avoid any bugs:

For the css (in tiddler sample007.css)

div.sample007 span { border: 1px solid red; }

in the html (in tiddler sample007)

<div class="sample007">
<span>this is my real html code here</span>
</div>

This is finally the simplest solution.

It could be used by a future <$stylesheet> widget like this.

First, here is a simple.css stylesheet, NOT tagged.

span { border: 1px solid yellow; }
h2  { color: red; background-color: tan; }

Then a sample tiddler named sample009

<$stylesheet ssrc="simple.css">
This <span>does work</span> OK!
</$stylesheet>

The widget would create a $:/temp/stylesheet/sample.css tiddler tagged as
“$:/tags/Stylesheet” with the following content:

[data-tiddler-title=“sample.009"] span  { border: 1px solid yellow; }
[data-tiddler-title=“sample.009"] h2  { color: red; background-color: tan; }

This would do the trick. The problem would be: when would that temporary tiddler be suppressed? It would be best that it is deleted when sample009 is closed or deleted. If sample 009 is renamed, it would also be mandatory that it be updated.

I’m not sure this can be possible.

I don’t know if I understand your question/example.

But I think the @Brian_Radspinner 's solution is the key.

Also i think you are focusing in widget while we have other awesome tool, the macros. You could have macros to add the styles. Maybe something like:

\define style-1()
[data-tiddler-title="<<currentTiddler>>"] .my-class{
...
}
\end

In a tiddler tagged as macro (or import the macro in your tiddler), then you could use it in other tiddlers.

Here’s another, arguably better, solution :

/* scopped css */

<$text text={{{ 
[{!!css}split[}]!is[blank]]
+[addprefix[ ]addprefix{!!prefix}addsuffix[}]]
+[join[ ]]
}}}/>

This snippet will automatically prefix your css rules (here, in the field “css”) with a prefix (here, in the field “prefix”), allowing to scope your css rules to something specific.

https://demos.tiddlyhost.com/#How%20to%20scope%20CSS

Note that in the future, it will be possible to nest CSS rules, allowing to easily scope css rules: CSS Nesting Module

1 Like

I think the iframe approach has great possibilities because we can use a custom body to do this and transclude the custom stylesheet (between the style tags) knowing it will only effect the contents of the iframe, or the current tiddler.

  • I will test ASAP

I already have a “local view template” solution (in another field of the tiddler) that only applies to the current tiddler, I plan to make a local-stylesheet, and local-macros field as well.

  • All to assist in development or solutions within a single tiddler scope.

[Edited]
I am not sure how to get the text inside the iframe wikified. Will experiment

Having a iddler candidate for special stylesheet named $:/user/database/test/blobs/461/testsol/example with its stylesheet named $:/user/database/test/blobs/461/testsol/example.css, I have something like that in that css tiddler, typed as ‘‘tw5’’ instead of text/css but of course tagged as $:/tags/Stylesheet

<$let here = {{{ [<currentTiddler>dump[current]removesuffix[.css]dump[here]] }}}>
[data-tiddler-title="<<here>>"] span.active > span {
  display: none;
}
[data-tiddler-title="<<here>>"] span.active::before {
  content: "♥";
}
</$let>

which renders as

[data-tiddler-title="$:/user/database/test/blobs/461/testsol/example"] span.active > span {
  display: none;
}
[data-tiddler-title="$:/user/database/test/blobs/461/testsol/example"] span.active::before {
  content: "♥";
}

And I think it’s quite handy and allows for cut and paste for all this kind of special case css tiddlers. That’s what I have finally done so far.

1 Like