bulma icon indicating copy to clipboard operation
bulma copied to clipboard

Bulma conflicts with Prism.js syntax highlighting plugin

Open robdcal opened this issue 7 years ago • 17 comments

This is about Bulma.

It is a conflict with a popular syntax highlighting plugin.

Overview of the problem

This is about the Bulma CSS framework. I'm using Bulma 0.6.2 My browser is Chrome. I am sure this issue is not a duplicate.

Description

Bulma uses the .number and .tag classes, but so does Prism.js (used for syntax highlighting). I understand that this isn't necessarily Bulma's problem - it could be Prism's - but this felt like a good place to start.

A couple of examples of code snippets after Prism has inject its classes:

HTML

<pre class=" language-html"><code class=" language-html">
<span class="token comment" spellcheck="true">&lt;!-- The drum 'keys' --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>keys<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">data-key</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>65<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>key<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>kbd</span><span class="token punctuation">&gt;</span></span>A<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>kbd</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>sound<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>clap<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">data-key</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>83<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>key<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>kbd</span><span class="token punctuation">&gt;</span></span>S<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>kbd</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>sound<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>hihat<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
...
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token comment" spellcheck="true">&lt;!-- The audio files --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>audio</span> <span class="token attr-name">data-key</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>65<span class="token punctuation">"</span></span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>sounds/clap.wav<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>audio</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>audio</span> <span class="token attr-name">data-key</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>83<span class="token punctuation">"</span></span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>sounds/hihat.wav<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>audio</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>audio</span> <span class="token attr-name">data-key</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>68<span class="token punctuation">"</span></span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>sounds/kick.wav<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>audio</span><span class="token punctuation">&gt;</span></span>
...
</code><p><code class=" language-html"></code></p></pre>

CSS

<pre class=" language-css"><code class=" language-css">
<span class="token selector"><span class="token class">.key</span> </span><span class="token punctuation">{</span>
<span class="token property">border</span><span class="token punctuation">:</span> <span class="token number">.4</span>rem solid black<span class="token punctuation">;</span>
<span class="token property">border-radius</span><span class="token punctuation">:</span> <span class="token number">.5</span>rem<span class="token punctuation">;</span>
<span class="token property">margin</span><span class="token punctuation">:</span> <span class="token number">1</span>rem<span class="token punctuation">;</span>
<span class="token property">font-size</span><span class="token punctuation">:</span> <span class="token number">1.5</span>rem<span class="token punctuation">;</span>
<span class="token property">padding</span><span class="token punctuation">:</span> <span class="token number">1</span>rem <span class="token number">.5</span>rem<span class="token punctuation">;</span>
<span class="token property">transition</span><span class="token punctuation">:</span> all <span class="token number">.07</span>s ease<span class="token punctuation">;</span>
<span class="token property">width</span><span class="token punctuation">:</span> <span class="token number">10</span>rem<span class="token punctuation">;</span>
<span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
<span class="token property">color</span><span class="token punctuation">:</span> white<span class="token punctuation">;</span>
<span class="token property">background</span><span class="token punctuation">:</span> <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">0</span>,<span class="token number">0</span>,<span class="token number">0</span>,<span class="token number">0.4</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token property">text-shadow</span><span class="token punctuation">:</span> <span class="token number">0</span> <span class="token number">0</span> <span class="token number">.5</span>rem black<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token selector"><span class="token class">.playing</span> </span><span class="token punctuation">{</span>
<span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">scale</span><span class="token punctuation">(</span><span class="token number">1.1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token property">border-color</span><span class="token punctuation">:</span> <span class="token hexcode">#ffc600</span><span class="token punctuation">;</span>
<span class="token property">box-shadow</span><span class="token punctuation">:</span> <span class="token number">0</span> <span class="token number">0</span> <span class="token number">1</span>rem <span class="token hexcode">#ffc600</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code><p><code class=" language-css"></code></p></pre>

The .tag and .number classes are affected, from what I can see.

Any short-term patch or long-term solutions in mind?

Steps to Reproduce

  1. Implement Bulma (include CSS)
  2. Implement Prism (include CSS and JS)
  3. Create a code block (i.e. <pre><code class="language-javascript">)

Expected behavior

Expect code to render properly - normal font sizes, etc.

Actual behavior

Pieces of the code where Prism adds 'tag' or 'number' classes conflict with the same classes provided by Bulma. The sizes, margins and more are impacted.

robdcal avatar Mar 07 '18 21:03 robdcal

Sorry - this was my first ever Issue raised on GitHub and it was a bit of a non-issue. I continued to look into it and Prism.js has a number of plugins of its own, one of which is designed to help with this specific issue!

http://prismjs.com/plugins/custom-class/

It allowed me to add a prefix to the classes it injects (i.e. prism-- to make prism--tag and prism--number). I then had to go into Prism's CSS and update the class references there. A minor hassle, but it's solved the problem for now!

While I'd be happy for this Issue to be deleted/closed, I'd still be interested to know if there are any other solutions to this.

robdcal avatar Mar 07 '18 22:03 robdcal

For anyone else having this issue, I believe you can solve the problem completely with a fairly small amount of CSS. You do have to put anything you want highlighted inside of an element with the content class, but it's probably a good idea to do that anyway.

.content .tag, .content .number {
  display: inline;
  padding: inherit;
  font-size: inherit;
  line-height: inherit;
  text-align: inherit;
  vertical-align: inherit;
  border-radius: inherit;
  font-weight: inherit;
  white-space: inherit;
  background: inherit;
  margin: inherit;
}

Is there a reason why Bulma doesn't 'reset' everything inside of .content elements? It could go a long way in avoiding conflicts like this.

For Prism specifically, you can also add the selector .token (like .token.number) to target the elements with greater specificity. Prism adds it to everything.

EDIT: Added margin: inherit after realizing it got messed up too.

Tattomoosa avatar Apr 18 '18 23:04 Tattomoosa

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Jan 21 '19 10:01 stale[bot]

Just had this problem as well. It's extremely annoying. Using very common CSS names in a library introduces a lot of problems.

awulkan avatar Jun 04 '19 19:06 awulkan

Also ran into this. I feel that Bulma should be dialing back here. Is there a general issue for scoping Bulma classes in a new major version of Bulma?

mlncn avatar Jun 06 '19 16:06 mlncn

Prism does allow the class names to be changed with a prefix,

Prism.plugins.customClass.prefix('prism-')

All you'll then need to do is add the prefix to the CSS of the theme you're using for Prism

VizuaaLOG avatar Jun 06 '19 21:06 VizuaaLOG

I believe it's worth "patching up" bulma to avoid this very specific conflict. The thing is, prism is most probably used in <code> and/or <pre>. From bulma's perspective, I don't see why those awkwardly global and generic selectors shouldn't exclude that, e.g. bulma could just define :not(code) .number {} or :not(pre) .number {} instead of just .number. I believe it would be a win-win situation without too much noise in bulma, and without losing or breaking anything in bulma projects.

loopmode avatar Nov 18 '20 12:11 loopmode

@Tattomoosa your workaround is great for most cases, but doesn't work in my case. I have no control over the order in which stylesheets are loaded, and bulma is loaded first, prism much later when a codeblock component is mounted.

Concretely, instead of the original issue: image

I end up with empty styles: image

🙂

loopmode avatar Nov 18 '20 12:11 loopmode

FYI my workaround goes like this: https://github.com/loopmode/bulma-prism

loopmode avatar Nov 18 '20 13:11 loopmode

Re-opening, as it is part of a more general namespacing challenge.

jgthms avatar Nov 18 '20 13:11 jgthms

Another workaround, based on https://jeremyabbott.dev/posts/setting-up-prism-with-bulma.html

import Prism from "prismjs";
import "prismjs/plugins/custom-class/prism-custom-class";
Prism.plugins.customClass.map({ number: "prism-number", tag: "prism-tag" });

loopmode avatar Nov 27 '20 08:11 loopmode

This one worked for me:

.token.number, .token.tag { all: inherit; }

a-bohush avatar May 07 '21 14:05 a-bohush

I take it from this thread that there is no way to prefix Bulma classes with a namespace of sorts. Is this correct? Not talking about workarounds above, but being able to use something like class="bulma-dropdown bulma-is-active". Thanks.

gh-andre avatar Feb 26 '22 18:02 gh-andre

@gh-andre Not directly with Bulma but you can run postcss with the plugin postcss-prefixer on the output CSS to add a prefix to every class and id.

Tattomoosa avatar Feb 27 '22 04:02 Tattomoosa

@Tattomoosa Thanks. It wouldn't help with JS source that may reference selectors in strings, though.

gh-andre avatar Feb 27 '22 13:02 gh-andre

@gh-andre Bulma doesn't have any JS source. Packages that use Bulma might, though.

Tattomoosa avatar Feb 27 '22 17:02 Tattomoosa

@Tattomoosa Good to know. I guess I'll exercise caution and stick with original selectors to avoid possible future problems in case I use any JS packages that do reference Bulma's selectors. Thanks for the insights. Much appreciated.

gh-andre avatar Feb 27 '22 18:02 gh-andre