For the highlighted code, you’ve made unhighlighted lines look more like comments than merely deemphasised lines. One alternative style that I’ve found effective in such situations is to reduce the opacity and partially desaturate:
But I have always found adding a yellow background to the line to be by far the most effective (that is, the most likely to be read and understood correctly without explanation), most likely combined with opacity reduction and/or desaturation. And yes, specifically yellow will normally yield the best results. (There may be cultural factors to weigh against this recommendation, but there’s also some actual colour science supporting it. I’d definitely avoid red and green for normal highlighting in western culture, though it’s great for removed and added lines in diffs—but do remember the colourblind and not make colour the only indication.)
Agreed on highlighting with a different background color. Unfortunately, it can be difficult to find a background color that is different-enough from the usual background while maintaining a high enough contrast with the text sitting on top of it. This is especially true if your syntax highlighting color palette covers all the hues you could use.
So here's another protip: Make the highlight pop with a brighter left-border, so your background color doesn't have to pop so much on its own and you have more wiggle room to maintain contrast. Something like what mdx-prism has in their readme image [1], though I don't like the specific blue-on-blue colors. This blog article [2] has an example in the middle with nicer colors.
Yes, don't disable link underlines within the code blocks, let the default be. It's not like there's a competing convention for underlining within code blocks.
It might also be worth having those links opening in new tabs as an option. Right now, at least on iOS, following a link and then going back leaves you at the top of the original page again, not where you were up to before you clicked the link.
In general, it's better for sites to not take away from the user the choice of opening a link in a new tab or not. When I follow a link on my iPhone, when I use the Back button, the page is still scrolled to where it was before, which is my typical experience in mobile Safari.
In general, I agree. But if the link is a surprise because the styling isn't obvious and it might easily be tapped while trying to scroll content on a small touchscreen and it breaks normal back button behaviour, I disagree in this specific instance. All of those things were true in iOS Safari on my iPhone at the time I wrote that comment.
I think for me biggest problem with code snippets is that I encounter them with mobile device. Lines are quite long, like who uses 80 character line limits these days, more like 160. This combined with reality that most websites don't allow mobile device to zoom out.
I wish I could read full lines of code instead of trying to scroll back and forth.
I hard wrap at <=80 columns, and enforce those standards in codebases and in CI. Prettier's default is 80, and I don't change it.
I have three huge monitors, but long lines just makes most of the right-hand side of an editor window wasted.
Text files (source) are documents, and documents are much taller than they are wide: portrait orientation, like letter or A4. My two side monitors and oriented in portrait mode for this reason, and their quadrants (also portrait) are where I put editors.
I made this comment not to show my age, but to overcome the loudness bias of trends. There are plenty of us out here who still do it the old way, because the new way isn't better.
Even 80 characters could be too long for some screens / font size. Long lines could be broken (like white-space: pre-wrap does), with an indicator that the line has been broken at the beginning of the continued lines. This is what Kate does and I think it is a good default, better than having to scroll horizontally.
I guess one could use prettier with different max line lengths on the same code, then hide irrelevant versions with a media query. Feels a bit overengineered TBH
Alternatively, on a mobile device, you could try to display the "desktop view" and put your phone in landscape mode.
That's... actually a brilliant idea, in my opinion. Overengineered? Idk, seems like something you'd have to implement once with like 100 lines of glue code for different libraries and then it could just work. And it could seriously benefit mobile viewers. Personally I read a lot of programming blogposts on my phone while commuting etc.
In mobile Safari, you can reduce the text size to 75% to fit more in the viewport but on the posted page, there's a max-width set that still makes horizontal scrolling necessary.
What you'd probably rather have is for the `<pre>` element's default styling of `white-space: pre` to be changed to `white-space: normal`, that would make the text wrap as it does in paragraphs and such. It's easy to tell when such wrapping is happening in the code block styling that includes line numbers.
I have the same problem. I've taken to reformatting code that I post on my blog to fit in something like 60 columns, with a modified code style that takes less horizontal space (using clang-format & prettier to do the work for me).
Could be interesting to explore using media queries to change the code layout itself, like setting indent levels and line break placements (in listing method parameters, for example). Maybe even variable/class/method name collapsing.
Certainly getting out of the scope of the orignal discussion here, but you would think people should be able to have their code layout and style to their own preference suited for their device. There are problems with that to overcome certainly, for e.g. referring to line numbers, but they seem fairly solveable.
But commenters here suggesting the 80 char limit, inherited from IBM punchcards and typewriters before that, for diplaying code on smart phones half a century later is a little hilarious to me.
Yes standards useful and workplaces can easily enforce their own internal ones for things like line length limits. But they are useless if they do not work for everyone who they apply to and especially not if they don't adapt to world around them. Cubit used to be a standard, too! But then we developed better ways to measure things than our inconsistently sized forearms.
Enter a line break if you need one. No need to force. We have high-res widescreen monitors now and it results in much more productive viewing. And editors can automatically wrap text if you need a narrower window.
I consider 80 a soft limit, and 128 (nice round number) a hard limit. I find that even 80 is seldom reached, since I tend to use sane identifier lengths and small indents. The longest lines in my code are usually comments.
I loath having 80 char limits. Nothing worse than you end up 3 characters over on a condition and need to try format it nicely across 2 lines. More often it’s less readable splitting it than just having it on 1 line.
If 80 char is a warning it’s ok. Because obviously if every line is super long that’s not readable either. Needs to be a balance.
I feel like it hinders readability. Sometimes the end of a line isn't that important and can mostly be inferred from the start of the line or only occasionally needs to be inspected, meanwhile being able to see more of the whole file on screen at once can be really beneficial.
My workplace has a C++ character limit of 80. A lot of people complain but I can have three code windows side-by-side plus a source tree so I think it's great.
to add to what you wrote, mobile web has this nasty bug with code sections with a horizontal scrolling bar inside a page that already has a horizontal scrolling bar. these two don't play well.
Possible bug? The `hover me` seems to be implying that hovering that text should highlight something in the code sample, but nothing is happening. I assume that's the goal anyway - mouse over sections of explaining-text to see the highlighted-code that's relevant. (both "highlight word" and "highlight lines" could be handy here. tbh I'd probably use "highlight lines" more often)
Ignoring that: this is pretty nice looking, both the explanation (clear and with good examples) and the component itself. Good work!
The best feature for me is that it works well without JavaScript. The document is still a document.
Except for collapsed code blocks. I would suggest collapsing them using JavaScript, so they are fully readable without. They are currently unavailable to someone who does not run JavaScript.
I'm curious why you avoided using mdx-prism in favor of re-implementing much of it yourself. If only because I just used it in my own project and spent time patching a minor Firefox-specific bug, and now I have FOMO because I like your implementation here :) Were your features impossible without huge changes?
I do like that you use the `line=1-3` syntax for highlighting instead of mdx-prism's `lang{1-3}`. Do you have any appetite for upstreaming that change?
Viewer attention is increasingly limited these days, so avoiding small mistakes which limit your audience is recommended.
Dark mode content such as TFA is practically unreadable outside in bright light. Your reader will need to remember to return to your page some other time when they can see it, but chances are they will not return.
And this is the power of MDX (and some great focus from the author of course). I’m having a hard time trying to understand why some people seem to dislike MDX, it is the holy grail of web authoring imho.
It's because "standard" Markdown and many other formats already support HTML. If these kind of components were vended as standard web components, they could work in existing Markdown files and workflows.
This exists! But with a slightly different set of libraries than the highlighter used by the post author: remark-shiki-twoslash[1]. Shiki tokenizes using the same language definitions as VSCode, Twoslash uses the same language service.