Themed Posts: Theming trail items clashes with new Tumblr A/B test
Platform
MacOS 14.8.1 arm64
Browser
Firefox 145.0.1
Addon version
1.1.4
Details
With the new Tumblr a/b test, hovered trail items can have background-color: var(--content-tint). This overrides, rather than adding to, the background color we set on trail items with the "Theme every reblog trail item individually" option, so trail items go "transparent" when hovered and their text colors can be unreadable.
A hotfix for this would be straight-up disabling that option if the a/b test is detected (not immediately sure of a clean way to do this; the CSS map has 53 entries for the obvious string). If we use color-mix to fix it I am going to advocate that we do not change minimum browser versions and leave the regression on Chrome 109 intentionally.
Edit:
A hotfix for this would be straight-up disabling that option if the a/b test is detected
This has been done in #2026, so the new behavior is that the "Theme every reblog trail item individually" option just does nothing in this case for now.
Well... this is uh... one way to do it.
Background color is themed post coloration; inset box shadow is hover effect:
diff --git a/src/features/themed_posts/index.js b/src/features/themed_posts/index.js
index 7a42fac1..030f2336 100644
--- a/src/features/themed_posts/index.js
+++ b/src/features/themed_posts/index.js
@@ -115,6 +115,16 @@ export const main = async function () {
${postSelector} ${reblogSelector}:not(:last-child) > :last-child {
margin-bottom: 15px;
}
+
+ @media (hover: hover) and (pointer: fine) {
+ [data-xkit-themed]${keyToCss('reblog')}${keyToCss('withTrailItemPermalink')} {
+ transition: box-shadow 0.2s linear;
+ }
+ [data-xkit-themed]${keyToCss('reblog')}${keyToCss('withTrailItemPermalink')}:hover {
+ background-color: var(--content-panel);
+ box-shadow: inset 0 0 0 9999px var(--content-tint);
+ }
+ }
`;
if (missingPostMode === 'palette') {
styleElement.textContent += `
Also works. Background color is themed post coloration; pseudo element is hover effect:
diff --git a/src/features/themed_posts/index.js b/src/features/themed_posts/index.js
index 7a42fac1..d427b027 100644
--- a/src/features/themed_posts/index.js
+++ b/src/features/themed_posts/index.js
@@ -115,6 +115,23 @@ export const main = async function () {
${postSelector} ${reblogSelector}:not(:last-child) > :last-child {
margin-bottom: 15px;
}
+
+ @media (hover: hover) and (pointer: fine) {
+ [data-xkit-themed]${keyToCss('reblog')}${keyToCss('withTrailItemPermalink')}:hover {
+ background-color: var(--content-panel);
+ }
+ [data-xkit-themed]${keyToCss('reblog')}${keyToCss('withTrailItemPermalink')}::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+
+ transition: background-color 0.2s linear;
+ background-color: transparent;
+ }
+ [data-xkit-themed]${keyToCss('reblog')}${keyToCss('withTrailItemPermalink')}:hover::before {
+ background-color: var(--content-tint);
+ }
+ }
`;
if (missingPostMode === 'palette') {
styleElement.textContent += `
I was hoping there would be a way to put an element fully behind the background color, so that we wouldn't have to override the Tumblr-set stuff and this wouldn't have to be conditional, but no dice yet.
Appears to function, but potentially has side effects and edge cases where it wouldn't, so hard pass, but for completeness:
Pseudo element is themed post coloration (order reversed using z-index); background color is hover effect (no modification necessary):
diff --git a/src/features/themed_posts/index.js b/src/features/themed_posts/index.js
index 7a42fac1..55ab2bfb 100644
--- a/src/features/themed_posts/index.js
+++ b/src/features/themed_posts/index.js
@@ -115,6 +115,18 @@ export const main = async function () {
${postSelector} ${reblogSelector}:not(:last-child) > :last-child {
margin-bottom: 15px;
}
+
+ [data-xkit-themed]${keyToCss('reblog')}::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ z-index: -1;
+
+ background-color: var(--content-panel);
+ }
+ ${keyToCss('reblogTrailWrapper')}:has(> [data-xkit-themed]${keyToCss('reblog')}) {
+ isolation: isolate;
+ }
`;
if (missingPostMode === 'palette') {
styleElement.textContent += `
edit: Although this is the only one that's potentially compatible with #2007 without special case logic...
Note: test any implementation of this when hovering over the footer of a reblog with contributed content (post must be clickable, so it cannot be viewed alone) and moving the cursor to the contributed content or vice versa; it will probably be slightly glitchy unless implemented very carefully (ex: don't set data-xkit-themed on trail item if trail item matches parent post if (blogNameTrail[i] === visibleBlog.name) return;)
My final proposal is, as mentioned, the only one so far that still uses background-color as the hover effect and thus would work with #2024 without one feature detecting the other feature and triggering special case logic in some way. Here's a slightly cleaner version.
The risk with creating a stacking context on reblogTrailWrapper is that an element inside the reblog trail that's supposed to float using z-index might not layer correctly. Of course, Tumblr uses react portals for this kind of thing, which avoids this, and we don't currently enable quick reblog/quick tags inside reblog trails... but this might not be the case forever. Now, that's still not certain to be a problem: z-indexes still work in a stacking context, and the #1876 situation only occurs if a floating modal makes it far down enough to be underneath the next post in the timeline, which in this hypothetical it would be doing from inside the reblog trail, which would rely on the quick tags modal being tall and the post footer being short.
Having to even think about this may be sufficient reason to go with one of the other options, but that would mean using background and/or background-color as the themed posts coloration and something else for the hover effect, which in addition to requiring a special case to kill the hover, would mean that #2024 should probably use a high enough specificity for background-color rather than using !important on it.
diff --git a/src/features/themed_posts/index.js b/src/features/themed_posts/index.js
index 7a42fac1..e8bb2c97 100644
--- a/src/features/themed_posts/index.js
+++ b/src/features/themed_posts/index.js
@@ -95,7 +95,9 @@ const processPosts = async function (postElements) {
blogNameTrail.push(visibleBlog?.name);
}
[...postElement.querySelectorAll(reblogSelector)].forEach((reblog, i) => {
- reblog.dataset.xkitThemed = blogNameTrail[i] ?? '';
+ if (blogNameTrail[i] !== visibleBlog.name) {
+ reblog.dataset.xkitThemed = blogNameTrail[i] ?? '';
+ }
});
}
});
@@ -115,6 +117,18 @@ export const main = async function () {
${postSelector} ${reblogSelector}:not(:last-child) > :last-child {
margin-bottom: 15px;
}
+
+ ${postSelector} ${reblogSelector}[data-xkit-themed]::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ z-index: -1;
+
+ background-color: var(--content-panel);
+ }
+ ${postSelector} ${keyToCss('reblogTrailWrapper')}:has(> ${reblogSelector}[data-xkit-themed]) {
+ isolation: isolate;
+ }
`;
if (missingPostMode === 'palette') {
styleElement.textContent += `
Note: one can—kind of—use multiple backgrounds for this, i.e.
whatever:hover {
background: linear-gradient(var(--content-tint), var(--content-tint)), var(--content-panel);
}
or even
whatever:hover {
background: linear-gradient(var(--content-tint), var(--content-tint)), linear-gradient(var(--content-panel), var(--content-panel));
}
But one can't transition between background values, so this is just a strictly worse version of either of the former two options (inset box shadow, pseudo element over the background).