CSS Anchor positioning
CSS Anchor positioning is here!
Now we can position elements relative to any element, not just the relative parent.
This would have been handy 15 years ago..
Anyway glad it’s coming now! Come on Firefox, you too.
CSS Anchor positioning is here!
Now we can position elements relative to any element, not just the relative parent.
This would have been handy 15 years ago..
Anyway glad it’s coming now! Come on Firefox, you too.
I understand the joy and pain of programming without autocomplete, but navigating your code with an lsp is so powerful, that you should take the time to set it up, learn the bindings and use it.
With neovim it’s traditionally been super hard to get working. I believe it will work without plugins, but I found it a better experience using blink.cmp
. This is how I got it working using Neovim v0.11.3
blink.cmp
(handles the auto-complete dropdown ui, just a better out of the box experience)neovim/nvim-lspconfig
(quality of life, so we don’t have to configure each LSP manually)mason-org/mason.nvim
(quality of life, for keeping your LSP servers up to date)There are multiple ways of triggering the completions. I’m a tab-person, and with blink.cmp you enable that like so:
keymap = { preset = 'super-tab' },
Finally, since we installed nvim-lspconfig
, and this is the reason we do it, we have default configs we can enable like this in our config.
Run :Mason
to manage (install) your prefered LSP servers. For web dev, this is what I use:
vim.lsp.enable('lua_ls')
vim.lsp.enable('html_lsp')
vim.lsp.enable('css_lsp')
vim.lsp.enable('ts_ls')
vim.lsp.enable('svelte')
vim.lsp.enable('biome')
Use :checkhealth vim.lsp
to debug whether it’s working for the active buffer.
As always, these tools all have one million settings available to customize into oblivion.
For completions you do smth like:
For navigating, this is the beauty of it:
"grn" is mapped in Normal mode to vim.lsp.buf.rename()
"gra" is mapped in Normal and Visual mode to vim.lsp.buf.code_action()
"grr" is mapped in Normal mode to vim.lsp.buf.references()
"gri" is mapped in Normal mode to vim.lsp.buf.implementation()
"grt" is mapped in Normal mode to vim.lsp.buf.type_definition()
"gO" is mapped in Normal mode to vim.lsp.buf.document_symbol()
CTRL-S is mapped in Insert mode to vim.lsp.buf.signature_help()
You can skip through diagnostics using [d
and ]d
.
It’s not too complicated.
The newest example is unfortunately the nx
package as detailed here: https://socket.dev/blog/nx-packages-compromised. Wild, but obvious. Can recommend you also read https://simonwillison.net/2025/Jun/16/the-lethal-trifecta/.
This one was interesting as it relies on the affected users having AI CLI tools installed and uses it to do the work of discovering and extracting sensitive files, disguised as a “pentest agent prompt”.
How do we deal with this?
Deno programs run without file, network or environment access unless you give it permissions. It looks similar to this deno run --allow-net --allow-read --allow-env server.ts
.
Socket provides both CI actions that notify you about nasty packages in your code, and they offer a a “safe npm” wrapper when you npm i
.
Claude (and the other AI CLI tools) all offer granular permissions through “tool usage” and more.
We’ll see! For sure there will be many examples as we continue to let AI control our systems.
.innerHTML()
can take you a loooong way, but there’s a breaking point where it just becomes too tedious to use, too annoying to
deal with event handlers or escaping security. So when you want to generate HTML with JS, most use a framework. But you might not need one. Sometimes it is very fine to organize to your own desires and let uhtml handle rendering + producing the HTML. And the new v5 version has (finally?) made the API less confusing, and in my experience just works.
Here’s a quick example from https://github.com/WebReflection/uhtml:
<!doctype html>
<script type="module">
import { html } from 'https://esm.run/uhtml';
document.body.prepend(
html`<h1>Hello DOM !</h1>`
);
</script>
What feels like two decades ago I was busy making masonry-style layouts for different agency & portfolio websites. Funny to see the masonry layout slowly but surely reaching the web platform as a standard.
Here’s an excerpt of the proposed (!) syntax:
.container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
item-flow: row collapse;
gap: 1rem;
}
Bots have been scraping the open web since a long time. Since the AI robots entered the game, people have become more aware. Especially when it quadruples your hosting bill… Websites are blocking the wrong AI scrapers because AI companies keep making new ones.
If you’re curious about blocking bots, check Dark Visitors’ robots.txt documentation, and if your site is on Cloudflare they offer tools too, on the network.
For another idea I needed a drawer UI like you know from mobile UI.
If you’re using React, Vaul seems good. But I’m not using React.
I prototyped a new custom element: <rough-drawer>
, but quickly learned that this pattern is commonly called a “sheet”. And since all my web components are prefixed with my last name… welcome
It’s not done, but try dragging on https://sheet.0sk.ar/ and view source.
Observable is a friendly tool, and it’s more aligned with the web with their new version.
When it comes to standard web UI, Radix is a good place to start.
SVG is wild, and this is a great intro:
uhtml
is (was?) my library of choice for rendering HTML when I don’t have a framework. It was always a very confusing API to me, but the new version seems to unify things under one module, which is relieving.
And a shout out to Ink & Switch, who continues to inspire more thinking
Also, pondering whether to post these as single posts with a bit more context, or keep it a collection whenever I have a few to share.
We’ve had the copy/pasting era of the LLMs, we have AI assistants inside our editors and now we also have them as CLI programs. Having them side-by-side with your local files and letting it loose is a sight to behold. The UI is interesting, too. Slash commands, auto-complete and a text input with many shortcuts, vim-bindings and so on. Pretty fun way to interact with your files.
claude
just works really well.
gemini
(Google’s AI) released their CLI tool and made it open source. It was interesting to read their system prompt.
Framework components are not necessarily custom elements.
Here are a few more or less related articles on the topic: