0

I'm working on a feature to highlight search results on a page at runtime by wrapping text in <mark> tags. The site is using Vuetify JS so almost every element is a flex container, and (as expected) the whitespace gets collapsed between text nodes and elements in a flex container.

When I highlight part of a text node in a flex container, the spaces around the highlighted area disappear, and the element looks broken.

Example:

button {
  display: flex;
}
<button>Add to <mark>cart</mark> now</button>

<p>(Should say "Add to <mark>cart</mark> now")<p>

Is there any way to preserve the whitespace between the <mark> element and the text adjacent text nodes? Update: Since this is interacting with a Vuetify app, I'm hoping for some styles I can apply to the injected <mark> element, rather than the parent flex container.

I've tried adding pseudo-elements to the ::before/::after with content(' ') to no avail.

DMack
  • 871
  • 2
  • 9
  • 21
  • use `column-gap` – epascarello Sep 07 '22 at 22:43
  • 2
    *The site is using Vuetify JS so almost every element is a flex container* --> this is what you need to fix because making everything flexbox is wrong. Read this: https://dev.to/afif/never-make-your-text-container-a-flexbox-container-m9p – Temani Afif Sep 07 '22 at 23:02
  • 1
    Does this answer your question? [CSS flex box last space removed](https://stackoverflow.com/questions/39325039/css-flex-box-last-space-removed) – Mark Schultheiss Sep 07 '22 at 23:30
  • The answers about white-space: pre & pre-wrap are great to know, but unfortunately in this case with a 3rd-party framework like Vuetify, I can't blanket-add a white-space rule to any element with matching text without causing other problems. (Previously-unseen white space will get rendered at the start/end of the innerText, for instance). Is there anything I can do just to the `mark` element I'm injecting? – DMack Sep 07 '22 at 23:44
  • It's weird that a vue framework would have CSS opinions like putting display: flex on everything. I believe that button elements aren't allowed to have display flex. I've had to put a span/div in the button to apply the flex properties. But also, in general flex parents should have child elements and not just plain text. https://stackoverflow.com/questions/35464067/flex-grid-layouts-not-working-on-button-or-fieldset-elements – sheriffderek Sep 13 '22 at 03:25
  • It's handy for aligning icons on your buttons, but the framework should wrap your label text in a span or something, agreed. I think I'll end up just identifying the problematic spots and wrapping things in spans, rather than hacking on the framework's styles – DMack Sep 14 '22 at 04:23

3 Answers3

1

If you need to preserve the white space for visual purposes, then gap: 3px is a simple way to create space between items in a flex container.

Edit: updated answer based on @herrstrietzel's suggestion to use 0.2em instead of pixels, so the spacing scales with font size increase (Codepen demonstration in comments).

button {
  display: flex;
  gap: 0.2em;

}
<button>Add to <mark>cart</mark> now</button>

<p>(Should say "Add to <mark>cart</mark> now")<p>
  • That won't scale to the font size, however. If the button font size is 2rem then the 3px spacing will not be proportionate. – Adam Sep 07 '22 at 23:07
  • @hjalmardev: replace 3px with a relative unit like `0.2em` and it will work pretty well: [Codepen](https://codepen.io/herrstrietzel/pen/KKRzvqR). Another benefit of this approach it will only address flex elements (... that shouldn't use flex - as commented by Temani Afif) – herrstrietzel Sep 09 '22 at 15:29
  • 1
    @herrstrietzel I edited my answer to include your suggestion, and thank you for the Codepen demonstration too! –  Sep 13 '22 at 01:41
0

Wrap it in pre tags and style it to inherit the body font

Add white-space:pre to the button rule.

Edit: p tags work too.

button {
  display: flex;
  white-space: pre;  
}
<button>Add to <mark>cart</mark> now</button>

<p>(Should say "Add to <mark>cart</mark> now")
  <p>
Adam
  • 5,495
  • 2
  • 7
  • 24
-1

Use non-breaking space &nbsp; instead of the two regular whitespace characters around the <mark>...</mark> tags.

button {
  display: flex;
}
<button>Add to&nbsp;<mark>cart</mark>&nbsp;now</button>

<p>(Should say "Add to <mark>cart</mark> now")<p>
svin83
  • 239
  • 1
  • 4
  • 13