Height mismatch of highlighted line number in syntax highlighting

The yellow highlight color around the line number is smaller than the yellow highlight color around the code (see line 10):

Is this normal? How do I get both parts to appear to be the same, even, horizontal bar?

I narrowed it down to Bootstrap 5. If I omit its .css file, the code part of the highlighted line becomes shorter and matches the height of the highlighted line number.

Is this website public ? Then I can inspect and see the styles.

@Sid It can be seen here:

Scroll to the bottom.

I found something different.


If I disable the display: flex, the issue seems to be solved.

This is not a proper solution to your problem. But I think it’s an interesting observation.

@Sid I now have a standalone repro:

<!doctype html>
<html>
<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
<style>
/* Background */ .bg { color: #c9d1d9; background-color: var(--bs-body-bg); }
/* PreWrapper */ .chroma { color: #c9d1d9; background-color: var(--bs-body-bg); }
/* Other */ .chroma .x {  }
/* Error */ .chroma .err { color: #f85149 }
/* CodeLine */ .chroma .cl {  }
/* LineLink */ .chroma .lnlinks { outline: none; text-decoration: none; color: inherit }
/* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; }
/* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; }
/* LineHighlight */ .chroma .hl { background-color: #ffffcc }
/* LineNumbersTable */ .chroma .lnt { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #64686c }
/* LineNumbers */ .chroma .ln { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #6e7681 }
/* Line */ .chroma .line { display: flex; }
/* Keyword */ .chroma .k { color: #ff7b72 }
/* KeywordConstant */ .chroma .kc { color: #79c0ff }
/* KeywordDeclaration */ .chroma .kd { color: #ff7b72 }
/* KeywordNamespace */ .chroma .kn { color: #ff7b72 }
/* KeywordPseudo */ .chroma .kp { color: #79c0ff }
/* KeywordReserved */ .chroma .kr { color: #ff7b72 }
/* KeywordType */ .chroma .kt { color: #ff7b72 }
/* Name */ .chroma .n {  }
/* NameAttribute */ .chroma .na {  }
/* NameBuiltin */ .chroma .nb {  }
/* NameBuiltinPseudo */ .chroma .bp {  }
/* NameClass */ .chroma .nc { color: #f0883e; font-weight: bold }
/* NameConstant */ .chroma .no { color: #79c0ff; font-weight: bold }
/* NameDecorator */ .chroma .nd { color: #d2a8ff; font-weight: bold }
/* NameEntity */ .chroma .ni { color: #ffa657 }
/* NameException */ .chroma .ne { color: #f0883e; font-weight: bold }
/* NameFunction */ .chroma .nf { color: #d2a8ff; font-weight: bold }
/* NameFunctionMagic */ .chroma .fm {  }
/* NameLabel */ .chroma .nl { color: #79c0ff; font-weight: bold }
/* NameNamespace */ .chroma .nn { color: #ff7b72 }
/* NameOther */ .chroma .nx {  }
/* NameProperty */ .chroma .py { color: #79c0ff }
/* NameTag */ .chroma .nt { color: #7ee787 }
/* NameVariable */ .chroma .nv { color: #79c0ff }
/* NameVariableClass */ .chroma .vc {  }
/* NameVariableGlobal */ .chroma .vg {  }
/* NameVariableInstance */ .chroma .vi {  }
/* NameVariableMagic */ .chroma .vm {  }
/* Literal */ .chroma .l { color: #a5d6ff }
/* LiteralDate */ .chroma .ld { color: #79c0ff }
/* LiteralString */ .chroma .s { color: #a5d6ff }
/* LiteralStringAffix */ .chroma .sa { color: #79c0ff }
/* LiteralStringBacktick */ .chroma .sb { color: #a5d6ff }
/* LiteralStringChar */ .chroma .sc { color: #a5d6ff }
/* LiteralStringDelimiter */ .chroma .dl { color: #79c0ff }
/* LiteralStringDoc */ .chroma .sd { color: #a5d6ff }
/* LiteralStringDouble */ .chroma .s2 { color: #a5d6ff }
/* LiteralStringEscape */ .chroma .se { color: #79c0ff }
/* LiteralStringHeredoc */ .chroma .sh { color: #79c0ff }
/* LiteralStringInterpol */ .chroma .si { color: #a5d6ff }
/* LiteralStringOther */ .chroma .sx { color: #a5d6ff }
/* LiteralStringRegex */ .chroma .sr { color: #79c0ff }
/* LiteralStringSingle */ .chroma .s1 { color: #a5d6ff }
/* LiteralStringSymbol */ .chroma .ss { color: #a5d6ff }
/* LiteralNumber */ .chroma .m { color: #a5d6ff }
/* LiteralNumberBin */ .chroma .mb { color: #a5d6ff }
/* LiteralNumberFloat */ .chroma .mf { color: #a5d6ff }
/* LiteralNumberHex */ .chroma .mh { color: #a5d6ff }
/* LiteralNumberInteger */ .chroma .mi { color: #a5d6ff }
/* LiteralNumberIntegerLong */ .chroma .il { color: #a5d6ff }
/* LiteralNumberOct */ .chroma .mo { color: #a5d6ff }
/* Operator */ .chroma .o { color: #ff7b72; font-weight: bold }
/* OperatorWord */ .chroma .ow { color: #ff7b72; font-weight: bold }
/* Punctuation */ .chroma .p {  }
/* Comment */ .chroma .c { color: #8b949e; font-style: italic }
/* CommentHashbang */ .chroma .ch { color: #8b949e; font-style: italic }
/* CommentMultiline */ .chroma .cm { color: #8b949e; font-style: italic }
/* CommentSingle */ .chroma .c1 { color: #8b949e; font-style: italic }
/* CommentSpecial */ .chroma .cs { color: #8b949e; font-weight: bold; font-style: italic }
/* CommentPreproc */ .chroma .cp { color: #8b949e; font-weight: bold; font-style: italic }
/* CommentPreprocFile */ .chroma .cpf { color: #8b949e; font-weight: bold; font-style: italic }
/* Generic */ .chroma .g {  }
/* GenericDeleted */ .chroma .gd { color: #ffa198; background-color: #490202 }
/* GenericEmph */ .chroma .ge { font-style: italic }
/* GenericError */ .chroma .gr { color: #ffa198 }
/* GenericHeading */ .chroma .gh { color: #79c0ff; font-weight: bold }
/* GenericInserted */ .chroma .gi { color: #56d364; background-color: #0f5323 }
/* GenericOutput */ .chroma .go { color: #8b949e }
/* GenericPrompt */ .chroma .gp { color: #8b949e }
/* GenericStrong */ .chroma .gs { font-weight: bold }
/* GenericSubheading */ .chroma .gu { color: #79c0ff }
/* GenericTraceback */ .chroma .gt { color: #ff7b72 }
/* GenericUnderline */ .chroma .gl { text-decoration: underline }
/* TextWhitespace */ .chroma .w { color: #6e7681 }
</style>        
</head>
<body>
{{ $code := `float Q_rsqrt( float number )
{
    long i;
    float x2, y;
    const float threehalfs = 1.5F;

    x2 = number * 0.5F;
    y  = number;
    i  = * ( long * ) &y;
    i  = 0x5f3759df - ( i >> 1 );
    y  = * ( float * ) &i;
    y  = y * ( threehalfs - ( x2 * y * y ) );

    return y;
}` }}
{{ highlight $code "c" "linenos=true,hl_lines=10" }}
</body>
</html>

Comment out the <link> tag and the highlight height will be consistent.

@Sid Which display: flex do you mean? If I delete the one on the corresponding figure, I see the code and figure caption become left-aligned, but the highlight heights remain inconsistent for me.

Ah, I see what you mean. The .line elements have display:flex. I can also see the highlight height become consistent when disabling display:flex. However, the whole highlight line takes the narrower height, which looks wrong compared to the highlight examples on Syntax Highlighting |Hugo. Also, the highlight color doesn’t extend fully to the right, as Syntax Highlighting |Hugo shows. It looks like display:flex has to be set on the line number .hl.

I meant this one.

This workaround seems to work for now:

div.highlight > div.chroma > table.lntable .lnt,
div.highlight > div.chroma > table.lntable .hl {
    display: flex;
}

Still, it’s not good that highlighting doesn’t work with Bootstrap out of the box. Perhaps it’s a Chroma bug?

Thank you for your help, @Sid!

1 Like

It is not. Is it simply a Bootstrap styling conflict triggered by:

  • Displaying a number at the beginning of each line, AND
  • Rendering the highlighted code in an HTML table with two cells

See https://gohugo.io/functions/highlight/#options and the admonition regarding shorthand notation.

We would have changed the default value for markup.highlight.lineNumbersInTable to false, but this is a blocker:

https://bugzilla.mozilla.org/show_bug.cgi?id=1273836

Opened seven years ago.

1 Like

@jmooring The admonition you refer to in transform.Highlight | Hugo seems to be:

Instead of specifying both lineNos and lineNumbersInTable, you can use the following shorthand notation:

lineNos=inline
equivalent to lineNos=true and lineNumbersInTable=false
lineNos=table
equivalent to lineNos=true and lineNumbersInTable=true

I don’t follow how that’s related, other than lineNos=true creates the conditions for the styling conflict you described:

  • Displaying a number at the beginning of each line, AND
  • Rendering the highlighted code in an HTML table with two cells

Changing the default of lineNumbersInTable doesn’t change what happens when it’s true. In my example, I explicitly turn on line numbers.

I see that you’re aware of the styling issue, but I don’t see that you have a workaround or fix for it, other than disabling line numbers. Is that correct? Just want to confirm I understand what you were saying.

No.

Without Bootstrap, the height of the highlighted lines is consistent regardless of whether lineNumbersInTable is true or false.

image

With Bootstrap, the height of the of the highlighted lines is inconsistent when lineNumbersInTable is true.

image

Try it:

git clone --single-branch -b hugo-forum-topic-42304 https://github.com/jmooring/hugo-testing hugo-forum-topic-42304
cd hugo-forum-topic-42304
hugo server

Is that correct?

No.

I meant in the context of using Bootstrap and wanting line numbers. Not using Bootstrap isn’t an option for me (and for many, I imagine), as well as line numbers. In my opinion, Hugo should work flawlessly with Bootstrap (assuming Bootstrap doesn’t do anything unusual).

It looks to me from your screenshots that there’s no fix currently for this context, aside from what I posted above. I suggest putting that fix in the highlight documentation so others can know how to work around it. You’re free to use my code verbatim if you wish.

I think I see what you mean about lineNumbersInTable. linenos=inline is the same as lineNumbersInTable=false and lineNos=true, so a workaround is to use linenos=inline, although the line numbers then become part of the text selection.

That does render correctly, but it does have the selection downside. It would be useful to put the CSS fix in the documentation to have the option of both features working correctly.

When you use Bootstrap with lineNumbersInTable=false you get line numbers and the line height is consistent. The only downside is when people use Firefox with copy and paste (see Mozilla issue I referenced above).

That would be nice. And it should work with Bulma too. And with every other CSS library.

You can either find the conflict in the library and override it, or export and modify the Chroma CSS with:

hugo gen chromastyles --style foo

and set this in your site configuration:

[markup.highlight]
noClasses = false

Yep, that works too. But my point is that I, and I assume most users, would assume this would work out of the box, and more documentation could fix that expectation and save debugging time. I sense reluctance from you to do this for some reason, but that’s fine, I just wanted to suggest it as an improvement.

Feel free to submit a PR to the docs site.

2 Likes

Follow-up…

I am unable to reproduce this, either with Chrome or Firefox, either with or without Bootstrap.