First link in a Harlowe passage unexpectedly prioritizing global link color

Twine Version: Harlowe 3.3.9

I decided to finally just make a dedicated thread to see if anyone can help me solve this, since I’m planning on doing some visual overhauls/adjustments for my projects.

In the example passage provided, I have coded in nested “click to reveal more text” style links, which are assigned a grayish color in the in-page code. However, the first—and only the first—one of these links on the page ignores the assigned color and instead unexpectedly uses the global link color (a shade of red), before reverting to the assigned color once it is clicked to reveal the next bit of text.

For my projects, I have just accepted the reality that this happens and worked around it, but it would be pretty cool if someone could figure out and then show me how to convince the first link to use the in-page assigned color rather than the global color, so I have more agency to decide what color it is on a page-by-page basis rather than be forced to accept that it will always be whatever I set the global link color as.

The attached file is a pared down example project with a single passage that illustrates the issue.

Thanks!

RI_TestPassage.html.zip (138.8 KB)

2 Likes

You are using the (link-style:) macro to apply styling…

(link: "Click to reveal more text.")
  + (link-style: (text-color: #87656b) + (hover-style: (text-color: #e4092e)))
  + (t8n: "dissolve")[ ...content of revealed areas, that includes "child" links...]

…and as stated in that macro’s documentation…

When attached to a hook, this causes all of the links inside the hook to be styled using the specified changer.

…that macro only effects the links within its associated Hook, and the 1st link isn’t inside that Hook.

The HTML structure of the 1st of your links…

<div class="presentpsg" data-raw="">
	...initial static content...
	<tw-expression type="macro" name="link" return="changer"></tw-expression>
	<tw-expression type="macro" name="link-style"></tw-expression>
	<tw-expression type="macro" name="t8n"></tw-expression>
	<tw-hook>
		<tw-link tabindex="0" data-raw="">Click to reveal more text.</tw-link>
	</tw-hook>
</div>

The above <tw-hook> structure changes to the following after the 1st link is selected…

<tw-hook>
    Now that the first has been clicked, all the future nested links display with the correct grayish color.
    <tw-expression type="macro" name="link" return="changer"></tw-expression>
    <tw-expression type="macro" name="link-style"></tw-expression>
    <tw-expression type="macro" name="t8n"></tw-expression>
    <tw-hook>
        <tw-enchantment hover="false" style="color: rgb(135, 101, 107);">
            <tw-link tabindex="0" data-raw="">Click to reveal more text.</tw-link>
        </tw-enchantment>
    </tw-hook>
</tw-hook>

…and as you can see the <tw-enchantment hover="false" style="color: rgb(135, 101, 107);"> element that is applying the alternative styling only wraps the 2nd (and later links).

note: personally I would use CSS Rules that target the elements generated by the link macros, or Named Hooks wrapping those link macro calls.
ex 1. If I change the Passage content to something like…

<div class="presentpsg">
	...initial static content...
	(link: "Click to reveal more text.")+(t8n: "dissolve")[
		...1st level of revealed content...
		(link: "Click to reveal more text.")+(t8n: "dissolve")[
			...2nd  level of revealed content...
			(link: "Click to reveal more text.")+(t8n: "dissolve")[
				...3rd  level of revealed content...
			]
		]
	]
</div>

…then a CSS Rule like the following in the project’s Story Stylesheet area could be used to style all links found within the presentpsg classed <div>

.presentpsg tw-link {
	color: #87656b;
	
	&:hover {
		color: #e4092e;
	}
}

ex 2. And in situations where styling needs to be applied more selectively, a known Named Hook could be used to mark the content…

|option>[(link: "Link Label")[...content to reveal...]]

…which would generate a HTML structure that includes a <tw-hook> element with that name…

<tw-hook name="option">
	<tw-expression type="macro" name="link" return="changer"></tw-expression>
	<tw-hook>
		<tw-link tabindex="0" data-raw="">Link Label</tw-link>
	</tw-hook>
</tw-hook>

…which could be targeted using a CSS Selector like the following…

tw-hook[name="option"] tw-link {
	color: #87656b;
	
	&:hover {
		color: #e4092e;
	}
}

note: I personally would use Hidden Hooks and (show:) macros to reveal additional content based on the end-user’s interaction with the Passage being visited..

<div class="presentpsg">{
	<p>...initial static content...</p>
	(link: "Click to reveal more text.")[(t8n: "dissolve")(show: ?block1)]
	|block1)[
		<p>...1st block of revealed content...</p>
		(link: "Click to reveal more text.")[(t8n: "dissolve")(show: ?block2)]
	]
	|block2)[
		<p>...2nd block of revealed content...</p>
		(link: "Click to reveal more text.")[(t8n: "dissolve")(show: ?block3)]
	]
	|block3)[
		<p>...3rd block of revealed content...</p>
	]
}</div>

…as it doesn’t result in the same nesting mess of “revealing” links that the technique you’re using can become.

2 Likes

Thank you so much for taking the time to answer my question! This explanation is much more technical than I’m used to (I am not very experienced in anything programming-related, hence doing things like nesting links that I am probably not “supposed” to do), but I will work through the examples you laid out here and see if I can get things working in a way that I understand.

Take care, and thanks again,
DemonApologist

1 Like

It’s less a case of “not supposed to do”, and more a case of “there are different ways to achieve a similar outcome”, which is a common occurrence in the wonderful world of programming… :slight_smile:

2 Likes