Skip to content

Instantly share code, notes, and snippets.

@dance2die
Last active August 24, 2021 20:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dance2die/6c80c38e7df6c6f3df006be3820621ad to your computer and use it in GitHub Desktop.
Save dance2die/6c80c38e7df6c6f3df006be3820621ad to your computer and use it in GitHub Desktop.
Blogs before migration to Next.js from Gatsby.js
title date
How to add Tailwind CSS for Docusaurus
2021-06-22

Steps

  1. Install Docusaurus
  2. Install and Configure Tailwind CSS
    1. Install Tailwind CSS:

      • npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
    2. Configure Tailwind CSS

      • Generate postcss.config.js and tailwind.config.js: npx tailwindcss init -p
    3. Purge configuration

      • Update tailwind.config.js

         module.exports = {
           purge: [ './src/**/*.{js,jsx,ts,tsx}' ],
         };
    4. Apply Tailwind CSS prefix

      • to prevent Docusaurus class nameing collision

      • Update tailwind.config.js.

         module.exports = {
           prefix:  'tw-',
         };
    5. Include Tailwind CSS.

      • Create src/css/tailwind.css

      • Do NOT include @tailwind base; because it will reset CSS breaking Docusaurus styles.

         @tailwind components;
         @tailwind utilities;
    6. Configure docusaurus.config.js to include Tailwind CSS file

       ```diff
       module.exports = {
         /** ... **/
         presets: [
           [
             "@docusaurus/preset-classic",
             {
               docs: {
                 ...
               blog: {
                 ...
               },
               theme: {
                 - customCss: require.resolve('./src/css/custom.css'),
                 + customCss: [require.resolve("./src/css/custom.css"), require.resolve("./src/css/tailwind.css")],
               },
             },
           ],
         ],
       };
      
       ```
      
title date
GitHub Universe Gradient Border Button
2021-06-11

In the previous post, "GitHub Universe Gradient Border Card", I showed you how to apply a gradient "fake" border for a card component.

This post will show you how to apply the gradient style for a button.

Slightly different as hover will change the whole button color instead of that of borders.

gh universe gradient button

Demo: https://codepen.io/dance2die/pen/RwpegqY?editors=1100

Overview

Similar to the card component,

  1. Create a block element wrapping an anchor element
  2. Add ::before content, slightly smaller than the block element
  3. Add ::after content, which has the same size as the element

Details

Here is the "button" element (actually just an anchor that looks like a button).

<div class="wrapper">
  <a href="#" class="button"><span>View All</span></a>
</div>

Button wrapper setup

As you will position borders using an absolute positioning with z-index,
you need to set the relative positioning and isolate so that z-index doesn't affect the rest of the document.

CSS variables defined here will be available to children.
--offset is the border width.

.wrapper {
  position: relative;
  isolation: isolate;

  --width: 120px;
  --height: 40px;
  --offset: 2px;
}

Button setup

Create a transparent button without anchor underline.
The size should use the dimension defined in main element.

transition makes the color change more graceful, less jumpy.

.button {
  width: var(--width);
  height: var(--height);

  text-decoration: none;
  color: white;
  background: transparent;

  transition: color 0.3s ease-in-out;
  
  /* rest is for setting link style/position */
  ...
}

Button Background

The content area of .button::before will provide the button background.

Absolutely position the background smaller than half of offset on each side (top/left/width/height).
to show the border through it.
z-index: -1 will let .button content (<span>View All</span>) to show up on top of the background.

.button::before {
  display: block;
  content: "";
  position: absolute;

  top: calc(var(--offset) / 2);
  left: calc(var(--offset) / 2);
  width: calc(var(--width) - var(--offset));
  height: calc(var(--height) - var(--offset));
  background: #000;
  z-index: -1;
}

Button Border

Absolutely position the border, which has the same size as .button.
It should show up behind the content as well as the background (z-index: -3).

But since the border content is bigger than the background, .button::after will look like a border for the button.

.button::after {
  display: block;
  content: "";
  position: absolute;

  top: 0;
  left: 0;
  width: var(--width);
  height: var(--height);

  /* Gradient copied from GitHub Universe 2020 */
  background: linear-gradient(267.91deg, #ffe57f 9.35%, #ff7170 96.48%);

  z-index: -3;
}

Changing colors on hover

When you hover over the button, setting the background color opacity transparent will make the button same color as the border.

.button:hover is optional as the text looks better in this case as black.

.button:hover {
  color: #000;
}
.button:hover::before {
  opacity: 0;
}
title date updated_on
GitHub Universe Gradient Border Card
2021-06-09
2021-06-11

GitHub Universe has a list of "boxes" with gradient backgrounds.

gh universe border color

They aren't really borders but faked to look so.
Here is the demo.

Overview

Here is how the card is implemented.

  1. Create a block element
  2. Add a ::before content, which is slightly smaller than the block element
  3. Add an ::after content, which has the same size as the element

box

Details

Size and Location

First, we need to set the size of the element, ::before, and ::after.

--offset is the "border width" (named so because they aren't really border width".)

  • .box has the width/height - offset value (emulating box-sizing: border-box)
  • .box::before has the same size as .box but moved down-right by half the amount of the offset
  • .box::after takes up the full width/height. The offset amount will show throuh .box::before as a border.

Note that display: "block"; (or inline-block) is required to be able to set width/height.

.box {
  --width: 300px;
  --height: 200px;
  --offset: 15px;
  
  width: calc(var(--width) - var(--offset));
  height: calc(var(--height) - var(--offset));
}

.box::before {
  display: "block";
  top: calc(var(--offset) / 2);
  left: calc(var(--offset) / 2);
  width: calc(var(--width) - var(--offset));
  height: calc(var(--height) - var(--offset));
}

.box::after {
  display: "block";
  top: 0;
  left: 0;
  width: var(--width);
  height: var(--height);
}

Positioning Pseudo Elements

Without content, pseudo elements wont' show. To place content with top/left relative to the current element, we can position them with absolute.

.box::before {
  content: '';
  position: absolute;
...
}

.box::after {
  content: '';
  position: absolute;
  ...
}

Setting Background Colors

The main content's background color is applied in ::before, while the border color is in ::after.

.box::before {
  background: #000;
}

/* Background linear gradient here is shown as a border */
.box::after {
  /* a cool background copied from GH Universe */
  background: linear-gradient(
    269.16deg,
    #ffe580 -15.83%,
    #ff7571 -4.97%,
    #ff7270 15.69%,
    #ea5dad 32.43%,
    #c2a0fd 50.09%,
    #9867f0 67.47%,
    #3bf0e4 84.13%,
    #33ce43 105.13%,
    #b2f4b6 123.24%
  );
}

Showing Borders

For the :before content to show on top of :after, you need to set z-index values.
z-index in :before is higher than that of :after but lower than that of current block.

e.g.

.box {
/* no z-index needed */
}

.box::before {
  z-index: -1;
}

.box::after {
  z-index: -3;
}

Changing Border Color on Hover

If you want to change the border brighter on hover,
we can set the opacity of gradient (in ::after) lower, and increase it on hover.

.box::after {
  opacity: 0.7;
}

.box:hover:after {
  opacity: 1;
}

Showing a list of "Boxes".

The above code will work for a box only.
("borders" will overlap with other boxes without following instruction.)

To show a list of boxes, you need to wrap each block element with another block element, with position: relative applied.
Or else "borders" will overlap because of position: absolute for the box.

List of boxes

<main>
  <div class="relative"><div class="box">Box1</div></div>
  <div class="relative"><div class="box">Box2</div></div>
  <div class="relative"><div class="box">Box3</div></div>
  <div class="relative"><div class="box">Box4</div></div>
  <div class="relative"><div class="box">Box5</div></div>
  <div class="relative"><div class="box">Box6</div></div>
</main>

Updated CSS

Demo: https://codepen.io/dance2die/pen/xxqamLa?editors=1100

Updated CSS also fixes the .box size.

main {
    --offset: 20px;

  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: calc(var(--offset) * 2);
  
  padding: 1.5rem 1rem;
  height: 100%;
  width: 750px;

  overflow-x: scroll;
  position: relative;
}

.relative {
  position: relative;
}

.box {
  --width: 300px;
  --height: 200px;

  flex-shrink: 0;
  width: var(--width);
  height: var(--height);
  padding: calc(var(--offset) / 2);

  display: grid;
  place-items: center;

  color: white;
  font-size: 3rem;
  font-weight: bold;
}

.box::before {
  content: "";
  display: block;
  position: absolute;
  background: #000;
  top: calc(var(--offset) / 2);
  left: calc(var(--offset) / 2);
  width: calc(var(--width) - var(--offset));
  height: calc(var(--height) - var(--offset));
  z-index: -1;
}

.box::after {
  content: "";
  display: block;
  position: absolute;
  background: linear-gradient(
    269.16deg,
    #ffe580 -15.83%,
    #ff7571 -4.97%,
    #ff7270 15.69%,
    #ea5dad 32.43%,
    #c2a0fd 50.09%,
    #9867f0 67.47%,
    #3bf0e4 84.13%,
    #33ce43 105.13%,
    #b2f4b6 123.24%
  );
  opacity: 0.7;
  top: 0;
  left: 0;
  width: var(--width);
  height: var(--height);
  z-index: -3;
}

.box:hover::after {
  opacity: 1;
}
title date
CSS variable is not assinable in TypeScript React
2021-07-20

When you use React with TypeScript, you have have seen an error like this.

not assinable react cssproperties

Type '{ "--language-color": string; }' is not assignable to type 'Properties<string | number, string & {}>'. Object literal may only specify known properties, and '"--language-color"' does not exist in type 'Properties<string | number, string & {}>'. The expected type comes from property 'style' which is declared here on type 'DetailedHTMLProps<HTMLAttributes, HTMLElement>'

Cast it to React.CSSProperties.

<i
          style={{ "--language-color": item.primaryLanguage.color } as React.CSSProperties}
          className={`w-4 h-4 rounded-full bg-[var(--language-color)]`}
        />
title date tags
Copying MDX Frontmatter image to Public folder in Nextjs
2021-08-11
issues, nextjs, nodejs, fs, troubleshooting

There is no built-in mdx-bundler way to extract banner image mentioned in frontmatter. kentcdodds/mdx-bundler#70

Had to use fs to copy it to the public folder manualy.

title date
Moonlander Oryx configuration on Ubuntu
2021-08-11

Issue

Flashing Moonlander on Ubuntu (I am using 21.04) caused following error in console.

warning OpenDevices: libusb: bad access [code -3]

Fixes

  1. Install dependency
sudo apt install libusb-dev
  1. Create a udev rule file
sudo touch /etc/udev/rules.d/50-wally.rules
  1. Add Moonlander configuration in the rule file
# STM32 rules for the Moonlander and Planck EZ
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", \
    MODE:="0666", \
    SYMLINK+="stm32_dfu"

Now reboot!!!

Resources

  1. https://github.com/zsa/wally/wiki/Linux-install#2-create-a-udev-rule-file
  2. https://pcfr.uk/2020/11/29/actually-playing-with-ergodox.html
title date
VSCode oembed link update with RegEx
2021-08-24

My previous Gatsby blog required gist:dance2die/{gistID} format to process GitHub gists.

To take advantage of oEmbed links, I decided to use a full URL.

There were over 300+ gists to process and manual replace seemed ridiculous.

Found this article, VS Code: Search-and-Replace Regex, which explained how to replace regex expressions to replace.

When I matched gist:(.*?) I saw 328 matches. I can refer to the matched group (.*?), which contains dance2die/{gistID} using $1 (first match). I can now append the gist link to the match with https://gist.github.com/$1.

VSCode shows the replacement string inline, and confirmed they work before replacing.vscode regex replace

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment