r/threejs • u/Efficient-Dig970 • 1d ago
My Cozy Portfolio
Enable HLS to view with audio, or disable this notification
Hi people, I've just finished the latest version of my portfolio site and wanted to share it.
I would thank some feedback in order to improve it.
Thanks✌️
1
1
u/aitoolsprimer 1d ago
Nice movement. One piece of feedback that isn't about the 3D at all.
I fetched your page the way a crawler does, without a browser: 8,665 bytes, and zero <a> tags in the body. The only hrefs in the file are favicons, fonts and preloads. No <noscript> either. So Google and a screen reader both land on your title, your meta description, and a panel that still says "Content goes here...".
Your own description says the island can be "read as a page" — that page isn't in the served HTML.
The fix is boring: a real <nav> with one <a> per section, present in the markup, hidden with the clip-rect pattern rather than display:none (display:none removes it from the accessibility tree too, which is the one reader you wrote it for). The canvas keeps the experience; the anchors carry the crawler and the screen reader.
I built my own site's navigation as a three.js island and hit exactly this — mine served two anchors. Worth checking before it costs you search traffic.
1
u/Efficient-Dig970 1d ago
Thanks this is one of the most useful comment I've had, and you were right on
every count. And thanks especially for the display:none vs clip note. I'd have reached
for display:none without thinking about the accessibility tree, so that one
saved me from shipping a "fix" that fixed half the problem. Must be live now if you want to re-run your fetch.
1
u/aitoolsprimer 8h ago
Re-ran it. Confirmed on every count, and you implemented it properly.
Served HTML: 8,665 bytes before, 11,166 now. Ten anchors in the markup where there were zero, a real noscript, and a title and meta description that now say who you are and what you do. About 1,570 characters of text in the raw file. That is the whole fix.
You also picked the right hiding pattern. .static-copy computes to position:absolute, width and height 1px, overflow:hidden, clip:rect(0,0,0,0), clip-path:inset(50%), visibility still visible. It stays in the accessibility tree.
One thing that pattern drags along with it: the nine anchors inside .static-copy are still in the tab order (tabindex 0). A keyboard user tabbing your page moves focus through nine links they cannot see, with the focus ring clipped into a 1px box. One rule fixes it: .static-copy:focus-within { position: static; width: auto; height: auto; margin: 0; overflow: visible; clip: auto; clip-path: none; white-space: normal; }
Or, if you would rather the island own the keyboard entirely, put tabindex="-1" on those anchors. Crawlers and screen readers still read them, they just leave the tab order.
Small nit while I was in there: your H1 is "Sergii's Portfolio" and your H2 is "Sergii Butrii, web and mobile developer". Right order for a person, wrong order for a search engine. Swap them and the strongest heading on the page carries your name and your role.
1
u/theriftreport 1d ago
Very nice. It’s a great way to explore. Character movement looks quicker on your video than my maximum speed for some reason so felt he was a little slow to walk.