3DRX

// post

Copy code button using vanilla js

adding copy code button to my blog

Updated

This blog is build on top of the Astro.js blog template, which is great. But it doesn’t provide a copy code button for every code block by default. So I’m adding it by myself.

Crafting the button

I found this repo containing the perfect copy code button I want, so I used this code. The author also have a YouTube video explaining the code, please check it out.

However, the layout approach the above component offered is not optimal, when the code block scrolls horizontally, the button scrolls with it too.

Down below is my workaround to the problem.

Changing layout

By analyzing the HTML generated by Astro, I found that all code block is a pre object. And the “copy” button should be a div that floats in the top right corner of the pre.

My approach using vanilla js and css:

let blocks = document.querySelectorAll("pre");

blocks.forEach((block) => {
  // replace every pre with a div containing a pre and a copy-code-button
  let div = document.createElement("div");
  div.classList.add("code-block-wrapper");
  let button = document.createElement("copy-code-button");
  div.appendChild(button);
  div.appendChild(block.cloneNode(true));
  block.replaceWith(div);
});
.code-block-wrapper {
  position: relative;
}
pre {
  padding: 1rem;
  border-radius: 12px;
  padding: 1rem;
  border-radius: 0.5rem;
  position: relative;
}
pre > code {
  all: unset;
  overflow: auto;
}
.code-block-wrapper > copy-code-button {
  z-index: 99;
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  overflow: hidden;
  visibility: hidden;
}
.code-block-wrapper:hover > copy-code-button {
  visibility: visible;
}