Change article header to "position: sticky"

Hi,

As far as I know, right now tt-rss uses a hide/show floating header for article titles while scrolling. This works OK, but just about every time I use my instance I think to myself “Hey, this might be cleaner with sticky positioning, and I might actually know how to do that.” and so now I’m writing this post.

Here’s the current functionality: Imgur: The magic of the Internet

And here is a very rough mock-up of sticky positioning: Imgur: The magic of the Internet

Here’s the CSS compatibility:


Annnnnd. Yup, all the browsers support it.

Benefits to this new idea: A little bit cleaner visually, no more titles that are rendered before or after their respective articles (or maybe that only happens to me?). And the updateFloatingTitle javascript function can either be lightened or removed altogether.

Fox: I’d like to work on this and submit a pull request. Would you be interested in merging it if I do?

I think this is a good idea. I’ve used sticky on a few other sites and it works really well.

(Plus I’ve noticed that TT-RSS can sometimes not handle returning the article heading to “normal” if the article is collapsed (combined display mode, not expanded) and the normal and stuck versions are basically in the same spot.)

this looks very nice, certainly submit a PR.

yes, the fewer JS hacks like this, the better.

e: if we could remove it altogether that would be wonderful.

Sweet!

@fox My gogs account is ctag, I’m ready to make a fork to play with.

sure, you should be able to fork now.

I’m dumber than I look, so this might take a while.

I beat the app’s Dockerfile with a mallet until it started working as a testing environment, and got a mockup of the CSS going. Is there a less Makefile? I saw one in the git history at one point. Or do you run lessc --source-map light.less light.css for each CSS file?

The article content sliding under the header without any sort of dropshadow looks bad and confusing. Unfortunately there doesn’t appear to be a baked-in CSS solution to adjusting an element’s properties after it becomes “stuck” to the window, and a static always-on dropshadow is equally bad. I found some possible solutions:

  1. Add a javascript event observer that adds a shadow when the article begins to scroll. I’d just rather not do this.
  2. Cite some jank CSS magic to make a drop shadow appear on scroll with nested sticky elements. It appears to work, just is gross and I saw some demos that had become broken in newer browsers.
  3. Add a static border to the header. It isn’t a drop shadow, but appears to look OK both before and during scrolling. And it matches the bottom border of the toolbox at the very top. I prefer this one best.

There’s also a hiccup with the header’s background. It’s set to “transparent !important;” I think because the .Selected article div behind it is changed colors on checkbox… Should the .Selected color change be moved to the .header element?

And if you want to help me sleep at night: what does “cdm” in the CSS files stand for?

I’m using phpstorm automatic less builder, vscode also has one. If you want to do it manually then it’s basically what you said.

you could use a mutation observer which would add a class name based on, something, i dunno what exactly. position in the viewport? i would rather not have a static border around all headers.

it’s hard to discuss this without some kind of proof of concept which i could screw around with in dom inspector.

combined display mode. as opposed to three panel mode.

e: there’s also this Intersection Observer API - Web APIs | MDN apparently

https://codepen.io/hey-nick/pen/mLpmMV

e2: maybe this could also be used to clean up headline scroll handler :thinking:

there’s also this: An event for CSS position:sticky - Chrome Developers

Cool, I just found some pure CSS that might work. Should I give that a shot?

Either way I want to fix the background transparency issues first, then we can dial in a dropshadow solution that looks good.

Yeah, it’d be great to be able to share a live example. I’m pants-on-head bad at docker, but I’ll try to get it spun up on another machine that can have a port forwarded to it.

Thank you!

i’m not sure about this CSS thing, it looks like a hack. i think an intersection observer is the way to go here, personally.

I thought the whole point of this was to remove JavaScript? There’s already a working JavaScript setup to make the title heading stay on the page as the article scrolls; there’s little reason to change that if a CSS-only solution isn’t viable.

FWIW, I quickly brought up the inspector and added position:sticky;top:0 to div.header and it more or less worked. There would need to be a background set (it’s transparent right now) and perhaps a bottom border, but otherwise it looked fine and worked. I’m used CDM without expanded articles.

what, header transparency? it’s the

 div.cdm.expanded div.header {
-       background : transparent ! important;
+       background : @default-bg ! important;
 }

this is just for drop shadow, there’s no ugly tracking of offsets to actually show/hide the element and, more importantly, reprogram its contents to point to a relevant article.

take a look at updateFloatingTitle().

btw, headline scroll handler should also benefit from the observer, because currently to figure out what’s above the viewport you need to count headlines from the beginning of the buffer, etc. this seems like a good find, at first glance.

i was bored so here’s a proof of concept

intersection.diff (4.6 KB)

e: sorry for trying to steal your show @ctag :slight_smile:

That diff works well on my end. The javascript turned out a lot cleaner than my kneejerk assumption thought it would.
With articles not auto-expanded in preferences the background is still transparent though.

No worries!

e: wait, I didn’t regenerate some of the css files.

you’re right about .expandable, i always forget it exists.

revised diff intersection.diff (10.1 KB)

there’s a weird non-zero scaling effect, i.e. transparent part above the floating title.

scaling

other than that, it seems to work properly. i’m very glad we could ditch updateFloatingTitle() altogether thanks to @ctag for position : sticky.

e:

now with backdrop blur :slight_smile:

That diff works well for the couple things I could think to try on my end. I dig the blur too.

I’m not seeing the transparent part here in Firefox.
image

Yay!

i think this is some kind of hidpi-scaling-related issue. could be chrome specific, too.

if nothing comes up, i’m gonna commit this to trunk tomorrow. would be nice if others tried this diff too.

thanks for testing!

well, this is in trunk now: https://git.tt-rss.org/fox/tt-rss/commit/7adbc95acc4b2677be3a1d830c69b892f77d2465