Custom fonts in your GitHub README with SVG

Gaurav Joshi
5 min read1 day ago

--

If you use GitHub, you might at some point wonder whether it’s possible to change the font in your project repository README. Perhaps you used a fancy font in the interface or the logo and now you want the project README to reflect the same style.

I wanted to create a GitHub profile README and wondered if I could make it look like my current resume header. While I have used Carlito font in my resume, GitHub README doesn’t allow custom fonts. This means I can bring the look of my profile README closer to my resume header, but not match it exactly. Where’s the fun in that?

Obviously, there are workarounds, especially since I was not looking for a custom font throughout the README, just in the header. Let’s evaluate the most obvious workaround — using images. Most projects include their logo in the README, usually as a logotype. It’s the most convenient solution.

This approach works well for something like a logotype or small icons and images that don’t change frequently. However, I, for one, frequently update my resume. To keep my profile README truly in sync with my resume, I’d have to create and upload a new image on GitHub every time I make a minor change or adjustment. Additionally, consider the hassle of creating separate images for both light and dark modes.

Ideally, I should be able to update the text, style, or font in my resume and replicate the same in my GitHub profile README with minimal effort.

Enter SVG. It’s still an image, but…

GitHub README files are essentially Markdown files and support embedding SVG images. One of the things I love about SVG is that it’s an XML-based (text-based) format for describing images. This means, if you know what you’re doing, you can create and edit SVG images using a simple text editor. SVG also supports a substantial subset of CSS properties, allowing me to replicate the resume header easily, complete with the font and styles to match. Since SVGs are easily editable, I can make any number of updates to the resume header and reflect those in the README with ease. How exciting!

However, before I could embed an SVG in my README, I needed to figure out how to include Carlito font in the SVG itself. My friend Google led me to a useful blog that has listed various methods for using a font in an SVG. Including a font with @import won’t work because GitHub usually strips out any external resources when rendering a README. Embedding font data using Base64 encoding, on the other hand, worked. Once again, Google found me a tool to convert a TTF font file to Base64 encoding.

Once I had the font converted to Base64 encoding, I could replicate my resume header as SVG within minutes:

<svg xmlns="http://www.w3.org/2000/svg" width="400px" height="110px" text-anchor="middle">
<defs>
<style>
@font-face {
font-family: "Carlito";
src: url(data:application/font-ttf;charset=utf-8;base64,base64_data);
font-weight: normal;
font-style: normal;
}
.heading {
font-family: "Carlito";
font-size: 36px;
fill: #3B3838;
letter-spacing: 4px;
text-transform: uppercase;
}
.sub-heading {
font-family: "Carlito";
font-size: 20px;
fill: #767171;
letter-spacing: 0.5px;
}
</style>
</defs>

<text class="heading" x="50%" y="40">
Gaurav Joshi
</text>

<text class="sub-heading" x="50%" y="75">
Software Engineer | San Francisco Bay Area
</text>
</svg>
  • @font-face CSS at-rule specifies Carlito font to be used in the SVG. (base64_data in src prop is to be replaced with the actual Base64 data of Carlito font.)
  • The .heading and .sub-heading styles correspond to the heading and subheading in my resume.
  • The <text> element renders the contained text — in this case my heading and the subheading.
  • The text-anchor="middle" attribute on the <svg> element ensures that all the contents are horizontally center-aligned.

I saved the SVG as profile-header.svg file in my repository and then created a README.md to include the SVG:

<p align="center">
<picture>
<img src="profile-header.svg" alt="Gaurav Joshi" />
</picture>
</p>
  • When the <img> element is wrapped in <picture>, GitHub won’t render it as a link to the corresponding file in the repository. It also has an added advantage that we’ll touch upon in a moment.

Here’s the result:

My GitHub profile in light mode

However, there’s a catch. Isn’t there always one? This is how my profile now looks in dark mode:

My GitHub profile in dark mode

When GitHub renders text in the README, it automatically adjusts the color to black or white depending on whether light or dark mode is being used. My SVG doesn’t have this automatic adjustment. Fortunately, GitHub provides a way to specify different images for light and dark modes.

But first, I needed a version of my SVG for dark mode. I created a copy of profile-header.svg and renamed the original to profile-header.light.svg, while naming the copy profile-header.dark.svg. In the dark mode SVG, I simply changed the styles for .heading and .sub-heading, specifically adjusting the text color. I used this tool to get an idea of the colors needed for dark mode.

Here’s the change I made in profile-header.dark.svg:

...

.heading {
font-family: "Carlito";
font-size: 36px;
- fill: #3B3838;
+ fill: #C6C3C3;
letter-spacing: 4px;
text-transform: uppercase;
}
.sub-heading {
font-family: "Carlito";
font-size: 20px;
- fill: #767171;
+ fill: #8F8A8A;
letter-spacing: 0.5px;
}

...

And then, in README.md:

<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="profile-header.dark.svg" />
<img src="profile-header.light.svg" alt="Gaurav Joshi" />
</picture>
</p>
  • This is the added advantage of wrapping the <img> element in <picture>. The <source> element allows me to specify a different SVG for dark mode and my original SVG for light mode.

With that, here’s how my profile looks in dark mode:

My GitHub profile in dark mode

Now, when I make changes to my resume, it’s relatively easy to keep my GitHub profile in sync. Any update to the font will just require new Base64 encoding in the SVG. New styles will require modifying style classes in the SVG. Changes in content will need updating the contents of the <text> element, and changes in layout will require rearranging the <text> elements. Mission accomplished!

Other than the resume header, I just included a couple of social media links in my GitHub profile. You can check it out here.

--

--

Gaurav Joshi

Master craftsman of innovative cross-browser compatible bugs.