Styling of PEPs

I think the contrast with the page background is too much for both hyperlinks and inline code background in dark mode

1 Like

Assuming you’re talking about the dark mode, I got a few requests to increase contrast over my original colour scheme, for readability and WCAG concerns.


1 Like

Currently, the contrast ratio for hyperlinks is about 9:1 (and 12:1 for normal text), WCAG requires a minimum of 4.5:1, and recommends 7:1 (and in my experience 5 to 7 is a good ratio for dark mode). Manually lowering the value of the hyperlinks down to 5:1 looks good for me.

By “looks good”, I mean the text doesn’t start to defocus and halo in my eyes when I’m sitting in a dark room.

Should we continue this discussion in another thread / on the PR?


You can blame me for that, since I asked @AA-Turner to increase the contrast on both those elements to improve readibility and accessability.

The links were previously darker blue, but I found them difficult to read them at smaller sizes (since the perceptual contrast to the human eye of blue with black is much lower than that of text closer to green), so @AA-Turner made them lighter. Furthermore, to note, even with the lighter color the contrast of the links with the background is still only 9.5, which is substantially less than the contrast of the regular text with the background, at 11.8. So I’m not sure how the contrast of the links could be too much, at least relative to the background, while the regular text is fine.

The inline code background was previously #222 instead of #333, but it took substantial effort to easily tell apart from regular text, at least on a moderately old, non-HDR 1200p Pro-IPS monitor; on older TN panels, or with poor settings or calibration or narrower gamut, it could be almost impossible.

This looks really good to me (I like the higher contrast too), although I had to boost the text to 125%.


Pinging @hugovk in case he has any comments.

I’m not sure I understand why having a contrast ratio lower than the regular text, as we both note, is too high contrast. Could you explain the downside you’re seeing here? Links shouldn’t be much harder to read than regular text, and as “readibility counts”, I think it should trump aesthetics here.

That said, if it is really seen as a problem, it could be reduced somewhat while still mostly preserving readability and accessibility. #7ae, for example, comes in only a little above the 7:1 contrast ratio specified as the minimum by the WCAG AAA standard and is still quite readable to my eye, while reducing contrast substantially over the 9.7:1 of the current #8bf.

As for the inline code, I don’t think it should go much lower as I already can barely tell it apart, and even at #222 its virtually invisible to my eye.

Just FYI, the PR was merged after substantial back and forth about the colors, and not sure its worth creating a new thread just for that, but that’s up to @AA-Turner .

On an unrelated note, @AA-Turner is there a reason to inject the a long ToC at the top of each PEP and display it in the sidebar in the new theme? Can we just drop the former, which will make PEPs shorter (e.g. by a full page on a 1200p monitor for PEP 8), looks less redundant, and ensure the abstract displays “above the fold” without pages of scrolling and the body text is easy to get to?

Good to know; was that on the dark theme or both? Its certainly something worth considering bumping up the size a notch or two further; while the text size is one tick bigger (16 px vs 15 px on the old PEPs), preferred text sizes on the web have gotten larger over the years as the viewing habits have changed. Also, I’ve noticed that source code renders much larger than the text, which looks kinda awkward, is much larger than the legacy build system and means that a PEP 8 79-character line will not fit on one line.

What I might suggest is boosting the body font size to 1.05 rem/17 px and reducing the code font size to 0.95 rem / 15 px, which evens out this difference, allows 80 characters to comfortably fit on one line like before, and makes the body text easier to read for those on small screens or with not so good eyesight, while only increasing total length by a small fraction.


For me, both.

Certainly true for me! :nerd_face:


I think this is a typeface issue. If you remove Cascadia Mono from the code fonts within Firefox/Chrome devtools, does it look more normal? I can’t remember why I picked Cascadia in the first place, or why I put it second. Note that the font size should be identical for prose and code.

consider bumping up the size a notch or two

I’d sort of be against this – the idea of using (r)em as the units in the CSS is so that user agents with greater default font sizes scale automatically. Equally zoom scale is remembered across a domain, so I think this is a fairly quick fix on the end-user end. (Sorry for being the awful person to say no, but by changing the default text size once we will inevitably get requests to make it bigger / smaller / squigglier – as long as the defaults don’t prohibit people (reasonably) setting these things locally, I would keep the status quo ante.)

I would probably be OK with changing the dark mode code theme one more time, but I don’t want to get into the business of overriding specific colours.

why have two tables of contents

Beyond tradition (10 years at least, perhaps longer), I think the “full page” table of contents does offer benefits – the sidebar one is more compressed, and so for PEPs with very long section titles the extra horizontal space can be beneficial.

Perhaps we could adopt the wikipedia model though, and keep the full ToC but make it collapsed by default. That would have some discoverability issues, but the UX pattern is fairly well established by wikipedia.


Not a problem for me, but the title colour is a little “brighter” on a phone in a dark room so I guess could be adjusted down a bit.

I also think the body text size could be bumped up a bit too (on desktop, looks okay on mobile), I’m sure we’ll get feedback on many things and can always iterate further.

Checking accessibility guidelines, WCAG has no minimum but this suggests 16px and no smaller than 12px. WCAG requires text to be zoomable to 200% so I think we’re okay there.

Interesting, Wikipedia on desktop shows the ToC for me on desktop, and it’s completely removed for mobile!


You’re quite right, I must be remembering an old design or another site entirely. Regardless, what I proposed is an option for a design pattern (though perhaps a weaker argument, now)



Yeah, it certainly is; I just didn’t think about suggesting changing it (which I should have).

On my machine (Win + FF with DejaVu fonts installed) I get a fallback all the way to DejaVu Mono, which looks much too large to my eye. If I remove that, it falls back to Consolas (which is on Windows and maaaaybe Mac but is not FOSS and is not on Linux), which looks great and is the same size as the text, and if I remove that further, it falls back to what I assume is Courier which looks somewhat in between and doens’t fix 79 chars on one line.

To get a consistent experience across platforms, without such large swings in size or appearance, what I recommend is doing what we do on Spyder docs and using a webfont from e.g. Google Fonts; e.g. for monospace we use Inconsolata. All you need to do is stick this in the <head> of page.html:

    <link rel="stylesheet" href="">

And then refer to it like so in your font-family stack

pre, code {
  font-family: "Inconsolata", Consolas, monospace;

Then every user will get the same FOSS monospace font deployed and cached on the first page load, and everything will be consistent.

I personally think the size is okay as is so long as it meets WCAG and easily allows and fully supports scaling; I mostly suggested it to help it match the monospace font size (which we have a better solution for). But I’m also okay with bumping it up a bit if others agree. The bigger issue for me is making the monospaced font match it, which the above will allow us to do.

I’d be okay with my compromise proposal above that achieves around a 7.5:1 contrast, between the 5:1 suggested by @EpicWink and the 10:1 currently, and right above the WCAG AAA minimum of 7:1.

Yeah, but we already broke with tradition by having it in a sticky sidebar, so retaining a duplicate copy that takes up a page or more of space above the abstract and the PEP itself doesn’t seem too worthwhile just for a bit more space to read long titles.

I’d be okay with this, though I still don’t really see a particularly compelling need. Discoverability isn’t a huge deal if we had an easily visible dropdown, and its in the sidebar anyway so it would only really matter for niche cases that really want to more easily read the full title at the top. But I don’t think it hurts too much to have it as a dropdown.

1 Like

About code font being larger than normal font, I think the issue is the normal font is renders smaller than “usual” fonts do. It’s using font-family: "Source Sans Pro", Arial, sans-serif.

If I remove Source Sans Pro from the list it uses the familiar Arial (same as here on Discourse), which appears larger than Source Sans Pro and much more in line with the code. This looks better to me.

There’s a strong argument to be made for using the so-called system font stack: no extra network requests, no “jump” in rendering as the font loads, more familiar, broad support, up-to-date. See:

1 Like

Hugo’s use of the phrase “system font stack” reminded me of where my inspiration for the monospace fonts came from – this post on StackExchange’s design subsystem. (more for historical interest than anything else)

I took Source Sans Mono from/for consistency with pythondotorg. Generally happy with using system fonts, I will prepare a PR a little later today.


This is an important concern – whilst on mobile and under media queries lines will wrap, on desktop especially a single line should fit at least 79-80 characters.


1 Like

TL;DR: I strongly suggest keeping the webfont, status quo for now with the sans body font and considering any site-wide change separately. Instead, you can set pre, code to use a similar webfont (i.e. Inconsolata, from the same source, Google Fonts, as the current sans font), and set its size accordingly to match.

The problem is, there’s no firm standard for how large a font should render at a given “point” or “pixel” size—especially for monospace fonts. In my experience with typography and UI, Helvetica (and Arial, its cheap clone) tends to be at the larger end of things (though fairly consistent with most sans fonts, which tends to be a good 10%+ larger than serif fonts at the same size—compare, e.g. Times/New/Roman vs. Helvectica/Arial). While it is somewhat different from Source Sans Pro, the latter is a webfont, which means it will get deployed consistently across all devices, and we can thus reasonably rely on it.

The monospace fonts that are currently used, however, are more variable, and a webfont is not used, thus users can (and are, based on the availability of the choices) likely to get any one of them depending on their OS and what they have installed; this will in turn greatly affect whether the monospace font looks out of proportion with the body font, and how many characters will fit on one line (79 or not):

  • Cascadia Mono (potentially future Windows, user-installed): 77 char; Larger than the body text, but a little slimmer horizontally than DejaVu
  • **Segoe UI Mono (newer Windows?): Unable to test; proprietary (AFAIK) and don’t have it on my machine
  • DejaVu Mono (some Linux, user-installed): 75 char; Looks much larger (H & V) than body font.
  • Consolas (most Windows): 85 (!)char; Close match to body font; substantially smaller (H & V) than DejaVu
  • Lucida Console (old Windows, maaaybe some Mac?): 76 char, similar vertical size to Consolas but similar horizontal size to many of the others, looks bigger than the body text overall
  • monospace (Likely fallback on most Macs, since no Mac-specific option is specified): On Windows this is Courier, but not sure if it resolves to the same on Mac

Each also has a quite different look, with some (Consolas) look better and more readable than others (Courier), and take up different amounts of vertical, horizontal and line spaceing. Further, I’m not sure any default Mac options are present at all. And there’s also Android, other Linux distros (that don’t have DejaVu), BSD and others to consider.

Instead of trying to find an unhappy compromise, test and balance many different OSes, versions and user configs or pick the lowest common denominator, I suggest simply using a web font to get consistent results on all platforms.

Source Sans Pro is the distinct font used on the rest of the Python website. Any change here should be coordinated with the rest of the site, so there isn’t an incohorent mix of fonts and styles used and the Python site has a cohesive look. Arial looks particularly alien compared to the old PEPs. I’d suggest deferring any such major change until after the initial implementation of the new build system, so as to avoid getting stuck bikeshedding over this.

While there’s definitely an argument to be made for using the system font stack on other sites, especially web apps and platforms, so as to feel cohesive with the system UI, there are some strong reasons not to in this specific case, and many of the cited reasons aren’t necessarily applicable here. Focusing on the three main points made by

Fast: No network request, no time to parse a font, no flash of an incorrect font.

The site already uses a webfont for the body text and I’ve never noticed any meaningful delay, and the cost is only really paid once, on first load.

Styles and Unicode: System fonts have lots of styles and broad language coverage, unlike many webfonts.

We’re already constrained to the limited styles (bold, italic, bold-itlatic) available in reST, and the PEP repo is in English; with only names and special-cases in other languages, with all the characters we’ve needed thus far covered by our existing fonts.

Familiarity: Web apps feel more native when they use system font faces.

The PEPs site isn’t a “web app”; the primary task of the body font is to display prose content, not UI (unlike many of the sites quoted as adopting it, e.g. GitHub). It should be familiar to those seeing other parts of the Python site and to the previous PEP pages, and present a unified cross-platform appearance per Python itself.

In addition, there are some pretty strong reasons why not to in this case:

  • As demonstrated above, there is no guarantee that the sans and mono fonts chosen will match, as they should here (not the case for most sites), nor that the mono font will be a certain line length, unlike with a webfont
  • The appearance of the site will look and behave substantially on different OSes, versions, users configs and even browsers (see the bugs reported there), requiring much more testing and potential for issues, versus a webfont looks and works the same on all
  • Because of the differences, we would have to pick an unhappy medium for font size, line height, etc. that would look okay on the average client but not so good on others
  • This would create an substantial inconsistancy between the look of the PEPs site and the rest of, unless we change everything, unlike using the existing webfont
1 Like

Very quickly (catching a train!) – I sympathise with the consistency argument, but e.g. the Python docs (which I assume get more hits than itself) use Arial & monospace

(from classic.css, L21-L28)

body {
    font-family: 'Lucida Grande', Arial, sans-serif;
    font-size: 100%;
    background-color: white;
    color: #000;
    margin: 0;
    padding: 0;

(from pydoctheme.css, L153-L156)

tt, code, pre {
    font-family: "monospace", monospace;
    font-size: 96.5%;

Will respond to the rest of the post later (post train!) – thanks for the detailed comments, by the way :slight_smile:


1 Like

That’s a good point. Still, though, at least up until now the PEPs have been much a part of the main Python website compared to the docs, which were its own thing and part of the language itslef. Furthermore, the docs were presumably designed before modern webfonts were widely supported and used, and as a legacy least common denominator, represent the worst of both worlds (openly decried by both webfont and system font stack camps alike; e.g. the system font stack site devotes considerable space to maligning Arial and Courier) aren’t something I think we should be constrained by, when that would be a step backward from either the status quo or the system font stack proposal (rather, they should presumably eventually be updated to either use webfonts or a system font stack approach, either being a major improvement over the existing status quo there—but I digress).

Safe travels, and enjoy your trip!

1 Like

I regret bringing up typography!

True, although a poor man’s proxy is matching x-heights – e.g. through Test page for estimating the relative x-height (aspect ratio) of a font, using JavaScript

From this list of python sites (including pythondotorg)

body text

  • Source Sans: www
  • Arial: bugs, buildbot, docs, packaging, speed, wiki
  • Segoe UI: devguide, mail
  • proxima-nova: status


  • Consolas: www, buildbot, devguide, mail, status
  • monospace: bugs, docs, packaging
  • Inconsolata: speed (doesn’t include the font as a stylesheet, so falls back to monspace)
  • Courier: wiki

system font stack (or similar)

  • devguide (through furo)
  • mail

The point here is that there is no real consistency – and the style is already a break from pythondotorg, so I don’t think we should be constrained by that – although it should be a consideration. At one point in this thread I argued that pythondotorg should probably be more of an advertising site for the project/language/charity, and should be purely focussed on hosting PEPs. This might lead to different typographic choices between the two sites. I also think now is the perfect time to switch the typefaces (if we choose to), as no-one is really used to the new design, and so there will be fewer complaints.

Not actually possible in reST without significant hacks :wink: (Docutils doesn’t allow nested markup, that’s on my to do list to look at)

The full list of characters used in the PEPs repo is below in a details block. I was surprised by how large the list was, to be honest. A large number are in PEP 672 (unicode security), PEP 536 (there’s a zalgo block on line 171), PEP 538 (coercing the C locale to UTF-8).

Characters in PEPs and verification script (click to expand)
from pathlib import Path

characters = set()
for path in Path(".").glob("pep-????.*"):

assert characters == frozenset({
    # ASCII / C0 Controls and Basic Latin
    "\t", "\n", "\f",
    " ", "!", '"', "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/",
    "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?",
    "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O",
    "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", "\\", "]", "^", "_",
    "`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o",
    "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~",
    # Latin-1 Punctuation and Symbols
    "\xa0", "¢", "§", "®",
    "°", "±", "µ", "½",
    "Å", "É",
    "×", "Ø", "ß",
    "à", "á", "ä", "å", "ç", "è", "é", "í", "ï",
    "ñ", "ó", "ö", "ø", "ú", "ü",
    # Latin Extended-A
    "č", "ğ", "Ł", "ň", "š", "ż",
    # Latin Extended-B
    "ƛ", "ƴ",
    # Spacing Modifier Letters
    # Combining Diacritical Marks
    "̀", "̂", "̃", "̄", "̆", "̇", "̉", "̊", "̍", "̏", "̒", "̓", "̔", "̗", "̘", "̙",
    "̛", "̜", "̝", "̞", "̟", "̡", "̣", "̤", "̦", "̧", "̨", "̩", "̪", "̫", "̬", "̭",
    "̮", "̯", "̲", "̴", "̷", "̹", "̺", "̻", "̼", "̽", "̾", "̿", "ͅ", "͆", "͇",
    "͈", "͉", "͍", "͎", "͏", "͐", "͑", "͒", "͓", "͔", "͗", "͙", "͚", "͜", "͠",
    "͡", "͢", "ͤ", "ͥ", "ͧ", "ͨ", "ͩ", "ͮ", "ͯ",
    # Greek and Coptic
    "Β", "ά", "α", "β", "γ", "ε", "ο", "π", "τ",
    # Cyrillic
    "В", "Д", "Н", "С", "а", "б", "в", "е", "и", "к", "л", "м", "н", "о", "р", "с",
    "т", "у", "ц", "я", "ѕ",
    # Hebrew
    "א", "ך", "ע", "ר",
    # Arabic
    "ة", "ق", "م", "ي", "٥",
    # N'Ko
    # Bengali
    # Oriya
    # Tamil
    # Latin Extended Additional
    "Ḛ", "Ṯ",
    # Greek Extended
    # General Punctuation
    "\u200b", "\u200f", "–", "—", "‘", "’", "“", "”", "…",
    # Superscripts and Subscripts
    # Letterlike Symbols
    "ℂ", "ℌ", "ℕ", "ℙ", "℮",
    # Arrows
    # Mathematical operators
    "∀", "∃", "∅", "⊗", "⋅",
    # Miscellaneous Technical
    "⌁", "⌚",
    # Enclosed Alphanumerics
    # Box Drawing
    "─", "└",
    # Miscellaneous Symbols
    "☂", "☃", "☺", "♨", "⚛",
    # Dingbats
    "✎", "✒", "✓",
    # Miscellaneous Mathematical Symbols B
    # Miscellaneous Symbols And Arrows
    # Katakana
    "ス", "パ", "ム",
    # CJK Unified Ideographs
    "十", "大", "学", "屆", "年", "日", "曜", "月", "槀", "櫰", "波", "激", "火", "筑", "粹", "羔", "鈩",
    # Alphabetic Presentation Forms
    # Halfwidth And Fullwidth Forms
    # Fullwidth Latin
    # Halfwidth And Fullwidth Forms
    # Specials
    # Mathematical Alphanumeric Symbols
    # Mathematical Alphanumeric Symbols
    # Miscellaneous Symbols And Pictographs

I agree. Equally though, macOS/OS X fundamentally look and feel different to Windows or Linux, and the cognative dissonance might be greater in an unfamiliar typeface than in different typefaces cross-platform.

I do have a personal preference for system fonts, partially due to the extra simplicitly of using built-in tools, extra familiarity, and not having to make a choice over font display. The reason I am hesitant though is that especially for PEPs, we should really make sure that a single line of literal/code display holds at least 80 characters, and I don’t know how we can guarantee that in the best way. (We could increase the margins of course, but there will always be someone with a really esoteric setup.)

I appreciate this is a lot of fence sitting! I’ll wait a day or two to allow anyone who wants to to voice an opinion, but otherwise I’ll have a look and propose a concrete suggestion as a PR to the peps repo.


1 Like

A fair point. Could a moderator split the recent “style/typography” posts to a new thread?

A decision on the documentation, mainly.

That is more to tie up loose ends though, and isn’t a blocker to the PEP itself.

Thanks @encukou, very kind!


1 Like