Kill-sticky, a bookmarklet to remove sticky elements and restore scrolling
github.com
github.com
So many sites have a top banner that disappears as you scroll down a page, but as soon as you scroll upwards even a little bit, it pops up again. This is immensely frustrating because I tend to read at the top of a page and scroll down as I'm reading. So if I scroll down slightly too far and then correct myself, the banner will instantly obscure the bit of the text I'm trying to read. It's very satisfying to be able to click on the bookmark and fix the site's crap design!
But often blocking JS means parts of the article don't display or the site breaks in other ways. Washington Post for example only shows blurry placeholder photos with JS off.
The kill-sticky or the element zapper in uBo can sometimes do what blocking JS cannot.
I guess they're useful when the content is of low quality but you're desperate to keep eyes on the name of your site.
I hate them.
About the only thing worse than self-hiding vanity flap is a floating side bar using a slow animation to slide back into your field of view, just terrible.
I have a special section in my uBlock user rules, and it is full of annoyances like this.
Another one is an element with popup on hover, but you can only close it by hover-unhover a popup itself. Fly across such element by accident and enjoy your semi-modal “no idea how to get rid of”-popup without even clicking anywhere.
So many hours spent on nothing when a simple `viewport-offset-{top,…}: 20px` could solve it once and for all. Instead we will support global nonsense described in the article for years, despite it stays nonsense at any angle.
To me, this is better usability. I agree - fixed headers obscure the page and it's bad. But simultaneously, it's nice to be able to access the header and navigation instantly. This seems like a good compromise?
It's fairly obvious which one is actually more important in the majority of cases and it's going to be the actual information you're currently reading through. Obscuring the actual content in any form is a direct reduction to page usability.
Seems like a definite win to me? Maybe your usability desires are different than other users desires? In the case of an autohiding header - it doesn't seem like a big reduction in page visibility?
I straight up permanently remove most sticky headers with Ublock Origin. 90% of the sites I read content on, I didnt get there by internal site navigation, I got there from a kagi search or HN link. The rare exception are documentation sites; I use their internal navigation often. Thankfully, though, very few of these sites use sticky headers. I just quickly scroll to the top or use the pagination buttons at the bottom.
This might be targeting a minority of users - it’s design for power users. I’d expect HN to be supportive of this sort of design.
You'd expect.. But please listen.
Its even worse on the phones where you sometimes get header plus some commercial and maybe a cookie banner, interacting with each other trying to figure out how to close them in order is a puzzle.
There have been maybe 1 or 2 sites out of all that i have visited, that I didn't immediately hate the banner.
To me it become a "site smell". So if I have an option I'll go elsewhere for my needs.
I read from the top of the screen and scroll the page so that I'm always reading at the same position without much vertical eye movement, and occasionally flick back a sentence or two for context, which is why it's annoying for me. For a reader who read down the page and occasionally scrolled it would be much less annoying.
Most implementations do the inverse: you overscroll a little, want to fix it, but the header appears. You want to scroll it away, but it persists for a while, so you lose track of where to start to make the line you needed to the top. Because user humiliation is a MUST for a modern site, I guess.
iOS Safari does it much better than a simple hysteresis for its URL bar, but I’m not sure web has enough event detail to implement its way: pull down does nothing, only “kick” down shows the bar.
Why is scrolling tied to changing the visible state of an interface element anyway? Scrolling down to hide and up to reveal /makes no sense/ to anyone other than the guy who wrote it (read: you).
Interface elements that pop in and out are /bad/, especially for people who aren't completely familiar with computers. Elements that change, especially ones that do so seemingly at random, are very disruptive, distracting, and hard to grasp.
An interface that is easy to understand and use has as few changing interface elements as possible, the more static the interface the better.
To me, the idea itself is not that bad and there are some usability gains to be had, but the implementations are just horrible, lazy, and user hostile.
The only thing that auto-hiding header does is cover up something I was trying to see.
Browser extensions are still notoriously difficult to get on mobile for some reason (even on Android, which is open source-ish). So far the best method I've found for injecting JS into sites on Android is the Bromite [1] browser, a Chromium fork that allows you to install userscripts (which are like "diet" extensions). It also enhances privacy and comes with an adblocker.
Whether all extensions work is a different story but its very neat!
Its available on MacOS and iOS, both supporting extensions.
I was so happy to discover this. Went and tried it on Firefox on iPhone... Nope. Apparently it works on all other browsers on iPhone. Just not Firefox. Sigh. I found that the bug report for doing javascript bookmarks was already filed years ago, and Mozilla just ignores it. Mozilla has a bizarre decision making structure.
1) (default) block all JS completely
2) Block 3rd party js
3) Permit all js (rare)
If the web fails to render in (1) and I do not necessarily need anything on that web I can get elsewhere, I just leave the web. F that web and F that creator. If I have to (webshop etc) I usualy just enable (2) which works most of the time. (3) is basically only for special webs like banking etc which is just PITA to debug as you have to be logging in constantly etc.
Websites today are just full of unnecessary crap and are downright unusable when on slower connection like 3G. Most of the webs now require your browser to download 2M of JS to have "slide out menus" or some other stupid stuff. uBlock is a must, because without that you will run out of data plan almost instantly.
And to make things worse, Chromium-based browsers will make adblocking much harder with Manifest v3. As soon as this happens, I will go to Firefox. And after that probably Links (unironically).
Btw spinning up a docker to shrink 1 JS function to a oneliner is perfectly capturing the essence of what's wrong with web nowdays :-D
I expected many websites would stop working, surprisingly though many sites work times, and i simply: - hit my shortcut to set uBlock Origin to "relax" mode whenever needed - exclude a few CDN's - use a different browser (in private mode) for shopping and such
In Firefox I've assigned it a keyword shortcut, so I can type `ctrl + l` to select the address bar, then `ks` `<enter>` to execute the JS without having to click.
I know I'm in the tiny minority here and firmly in the "yelling at the clouds" territory, but I really wish we could go back to the simpler times of the web being hyperTEXT documents linked together and that's it.
Gemini site and hubs do have a didactic to flavor; not that different from the old web.
Except the old web was yearning for more bell and whistle. Dynamic element. Gemini made anything not text illegal
OTOH, i see why things like adblocking is extension. That makes browser neutral with regard to content, while different plugins can bring different policies.
It's an almost incredible situation. Firefox and Safari have a setting to stop autoplay, but much of the time it doesn't actually work, and Chrome doesn't even seem to have a setting.
It's also amazing how when enough users decide that they hate some obnoxious web site behavior (pop-up windows, autoplaying video, etc.) enough to block it, the web site designer's response isn't "maybe we should be less obnoxious" but "how can we circumvent the user's preferences?"
But it seems it is still just a heuristic that blocks some JS play commands, while allows them in some context.
> I can’t even think of any plain text and
> image websites besides my own.
Ycombinator has a great news aggregation website that is text only. You can find a link to it from the top of this page. *$script,redirect=noop.js,3p
and then allow google.com for google sites such as google.co.uk with: @@||google.*$domain=google.\*
All of this is in my annoyances filter list: https://github.com/aembleton/Arthurs-Annoyances/blob/master/...Bookmarklets like this are helpful (and this is a great successor), but bookmarklets are very difficult to install and use for the average internet user. I could not figure out how to install this on my iPhone without using desktop Safari to sync bookmarks.
Is there any hope of browsers being able to combat popup modals and other sticky gross things in an automated (and on by default) way that doesn't totally break sites that require sticky items for navigation or other, non-hostile features?
Things will steadily devolve for users from that point.
Then we’ll need about ten years for the next generation of hypermedia to surface, which hopefully won’t have Turing-complete scripting on principle. But I’m not sure whether developers are smart enough to avoid repeating the same mistakes again and again…
But I don't think this will be the business model of the Web at large. Server costs would be too high. Webassembly blobs with WebGL gives you the sweet spot by offloading the compute cost to the user while stripping them practically all of their freedoms.
At least when Flash was common, full-Flash sites were not really as common as JS-only SPAs today, and it was easy to just block embedded plugins by default and only enable when necessary for some particular interactive element. In other words, plugins provided a clear separation between the "document browser" and the "very interactive", but with today's "JS everywhere", that distinction is getting more blurred and difficult to tease apart.
https://developer.chrome.com/blog/new-in-chrome-106/#popup-a...
The problem is commercial - companies that make browsers have gone all-in on "growth & engagement" and the "attention economy" and rely on the web being terrible to make their money, either directly (Google, Edge) or indirectly (Mozilla, funded by Google and thus unlikely to bite the hand that feeds).
Browser makers have given up on serving their users because it turns out you make more money by exploiting them.
It's like building a robot to pass the butter.
You could set up some CI to make automatic builds after merging to master, but that still wouldn't solve the problem of contributor wanting to test what he wrote.
I just took a second look at the repo, and realized there's no package.json. Typically, an open-source JavaScript project would have one. It would enumerate the dependencies and how they work together to generate the final output.
As a JavaScript contributor, I expect to be able to type
yarn
yarn run build
into any repo to generate the output (and test any changes I've made).I suspect the interactive web is not the author's primary platform. That's fine - it's his project; he can structure it however he wants. I was just surprised to see an unfamiliar, nontrivial dependency to concatenate a handful of lines into a bookmarklet.
Since you asked "Do you know a better way?" you can port the `npm install` line to a dictionary of dependencies in package.json. You can use wireit in that same file to chain the CLIs together, accomplishing what's currently the ENTRYPOINT line in Dockerfile.
It does the same thing that the current setup does, but it follows the conventions of the ecosystem. This makes it more available to external contributors, because they don't have to learn/install tools like Docker that aren't typically seen in JS.
I’m reality it’s just using node. But removed the requirement to set node up.
Just depends on what you expect your contributors to be more familiar/comfortable/ready for. For most JS projects, package.json is the expected onramp for new contributors. We all have node installed.
Not everyone has NodeJS. And not everyone has Docker, either. You know what we all do have?
A Web browser. The World Wide Wruntime.
You know—it's the thing that you're using to look at the README on GitHub (and this comment, probably), and is the reason that JS and bookmarklets even exist in the first place. It's widely popular exactly for its ability to publish/share content and apps without any onerous install step. (It's pretty nifty. NodeJS programmers should really consider looking into it sometime.)
Build.app.htm. Double click and then drag and drop the project source tree onto the browser tab. Done.
If you happen to already have all this trash installed in your user space and you like typing several commands instead of 1 command (make): great, just run it without Docker, nobody forces you to install it. What's even the problem…
If it were my project I'd just be assuming contributors had internet access and advising in the readme to "search for a good 'bookmarklet generator', paste in your code, then test it". I'd then test their tested bookmarklet code before accepting any PRs. Thus reducing the repo to two files and 1% of current complexity, most of that being in the readme itself.
I definitely don't think I'd start with a build system for a bookmarketlet.
I use Docker for everything locally. As a Python dev tired of fighting with different versions, virtual environments, wheel-issues etc...
> This makes it more available to external contributors, because they don't have to learn/install tools like Docker that aren't typically seen in JS.
I feel it's a bigger burden on me having to install whatever tools a random project expects. I vastly prefer a Dockerfile that just works, without me having to spend hours matching their setup, and also has the benefit that it doesn't pollute my system with lots of stuff.
If only there were some sort of ubiquitous platform—a World Wide one, even—that we could reliably depend on to fetch remote resources and that was especially suited for executing JS. It would need to run the code in a sandbox of, course, to ensure that it's acting in the interests of the user—a sort of "user agent"—and not just executing arbitrary code with full rwx privileges in the interests of the script author.
Maybe in a more perfect world...
Previously: <https://news.ycombinator.com/item?id=24495646>
I’m curious because I’d love to visit sites like these too. Meanwhile most social media, blogs, news sites and probably most HN submissions too have some.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ta...
I've had a "replace sticky with relative" filter in my MITM proxy since the day that CSS misfeature showed up in browsers.
The German Zugabeverordnung law was very strict against any "free" commercial offer tied to the obscuring of linked purchases. But instead of being extended to embrace the creation of sponsored funnels providing free entertainment websites, as is probably now long forgotten but fallacious doctrine, the internet instead made "free", "free".
https://marketinglaw.osborneclarke.com/marketing-techniques/...
https://competition-attorneys.de/lawyer/zugabeverordnung-ger...
The law was scrapped in 2004, unlikely [ed] not [/ed] coincidentally with establishing peak web commercial libertarian lobbying, the more political and in earnest post dotbomb.
That's position:fixed or perhaps position:absolute, not position:sticky. And honestly, the former two are far less annoying to experience because they're there from the beginning, while the latter trick you into thinking they can be scrolled out of sight, but don't.
https://github.com/szhu/pagefreeze
It does the same thing, and in addition also prevents any async JS from running. It also can be easily toggled per-site; just click the extension icon! Unfortunately I didn't have time to put a GIF in the README. OP did a better job of explaining what their project does!
Would love feedback on it + hope it helps someone as well!
The worst is when you use the top edge of the screen to read, but the site has a navbar that only shows up when you scroll up. So if you scroll slowly upwards, the navbar creeps slowly downwards, and keeps hiding the text you're trying to read. Thankfully such design choices seem to be getting rarer.
Do sticky headers measurably increase conversion rates, or is it a fad? If there's data to support why people keep making this decision, I guess I could be persuaded to feel that it's not a case of "Everyone likes to do it their way, and you like your way."
Does the bookmarklet get executed for the current open tab?
edit - just looked up the DF post I found out about it from, and it’s been 5.something years
[0] https://daringfireball.net/linked/2017/06/27/mcdiarmid-stick...
example.com###annoying-header:style(position: unset !important)
example.com##.restrictive-box:style(overflow: unset !important)Sunscreen?
Bookmarklets are underutilized.
They can even be utilized to automate simple tasks that I used to use INSERT MACRO PROGRAM NAME to do.
The downside is lack of mobile availability.
Cool story huh? Anyway, that never went anywhere, but I'd donate to an open source project if a better programmer than me wanted to take on this noble struggle.
it does put a little overlay telling you how many elements it adjusted, but you can remove that with a couple modified lines in the source.
With this, you can 'un-sticky' the element instead of removing it.
Here's the URL-encoded bookmarklet code with the above change:
javascript:(function()%7Bdocument.querySelectorAll('body%20*').forEach(function(node)%20%7Bif%20(%5B'fixed'%2C%20'sticky'%5D.includes(getComputedStyle(node).position))%20%20%7Bnode.style%5B'position'%5D%20%3D%20'static'%3B%7D%7D)%3Bdocument.querySelectorAll('html%20*').forEach(function(node)%20%7Bvar%20s%20%3D%20getComputedStyle(node)%3Bif%20('hidden'%20%3D%3D%3D%20s%5B'overflow'%5D)%20%7B%20node.style%5B'overflow'%5D%20%3D%20'visible'%3B%20%7Dif%20('hidden'%20%3D%3D%3D%20s%5B'overflow-x'%5D)%20%7B%20node.style%5B'overflow-x'%5D%20%3D%20'visible'%3B%20%7Dif%20('hidden'%20%3D%3D%3D%20s%5B'overflow-y'%5D)%20%7B%20node.style%5B'overflow-y'%5D%20%3D%20'visible'%3B%20%7D%7D)%3Bvar%20htmlNode%20%3D%20document.querySelector('html')%3BhtmlNode.style%5B'overflow'%5D%20%3D%20'visible'%3BhtmlNode.style%5B'overflow-x'%5D%20%3D%20'visible'%3BhtmlNode.style%5B'overflow-y'%5D%20%3D%20'visible'%7D)()Now, make an auto-detect for this and stick it into something like uBlockOrigin and we're golden. :)
On Unix, when you have Node.js installed, you can avoid the Docker overhead for creation of a bookmarklet from a JS file with a shell script like this:
cat 'kill-sticky.js' \
| tr -s '\011\012\015\040' '\040' \
| node -e 'console.log(`javascript:${encodeURIComponent(fs.readFileSync(process.stdin.fd).toString())}`)'
Insert the output as your bookmarklet's URL.javascript:for(e%20of%20document.querySelectorAll(%22body%20*%22))%7Bp=getComputedStyle(e).position;if((p===%22fixed%22)%7C%7C(~p.indexOf(%22sticky%22)))e.parentNode.removeChild(e);%7D
javascript:(function(){void([].forEach.call(document.querySelectorAll('body *'),e=>/fixed|sticky/.test(getComputedStyle(e).position)&&e.parentNode.removeChild(e)));document.body.style = 'overflow:auto !important; height:100% !important;';document.body.removeAttribute("class");document.firstElementChild.removeAttribute("style");document.firstElementChild.removeAttribute("class")})()
https://addons.mozilla.org/en-US/firefox/addon/hide-fixed-el...
https://addons.mozilla.org/en-US/firefox/addon/scroll-everyw...
That is, if you jump through the hoops to make more than the default 8 add-ons available on Firefox mobile:
https://blog.mozilla.org/addons/2020/09/29/expanded-extensio...
It works on Firefox for Android / Fenix. You'd need to use the Nightly app and a custom addon group to install it, though.
do you happen to use some other version of Firefox? I tested for stackoverflow and it didn't work. There's also a open bug about bookmarklets not working on android Firefox https://github.com/mozilla-mobile/fenix/issues/2871
I have a custom style to do this for ALL sites, warning:
1. it can break websites in unexpected ways
2. There's often a class on the <body> hiding overflow that needs to be overwritten instead/as well