1

I am attempting to make a div that mimics how a digital readout might display text:

  • show any and all characters as what they are (whitespace)
  • wrap to the next line, but not care about word boundaries or the like, simply continue writing characters to the space
  • treat newlines as newlines

Essentially I want my div to act like a grid of text, where each character is given a space, and no consideration for how words are broken up when going to the next line.

Example:

h e l l o w
o r l d
b i i i i
g h i \n
t h e r e

Would be how the sentence:

hello world     biiiig hi
there

would display.

However, it seems that I am unable to get this behavior, and no combination of white-space, word-break, or overflow-wrap is working...

var par = document.createElement("p");
var text = document.createTextNode(
    "Width of box: " + document.getElementById("textBody").clientWidth + "px"
);
par.appendChild(text);
document.body.appendChild(par);
div {
    font-family: "Lucida Console", "Courier New", monospace;
    border: 1px solid;
    margin: 1px;
    padding: 0px;
    font-size: 1em;
    width: 9ex;
    
    
    white-space: pre-wrap;
    word-break: break-word;
    overflow-wrap: anywhere;
}
<div id="textBody">hello world     biiiig hi
there</div>

Issues with the above snippet:

  • "world" isn't broken up and wrapped
  • the large amount of spaces between "world" and "biiiig" isn't honored/wrapped to the next line

Bonus question: I am new to em/ex units, you might see that I have tried to equate 7ex with "7 characters wide", but that seems to be off by a few pixels/character. Any guidance on achieving a simple "n chars wide"?

Update:

Thanks to @wazz for the point to <pre>. This solved the issue of how whitespace is treated, and some more word breaking css gets me closer, but still seeing that the whitespace isn't being wrapped down to the next line:

pre {
      border: 1px solid;
      padding: 0px;
      margin: 5px;
      white-space: pre-wrap;
      white-space: -moz-pre-wrap;
      white-space: -pre-wrap;
      white-space: -o-pre-wrap;
      overflow-wrap: break-all;
      word-break: break-all;
      
      font-size: 1em;
      width: 55px;
}
<pre>hello world     biiiig hi
there</pre>
Snappawapa
  • 1,697
  • 3
  • 20
  • 42
  • 1
    Your result is nothing like your sample. I think you should narrow down the problem to one thing, like creating 1 box with one letter in it. Or is it not supposed to look like the grid in the sample? I can't tell now, based on what you have so far. P.S. you might need to resort to `pre` tags, which maintain spaces. – wazz Aug 28 '21 at 00:53
  • exactly, the code in the snippet is misbehaving. the table example is what I would like to see in the snippet, but in a div. Playing around with the `pre` tag now, good point. Still getting similar issues with that though – Snappawapa Aug 28 '21 at 01:25
  • I don't think you can get the result you describe without js. – wazz Aug 28 '21 at 01:28
  • 1
    For the "bonus" look into css's `ch`. I've only used it once or twice and forget the details now but it came in very handy. – wazz Aug 28 '21 at 01:30

1 Answers1

0

You need white-space: break-spaces

.readout {
  font-family: "Lucida Console", "Courier New", monospace;
  border: 1px solid;
  padding: 0 0 0 10px;
  margin: 5px;
  font-size: 1em;
  width: calc((1ch + 10px) * 7);  
  letter-spacing:10px;
  white-space: break-spaces;
  word-break: break-all;
}
<div class="readout">hello world     biiiig hi
there</div>
Alohci
  • 78,296
  • 16
  • 112
  • 156
  • Quick q, what relation does the `10px` used in the width and padding have to the `font-size`? what if I wanted to use `1em`? – Snappawapa Aug 28 '21 at 15:14
  • @Snappawapa The 10px in the width is to match the 10px of the letter-spacing. 1em is a poor choice because there's no simple relationship between the em-square size and the character advance width; it depends on the font metrics. 1ch is a better choice. – Alohci Aug 28 '21 at 16:05