4

Suppose I have the following code:

(lambda (x) (+ x 1))

I'd like to display it as follows, without changing what actually gets copy-pasted:

(λ (x) (+ x 1))

The aim is to achieve an effect to Emacs' prettify-symbols-mode. This question shows how to hide some text and display something else instead, but display:none elements are not copied, at least in Firefox.

In other words, how can I display prettified source code listings, without breaking copy-paste? Bonus points for pure HTML+CSS.

The best that I could come up with is the following:

/* CSS */
.lambda:after {
    content:"λ";
}
<!-- HTML -->
(<span>
   <span style="position:absolute;left:-3000px;">lambda</span>
   <span class="lambda"></span>
 </span> x (+ x 1))

Is that the right approach?

Clément
  • 12,299
  • 15
  • 75
  • 115

3 Answers3

3

This works in Chrome and Firefox:

.hide {
  color: transparent;
  display: inline-block;
  width: 0;
}

.lambda:after {
  content:"λ";
}

JSFiddle

Leventix
  • 3,789
  • 1
  • 32
  • 41
  • Very nice! Experimenting with your example suggests that `position:absolute` works as well (instead of `display` + `width`). Do you have an opinion on what might be better? – Clément Mar 05 '16 at 21:16
  • With `position: absolute;` if you select it in Firefox, it covers out part of the visible text. Going with `width: 0` feels a bit better as you kind of want to squash the text to zero width. It's a bit of a hack either way, so whatever works :) – Leventix Mar 05 '16 at 21:32
3

Here's one option:

.lambda {
  font-size: 0;
}
.lambda:after {
  content: "λ";
  font-size: 16px;
  /* reset font */
}
(<span>
   <span class="lambda">lambda</span>
</span>x (+ x 1))
Paulie_D
  • 107,962
  • 13
  • 142
  • 161
  • Thanks! Is it a documented property that setting size to 0 will "hide" an element? Or will some browsers have a minimum size? – Clément Mar 05 '16 at 21:12
  • It's not hiding the element, just the text within it. I'm not aware of any specific issues with a minimum size except *possibly* some really old version of Android. – Paulie_D Mar 05 '16 at 21:15
1

The CSS content 3 draft proposes that content should apply to elements too. Then, if browsers decide to implement this behavior, you will be able to use

.lambda {
  content: "λ";
}
(<span>
  <span class="lambda">lambda</span>
</span>x (+ x 1))
Oriol
  • 274,082
  • 63
  • 437
  • 513
  • Indeed, that would be quite nice – Clément Mar 05 '16 at 21:48
  • Does the draft specify copy-paste behaviours, though? I can't see that in there. – Clément Mar 05 '16 at 22:15
  • @Clément No, but currently browsers only select DOM content. I think the CSS WG is considering adding some way to enable the selection of generated content in pseudo-elements, not sure how that will interact with `content` used on an element. – Oriol Mar 05 '16 at 22:58
  • 1
    Is this really true? Edge on Windows phone does select content on pseudo-elements. I don't know about Edge in Windows though. – Clément Mar 06 '16 at 00:31
  • @Clément My comment was based on [a quote](https://lists.w3.org/Archives/Public/www-style/2015Nov/0294.html) of Florian (invited expert of W3C): "*By default (as per the legacy behavior), generated content in pseudo elements is not searchable/copyable/selectable*". But true, on Edge you can select and copy generated content of pseudo-elements. This affects the other answers to your question too. – Oriol Mar 06 '16 at 00:46