Hacker News new | past | comments | ask | show | jobs | submit login
I spent some time exploring how to improve the UX of code blocks on the web (ped.ro)
191 points by lovelydrop on May 7, 2021 | hide | past | favorite | 66 comments



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:

  -.sx5jq50 .highlight-line[data-highlighted="false"], .sx5jq50 .highlight-line[data-highlighted="false"] * {
  -  color: var(---fadedLines);
  -}
  +.sx5jq50 .highlight-line[data-highlighted="false"] {
  +  opacity: 0.5;
  +  filter: grayscale(0.6);
  +}
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.

[1]: https://github.com/j0lv3r4/mdx-prism

[2]: https://leerob.io/blog/mdx


This is pretty good! One thing I wasn't able to trigger (or understand) was the "hover me" part from the "Interact with the content" section.


There's not much to it. Ignore the "hover me" label, and just hover over the highlighted parts of the code. They change color on hover.


I wish the "Click a highlighted word to navigate to a different page" was just an <a> tag rather than a JavaScript onclick handler.


I agree, I like to see where I'm going


great idea! implemented, and updated the article. thank you.


It's also not easy to quickly identify it's a link, as the word highlight is the same as the previous examples.

Maybe adding an underlines or something to make it slightly different might help with that.


Right, or a small "outgoing link" symbol (usually a box with an arrow coming out the top-right corner) next to it.


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.


It's looks great.

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.


The new way is to make the lines as long as a human needs it to be, and use the computer to automatically wrap them when you need a narrower view.


The Linux kernel style guide expresses a different rationale.


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.


ideally, there should be one content and exclusively handled with styling.

maybe using some combination of pre tags and white-space pre-wrap


It may be possible to use `<wbr>` in a single representation, assuming the indentation is solvable.


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.


or possibly pre-wrap


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.


If two people look at the same webpage with different size monitors, they see different code.

Probably not the best solution.


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.


80 characters is a widely-agreed-upon standard, and standards with lots of buy-in are useful for a variety of reasons, regardless of origin.

Units of precisely 20 feet is also a standard, used mostly in countries that use SI. It doesn't diminish the value or utility of containerization.


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.


Character limits are obsolete.

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.


That's the point. The renderer doesn't word wrap


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.


Depends a lot on the language. I've also seen people write lines of code that don't fit on my 4k TV


I use 80 character limits, and suggest corrections to that effect during code reviews. I feel it helps readability.

Is it becoming a tend to have longer limits?


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.


I still use 80 character line limits. Thanks to a wide monitor, I can fit 4 windows side by side and still read them without eye strain.


thank you! mobile is my biggest issue as well.

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.


Agreed, soft wrap exists in editors and could be added here.


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.


<details> is a native HTML accordion


You can also add an open attribute to specify that you want the <details> element opened by default


Looks great! I'd add a Copy to Clipboard button somewhere, since that's such a common use case when showing code


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.


Does anyone know if there's a trick to avoid the trailing newline when double-clicking a line to copy/paste it elsewhere?

This always annoys me for single-line commands. I'd love a CSS solution but can only think of some ugly JS approaches.


I hate that too, and it seems to be a very common default behaviour of text selection. Even Vim does it when you copy a whole line.

It's one of those little UI annoyances that refuse to disappear. Just like blinking cursors in unfocused input fields & windows.


I think that’s because, if you follow selection of a full line by a backspace/delete/cut, you expect the new line to disappear.

Apart from undo state, you also want cut to be equivalent to copy; backspace.


It probably ties into the whole “line ending not newline” philosophy of requiring files to end with an EOL character.


I mean you can probably fix this with autohotkey.

Whether this is a good idea is a whole different matter.


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.

My team is also working on code sample editor and preview components, but as web components for this reason: https://polymerlabs.github.io/playground-elements/


Nice! Here is another collection of ideas on improving code blocks https://co-pilot.dev/docs-code-block


This is super well done & polished. Will try out for future blog posts.

Thank you!


thank you <3


Would be nice to see Intellisense-style hover tooltips on code-blocks someday (via referencing a `.d.ts` or `.ts` file).

There might be some minimalist way to get Monaco into read-only mode for it...


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.

1: https://www.npmjs.com/package/remark-shiki-twoslash


The date on this article is June 02, 2021

Other than that, a great write-up.


loool, ooops. fixed, thank you


Excellent work, although the "hover me" doesn't do anything in Firefox 88 on Linux.


or on FF 88 on Mac


Great job! Would be nice to see a docusaurus plugin for this.


TIL I like turquoise themes.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: