Vim-style modal element picker & permanent hider for Tampermonkey. Select any page element, compose a multi-criteria fingerprint (structural path + tag + id + classes + text content), and hide matching elements permanently across page reloads.
Inspired by react-grab's hover UI, but purpose-built for persistent ad/distraction removal rather than React component inspection.
| Action | What happens |
|---|---|
Ctrl+Shift+H |
Toggle HIDE mode — stays active until you exit (Vim-style modal) |
| Hover | Pink overlay highlights the element under the cursor + floating label showing tag#id.class |
| Scroll wheel | Expand/shrink selection scope along the DOM tree |
| Click | Open the filter popover to compose hide criteria |
| Check conditions | Combine path / tag / id / individual classes / text content — preview match count and highlighted elements in real time, then click Hide |
p |
Open the rules panel to review, toggle, or delete rules |
Esc |
Close popover → close panel → exit HIDE mode (layered dismissal) |
When HIDE mode is active, a Vim-style status line appears in the bottom-left corner:
-- HIDE -- div.ad-banner [3 rules on this site] scroll:expand click:hide p:panel esc:exit
It shows the current target element description, active rule count, and a reminder of available keys.
When you click an element, a popover lists every candidate condition. Conditions are AND-combined — the element must match all checked criteria to be hidden.
| Condition | Default | Notes |
|---|---|---|
| path | checked | Structural body > ... > :nth-of-type(n) chain. Pins a single element precisely, immune to CSS class churn. |
| tag | off | e.g. div, aside, iframe |
| id | off | Only shown if the element has an id attribute |
| class | off | Each class shown as a separate checkbox (for CSS-in-JS sites where you may only want to match one of the hashed classes) |
| text | off | Trimmed & whitespace-collapsed content, first 80 chars. Matches prefix or exact. |
Path is checked by default because it uniquely anchors the selection. For
broader hiding (e.g. "all ads in a feed"), uncheck path and combine tag +
class instead.
Press p to open the panel (also accessible from the Tampermonkey menu):
- Toggle: Temporarily re-show elements hidden by a rule without deleting it
- Delete: Permanently remove a rule
- Hover: Hovering a disabled rule highlights its matching elements in orange on the page
| Channel | When applied | Mechanism |
|---|---|---|
| Pure CSS | document-start (before first paint) |
Rules without a text condition are compiled to CSS selectors and injected into a <style> tag. Zero flicker. |
| JS text-match | DOMContentLoaded + MutationObserver |
Rules with a text condition use querySelectorAll + JS filter. Tiny flash possible on very slow pages. |
Rules are stored per-origin in Tampermonkey's GM_setValue storage under
eg-rules:<origin>. The userscript runs on *://*/* so rules accumulate
separately for each site you visit.
A MutationObserver watches for inserted/changed nodes and re-applies JS-based
rules with a 250 ms debounce.
All UI (overlay, label, popover, panel, status bar) lives inside a single
#eg-host Shadow DOM node. Styles are fully isolated — no interference with
page CSS.
- Install Tampermonkey for your browser
- Open
element-grab.user.jsfrom this repository, or copy-paste the raw contents into Tampermonkey's "Create a new script" editor - The script activates on every site (
@match *://*/*). Rules are origin-scoped, so they only apply to the site where they were created.
Remove the script from Tampermonkey's dashboard. Rules stored in
GM_setValue will persist until you either:
- Delete them from the panel while the script is still installed, or
- Clear Tampermonkey's storage for the affected origins via the browser's developer tools
- Text-based rules may flicker briefly on pages that take a long time to render their initial DOM. This is inherent to text matching — you need DOM content to check text. Prefer pure-CSS conditions (path + tag + class + id) for zero-flicker hiding.
- Preview caps at 50 elements to avoid layout thrashing on large matches.
- No cross-site sync — rules live on the browser where they were created.
- No regex or substring text matching in v0.1. Text matches are prefix or exact (whitespace-collapsed, first 80 chars).
MIT