loading...
Cover image for Code block $ prefix

Code block $ prefix

glennmen profile image Glenn Carremans ・2 min read

I use the DigitalOcean community tutorials a lot for examples how to setup up different things in Linux (Nginx, MySQL, firewall, ...) and would also advice everyone to use them.

About 3 weeks ago I actually noticed something about their code blocks, some of them (containing terminal commands) started with $, nothing strange about that right?
Well actually it is because you can't copy it, it will only copy the code after the $ prefix. An example of this can be found here.

This caught my interest, I have never noticed this before and couldn't find any good examples how this was done. So I digged through the page source code and found the magical source code for this little piece of art.

It is actually a combination of some good old HTML combined with a little CSS magic. I will try to explain the different parts and at the end show a working JSFiddle example.

HTML
The HTML part is actually pretty simple. It is the normal code block syntax with an unordered list in it. This example shows a code block with multiple lines but of course if you only want a one-line code block you can do the same with only one list item (<li>).

<pre>
    <code>
        <ul class="prefixed">
            <li class="line">sudo apt-get update</li>
            <li class="line">sudo apt-get install apache2</li>
            <li class="line">sudo apache2ctl configtest</li>
        </ul>
    </code>
</pre>

CSS
I will split this part up into smaller sections.

This first part is only used to reduce the spacing between each list item. Nothing special about it.

pre .prefixed {
    white-space: normal;
    margin: 0;
}

Okay now we are getting to the first important part. list-style-type is used to remove the default list item style:

pre .line {
    list-style-type: none!important;
}

This last part is used to actually add the $ prefix in front of the code block. The first part is to make sure that a user can't copy it. The margins are used to add a little spacing around the prefix, of course can be adjusted how you like.
The most important part is content: "$";, this adds the prefix that we want to all the lines above.

pre .line::before {
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    -o-user-select: none;
    user-select: none;
    content: "$";
    margin-right: 10px;
    margin-left: 5px;
}

Bonus
I wanted to add this as a little bonus.
It is also possible to add different prefixes to each line without needing to make a different CSS style for each.
Add the prefix attribute, with any value that you like.

<li class="line" prefix="$">sudo apt-get install apache2</li>

In the last CSS block replace content: "$"; with this. It will get the attribute value and use that as the prefix instead.

content: attr(prefix);

This was my first time giving a coding tutorial so I hope you like it. Any feedback is of course welcome.

Posted on by:

glennmen profile

Glenn Carremans

@glennmen

Native Android developer/Consultant for Appwise, I work on custom projects for clients. PHP/JS (web) developer in my freetime. Trying to keep learning in an ever changing tech world.

Discussion

markdown guide
 

This is neat! I didn't realize you could pass things directly from HTML attributes to CSS using the attr() function. That seems like a really semantic way of handling cases like this.

Thanks!

 

It always makes me happy to be able to learn new things to other people😄

 

I came here to say the same thing! I didn't know that you could pass data around like that. This is awesome!

 

I have to admit I usually run away when CSS is being discussed,
but I thought I know most of it.

Well, content: attr(prefix); blew my mind.

 

Lol I am in the same boat as you on this 😂I am a "CSS newbie".
I also still learn a lot from CSS and it amazes me how much it changed compared to a few years ago. In "the old days" you where forced to use JS for a lot of animations but now you can do almost everything with only CSS.

 

Would it also be possible to say if you don't pass on a prefix in the html it shows default ($) and otherwise use the prefix? Seems a bonus on top the bonus to me!

 

Good question! I did a quick search and actually you can. developer.mozilla.org/en-US/docs/W...

attr() has an optional fallback, however this is still an experimental feature.

content: attr(prefix, "$");
 

And here i am looking at the docs and missing the last part about the fallback.. Thanks for that! Doesn't seem to work in my version of chrome yet tho.

 

Nice write up Glenn - For me this brought up a follow-up Q for you that might make for another good post...

If it was possible, do you think people would prefer that single-line terminal commands copied from webpages don’t include the linebreak?

(IE. would it be better that the command doesn't run immediately when posted into your terminal)

If so, how would you do it?

 

Interesting question, this might be a good #discuss topic.
I personally like to copy/paste without a linebreak, so I can always double check the command or edit/add things.

Your question "how would you do it?", do you mean as a dev that made the code block or as a user that copy/pasted the command?

 

Seems to work well on mobile too, nice find!