CSS/html coloring issue for choices

Edit: Twine Version 2.7.0
Harlowe.3.3.6 used as default

Inside harlowe: (align:"==>")[<span class="turn">(text-colour:red)[(text-style:"bold","smear")[[[Turn back|the eye]]]]]</span>

CSS Stylesheet Code below:

.turn {
    color: red; /* Set initial color */
    transition: color 0.3s; /* Add a smooth transition effect */
}

/* Apply the color change on hover */
.turn:hover {
    color: red; /* Change to the color you want on hover */
}

This will output the button choice “Turn back” in bold, red color, and with a smear effect. And hovering the text will remain it in red color.
Problem is, when I hover the text, it shows the default blue color instead of red. I already done this on two other button choice before and it worked. Not sure why this one doesn’t…

Hi,
I’m not that familiar with Harlowe, but try removing the (text-colour:red) since you are using css to style the text.

First a little background about the three types of CSS:

  • External - this type is loaded from an external css file, and its structure would look similar to your own CSS examples.
  • Internal - this type is contained within the HTML file, generally within the body of a <style> element. This is the type of CSS that is produced by the Story > Stylesheet area of the Twine 2.x application, and its structure would look exactly the same as your own CSS examples.
  • Inline - this type is assigned directly to the style attribute of the HTML element it will affect. And this is the type of CSS that Harlowe styling related macros produce.

When CSS is being applied to a specific element, by default an inline CSS property assignment will override the same property assignment if done via an external / internal CSS rule.
eg.
If you have an external / internal CSS rule like…

.warn {
    color: red;
}

…and a HTML element like…

<span style="color: green;" class="warn">Some textual content</span>

…then that textual content will be green because the inline color property assignment overrides the external / internal CSS rule color property assignment.

There are a couple of issues with your your existing example:

1: Malformed code.

If you add some indentation / formatting to your example…

(align:"==>")[
	<span class="turn">
		(text-colour: red)[
			(text-style:"bold","smear")[
				[[Turn back|the eye]]
			]
		]
	<!-- missing end span tag -->
]
</span>  <!-- end span tag without start tag  -->

…you will see that the end span tag (</span>) has been placed outside the associated Hook of your (align:"==>") macro call.

2: Inline applied CSS overriding Internal CSS rules.

If you use your web-browser’s Web Developer Tools to inspect the HTML element structure generated by that Passage content (when visited) you will see something like the following…

<tw-expression type="macro" name="align" return="changer"></tw-expression>
<tw-hook style="text-align: right; display: block;">
	<span class="turn" data-raw="">
		<tw-expression type="macro" name="text-colour" return="changer"></tw-expression>
		<tw-hook style="color: rgb(230, 25, 25);">
			<tw-expression type="macro" name="text-style" return="changer"></tw-expression>
			<tw-hook style="font-weight: bold; text-shadow: rgb(230, 25, 25) 0em 0em 0.02em, rgb(230, 25, 25) -0.2em 0em 0.5em, rgb(230, 25, 25) 0.2em 0em 0.5em; color: transparent;">
				<tw-expression type="macro" name="link-goto" return="command">
					<tw-link tabindex="0" data-raw="">Turn back</tw-link>
				</tw-expression>
			</tw-hook>
		</tw-hook>
	</span>
</tw-hook>

…and learn that a color property assignment of color: rgb(230, 25, 25); is being applied inline to the <tw-hook> element that is a direct child of your classed <span> element.

3: The “hover” state of the Markup based link is trumping that of your classed <span> element.

The C in CSS stands for Cascade, and that is the behaviour than allows inline CSS to override external / internal CSS rules. It also allows a more specific CSS selectors like your .turn:hover selector to override your .turn selector when the state of the target element-type is “hover”.

Harlowe has a default “hover” based CSS rule that targets the HTML element structure that is generated by the different “link” types it includes.

4: You don’t need to nest Harlowe’s styling macros if they are being applied to the same content.

Harlowe allows you to combine multiple Changer macros together like so…

(align:"==>") + (text-colour: red) + (hover-style: (text-color: red)) + (text-style: "bold", "smear")[
	[[Turn back|the eye]]
]

…and if you intend to use the same styling on multiple items within the same Passage then you can first assign that Changer combination to a Temporary variable and then apply the variable to the Markup based link (or a Hook)…

(set: _warn to (align:"==>") + (text-colour: red) + (hover-style: (text-color: red)) + (text-style: "bold", "smear"))

_warn[[Turn back|the eye]]

note: You can also assign Changer combinations to Story Variables, so the same styling can be applied to items in multiple Passages. However, if you intend to define such “global” like stylings then using a Internal CSS rule is a better solution because it:

  • reduces the size of progress History, as all Story variables are stored their
  • reduces the size of a Save, because they contain the current state of progress History at the time the save was created.
  • reduces the amount of inline applied CSS, which makes it easier to apply other Internal type rules.
3 Likes

Oh wow thank you very much it works! Now I really grasp a better understanding between Harlowe’s macro and CSS ;o
I didn’t even know Harlowe’s macro has built in (hover-style:(color:#))[] function :sob: