Some javascript would have been nice
I want my blog to be as javascript-less as it can be (so none). Why ?
- I hate writing js
- Better support across the board, especially all the weirdos with JS deactivated (me)
- I hate writing js
- I must be masochistic, and doing everything the hard way is always so funier
All is fine and good, since all posts here are statically generated, no javascript needed.
That was before I started thinking about code snippets. Now, I wish I wasn't a stubborn idiot and could write some javascript.
Code snippets and today's expectations
This blog's code snippets are generated using pygments and custom lua code, to fix indentation and add line numbering spans. So far so good, no javascript needed.
Although, if you read this post's title, you know we are talking copy here. Modern websites with code snippets all have something in common : a copy button !
Typically, those are created using bits of javascript and its clipboard API, but we want none, what should/can we do ?!
Not a lot in term of copy. Using today's CSS API, one cannot (as I know of) modify the system nor secondary clipboard. Our best workaround is to make whole-text selection easier, so copying is not as painful as it can be.
I thought you were a perfect match
Base state
I started to look at user-select
and pointer-events
, thinking I could pull some type of wizardry using hover states.
Sadly, this proved to not be viable (or I just could not pull it off).
Starting with a simple pre element :
This is a simple
multiline codeblock.
And adding a span element over our code snippet :
This is a simple
multiline codeblock.
Adding magic (or trying to)
Now, the idea was :
-
Set
cursor: pointer
on the span to fake a select button. -
When the span element is hovered, set its
pointer-events
to none, so all mouse events are transfered to the pre element -
Using the following selector,
span:hover ~ pre
, we are able to setuser-select
to all -
For the user, it feels like clicking on the button ends up selecting the whole code snippet whereas in reality they just clicked on the pre element with
user-select: all
-
Hide the span to screen readers as those do not need extra information
Users now only need to press Ctrl+c to have the selected code in their clipboard. Let's try this plan out !
This is a simple
multiline codeblock.
So you can easily see when everything aligns magically, the pre background turn aqua when you can finally click to select.
As you can see, it is not easy nor fast to trigger our desired state.
previous revisions: note on tactil screen
- version 1
-
And I'm pretty sure this won't work, or be even worst, on mobile. - version 2
-
So... I'm writing this paragraph after some tests : this version works soooo good on tactil screens : on my linux-surface and my android, it's perfect !
This makes the desktop failure that sadder, ahaha.
What I landed on, for now at least
local function gcdn(numbers)
local a = numbers[1]
for i = 2, #numbers do
local b = numbers[i]
while b ~= 0 do
a, b = b, a % b
end
end
return a
end
position: absolute
.
IMO, the codeblock looks nicer and everything is clearer since I can write more explicative text.
previous revisions: landed on button explanations
- version 1
-
Here, one can click on the
[select]
, to make the pre element selectable in one click, withuser-select: all
.
Once the all-select feature is no longer needed, another click on[stop]
, and things are back to normal.
minimal working example
<div>
<pre><code>:root {
display: none;
}</code></pre>
<label><input type="checkbox" />single click text selection</label>
</div>
div { position: relative; }
pre:has(~ label > input:checked) {
user-select: all;
}