
I work in Chrome with too many tabs and profiles. When I need to remember "come back to this tab later," I used to float windows in a corner—and then I could never tell which window was which in the Window menu.
So I made a bookmarklet that drops a bright pink sticky on the page. You can add more than one, drag the header to move, drag the corner to resize, and type whatever you need. Notes for a given URL are saved in local storage, so if you close the tab and come back, running the bookmarklet again pulls your notes back. That's the limit of what a bookmarklet can do without becoming a full extension.
Features
- Multiple notes — Click the bookmark again for another sticky.
- Persistent per URL — Stored locally per origin + path + query (same page gets the same notes back).
- No server — Nothing leaves your machine.
How to use it
- Install the bookmark using the button at the top or bottom of this page (drag to the bar) or paste the code block into a new bookmark's URL field.
- On a normal website, click the bookmark. A new sticky appears; click again for another.
- Drag the header to move, the corner nub to resize, ✕ to remove a note.
- Revisit the same page later and click the bookmark to restore saved notes from storage.
Some sites fight for focus so aggressively that the textarea won't stick; if that happens, there's no magic fix—remove the note and use paper.
Safari / Firefox: Works, but I've seen small cosmetic differences. The code is yours to tweak if that bugs you.
Bookmarklet Code:
javascript:(()=>{const P="___pinkStickyNote";const STYLE_ID="__pinkStickyStyleLS";const LAYER_ID="___pinkStickyLayerLS";const KEY=(()=>{try{return"__pinkStickies::"+location.origin+location.pathname+location.search;}catch(e){return"__pinkStickies::fallback";}})();const CSS=`#${LAYER_ID}{position:fixed;inset:0;z-index:2147483647;pointer-events:none;} .${P}{position:absolute;width:220px;height:180px;background:#ff2db2;color:#111;border:2px solid rgba(0,0,0,.35);border-radius:10px;box-shadow:0 10px 25px rgba(0,0,0,.25);overflow:hidden;display:flex;flex-direction:column;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;pointer-events:auto;} .${P}__header{flex:0 0 30px;display:flex;align-items:center;justify-content:space-between;padding:0 8px;background:rgba(255,255,255,.18);border-bottom:1px solid rgba(0,0,0,.2);cursor:move;user-select:none;} .${P}__title{font-size:12px;font-weight:800;letter-spacing:.2px;opacity:.85;} .${P}__close{width:22px;height:22px;line-height:20px;border-radius:6px;border:1px solid rgba(0,0,0,.25);background:rgba(255,255,255,.25);cursor:pointer;font-weight:900;} .${P}__close:hover{background:rgba(255,255,255,.4);} .${P}__body{flex:1;padding:8px;} .${P}__text{width:100%;height:100%;resize:none;border:none;outline:none;background:transparent;color:#111;font-size:13px;line-height:1.25;} .${P}__resize{position:absolute;right:6px;bottom:6px;width:14px;height:14px;cursor:nwse-resize;background:rgba(255,255,255,.45);border:1px solid rgba(0,0,0,.25);border-radius:4px;}`;const clamp=(v,min,max)=>Math.max(min,Math.min(max,v));const ensure=()=>{let s=document.getElementById(STYLE_ID);if(!s){s=document.createElement("style");s.id=STYLE_ID;s.textContent=CSS;document.documentElement.appendChild(s);}let layer=document.getElementById(LAYER_ID);if(!layer){layer=document.createElement("div");layer.id=LAYER_ID;document.documentElement.appendChild(layer);}return layer;};const safeParse=(txt)=>{try{const v=JSON.parse(txt);return Array.isArray(v)?v:[];}catch(e){return[];}};const loadAll=()=>{try{return safeParse(localStorage.getItem(KEY)||"[]");}catch(e){return[];}};const saveAll=(arr)=>{try{localStorage.setItem(KEY,JSON.stringify(arr));}catch(e){}};const forceFocus=(el)=>{const f=()=>{try{el.focus({preventScroll:true});}catch(_){try{el.focus();}catch(__){}}};f();setTimeout(()=>{if(document.activeElement!==el)f();},0);setTimeout(()=>{if(document.activeElement!==el)f();},25);setTimeout(()=>{if(document.activeElement!==el)f();},80);};const getAllLive=()=>Array.from(document.querySelectorAll("."+P)).map(note=>{const id=note.getAttribute("data-id")||"";const x=parseInt(note.style.left,10)||0;const y=parseInt(note.style.top,10)||0;const w=parseInt(note.style.width,10)||note.offsetWidth||220;const h=parseInt(note.style.height,10)||note.offsetHeight||180;const ta=note.querySelector("textarea");const text=ta?ta.value:"";return{id,x,y,w,h,text};}).filter(o=>o.id);const upsertSave=()=>{saveAll(getAllLive());};const buildNote=(data)=>{const layer=ensure();const note=document.createElement("div");note.className=P;note.style.zIndex="2147483647";note.setAttribute("data-id",data.id);note.style.left=(data.x||0)+"px";note.style.top=(data.y||0)+"px";note.style.width=(data.w||220)+"px";note.style.height=(data.h||180)+"px";const header=document.createElement("div");header.className=P+"__header";const title=document.createElement("div");title.className=P+"__title";title.textContent="NOTE";const close=document.createElement("button");close.className=P+"__close";close.type="button";close.title="Close";close.textContent="\u2715";header.appendChild(title);header.appendChild(close);const body=document.createElement("div");body.className=P+"__body";const ta=document.createElement("textarea");ta.className=P+"__text";ta.placeholder="Type...";ta.spellcheck=true;ta.value=data.text||"";body.appendChild(ta);const resizer=document.createElement("div");resizer.className=P+"__resize";resizer.title="Resize";note.appendChild(header);note.appendChild(body);note.appendChild(resizer);layer.appendChild(note);let drag=null,resize=null;const onMove=(e)=>{if(drag){const dx=e.clientX-drag.sx,dy=e.clientY-drag.sy;note.style.left=clamp(drag.ox+dx,0,window.innerWidth-30)+"px";note.style.top=clamp(drag.oy+dy,0,window.innerHeight-30)+"px";}else if(resize){note.style.width=clamp(resize.ow+(e.clientX-resize.sx),140,900)+"px";note.style.height=clamp(resize.oh+(e.clientY-resize.sy),90,900)+"px";}};const onUp=()=>{drag=null;resize=null;document.removeEventListener("mousemove",onMove,true);document.removeEventListener("mouseup",onUp,true);upsertSave();};header.addEventListener("mousedown",(e)=>{if(e.button!==0)return;e.preventDefault();drag={sx:e.clientX,sy:e.clientY,ox:parseInt(note.style.left,10)||0,oy:parseInt(note.style.top,10)||0};document.addEventListener("mousemove",onMove,true);document.addEventListener("mouseup",onUp,true);},{capture:true});resizer.addEventListener("mousedown",(e)=>{if(e.button!==0)return;e.preventDefault();e.stopPropagation();resize={sx:e.clientX,sy:e.clientY,ow:note.offsetWidth,oh:note.offsetHeight};document.addEventListener("mousemove",onMove,true);document.addEventListener("mouseup",onUp,true);},{capture:true});close.addEventListener("click",(e)=>{e.stopPropagation();note.remove();upsertSave();},{capture:true});let tmr=null;ta.addEventListener("input",()=>{if(tmr)clearTimeout(tmr);tmr=setTimeout(()=>upsertSave(),250);},{capture:true});ta.addEventListener("blur",upsertSave,{capture:true});ta.addEventListener("pointerdown",(e)=>{e.stopPropagation();forceFocus(ta);},{capture:true});return{note,ta};};const already=new Set(Array.from(document.querySelectorAll("."+P)).map(n=>n.getAttribute("data-id")).filter(Boolean));for(const s of loadAll()){if(s&&s.id&&!already.has(s.id))buildNote(s);}const id=String(Date.now())+"-"+Math.random().toString(16).slice(2);const w=220,h=180;const x=clamp(Math.round((window.innerWidth-w)/2),0,window.innerWidth-w);const y=clamp(Math.round((window.innerHeight-h)/2),0,window.innerHeight-h);const created=buildNote({id,x,y,w,h,text:""});upsertSave();setTimeout(()=>forceFocus(created.ta),0);})();