Skip to content

DIY Configure bold and italic faces

[ Consider using the fontaine package from GNU ELPA (by Protesilaos) for all font-related configurations. ]

The Modus themes do not hardcode a :weight or :slant attribute in the thousands of faces they cover. Instead, they configure the generic faces called bold and italic to use the appropriate styles and then instruct all relevant faces that require emphasis to inherit from them.

This practically means that users can change the particularities of what it means for a construct to be bold/italic, by tweaking the bold and italic faces. Cases where that can be useful include:

  • The default typeface does not have a variant with slanted glyphs (e.g. Fira Mono/Code as of this writing on 2021-07-07), so the user wants to add another family for the italics, such as Hack.
  • The typeface of choice provides a multitude of weights and the user prefers the light one by default. To prevent the bold weight from being too heavy compared to the light one, they opt to make bold use a semibold weight.
  • The typeface distinguishes between oblique and italic forms by providing different font variants (the former are just slanted versions of the upright forms, while the latter have distinguishing features as well). In this case, the user wants to specify the font that applies to the italic face.

To achieve those effects, one must first be sure that the fonts they use have support for those features. It then is a matter of following the instructions for all typeface tweaks.

Font configurations for Org and others.

In this example, we set the default font family to Fira Code, while we choose to render italics in the Hack typeface (obviously you need to pick fonts that work well together):

emacs-lisp
(set-face-attribute 'default nil :family "Fira Code" :height 110)
(set-face-attribute 'italic nil :family "Hack")

And here we play with different weights, using Source Code Pro:

emacs-lisp
(set-face-attribute 'default nil :family "Source Code Pro" :height 110 :weight 'light)
(set-face-attribute 'bold nil :weight 'semibold)

To reset the font family, one can use this:

emacs-lisp
(set-face-attribute 'italic nil :family 'unspecified)

To ensure that the effects persist after switching between the Modus themes (such as with M-x modus-themes-toggle), the user needs to write their configurations to a function and pass it to the modus-themes-after-load-theme-hook (Enable and load). This is necessary because themes set the styles of faces upon activation, overriding prior values where conflicts occur between the previous and the current states (otherwise changing themes would not be possible).

A theme-agnostic hook for theme loading.

This is a minimal setup to preserve font configurations across theme load phases. For a more permanent setup, it is better to rely on the custom-set-faces function: set-face-attribute works just fine, though it probably is better suited for quick previews or for smaller scale operations (custom-set-faces follows the format used in the source code of the themes, which can make it easier to redefine faces in bulk).

emacs-lisp
;; our generic function
(defun my-modes-themes-bold-italic-faces (&rest _)
  (set-face-attribute 'default nil :family "Source Code Pro" :height 110)
  (set-face-attribute 'bold nil :weight 'semibold))

;; or use this if you configure a lot of face and attributes and
;; especially if you plan to use `modus-themes-with-colors', as shown
;; elsewhere in the manual
(defun my-modes-themes-bold-italic-faces (&rest _)
  (custom-set-faces
   '(default ((t :family "Source Code Pro" :height 110)))
   '(bold ((t :weight semibold)))))

;; and here is the hook
(add-hook 'modus-themes-after-load-theme-hook #'my-modes-themes-bold-italic-faces)

Use theme colors in code with modus-themes-with-colors.

Using a hook at the post-load-theme phase.

Reload the theme for changes to take effect.