The words Under construction in black text on a yellow background with diagonal black stipes surrounding it
I'm in the process of moving my site. It's still a work in progress. Please excuse the mess and broken links.

CSS Pre Tag Wrap And Overflow Examples

TODO: Pull subtitle into page object

- When I want wrapping:

`white-space: pre-wrap; overflow-wrap: break-word;``

- When I don't want wrapping:

`white-space: pre; overflow-x: auto; overscroll-behavior-x: none;``

Notes

Debugging Stuff

I'm moving stuff around right now. All this below is helping me figure out where to put stuff

        -- title

CSS Pre Tag Wrap And Overflow Examples

I built this page to get a better understanding
of how CSS properties affect `pre`` tags.
There is no css on the page other than
what you see listed on the page. 
Each line in the examples starts with a 
capitalized word followed by a collection of 
text and underscores designed to make it 
easier to see each effect. 

I'm using two different versions in production

-- olist

- When I want wrapping:

`white-space: pre-wrap; overflow-wrap: break-word;``

- When I don't want wrapping:

`white-space: pre; overflow-x: auto; overscroll-behavior-x: none;``


-- html 

<div id="demoArea"></div>

-- notes
-- title: Notes
-- class: pageNotes

- From what I can tell there's not a way to suppress breaking 
at hyphens without breaking strings at another place. Using
`line-breaks: anywhere;`` prevented breaking on the hyphens
but broke wherever the string touched the boundary. 

- The primary recommendations I found for dealing with hyphens
would be to wrap them in spans with nowrap or to change the
character to something else that doesn't wrap. (but that 
would effect copy/paste). So, the wrap seems like the 
best option if it's important enough to put in the
work to make that happen

- An interesting play would be to update a syntax highligher 
to apply the nowrap along with the rest of the formatting

- I'm not using `text-wrap`` in any of the examples as it'
still experimental

- There's also a 'word-break' property but it seems aimed
at Chinese/Japanese/Korean (CJK) text. I don't know
enough about that to include it here. 

-- script

const example = `


ALFA ____ ____ ____


BRAVO _______ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____


CHARLIE     white      space


DELTA       white                                                         space


ECHO __ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____
FOXTROT _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____
GOLF __ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____


HOTEL ____ greetthenewguestsandleavequicklyguesstheresultfromthefirstplace ____


INDIA ____ GreetTheNewGuestsAndLeaveQuicklyGuessTheResultFromTheFirstPlace ____


JULIETT ____ steerthe-shipnorthwardssayitslowbutmakeitaddsalttothe-hotdish ____

KILO stringalfabravo stringcharliedetlaechofoxtrotgolfhotelindiajuliett endtext

`


const config = [

  {
    name: `/* No Styles Applied */`,
    color: "maroon",
    details: [
      "This is the baseline with no CSS applied",
    ]
  },

  { 
    name: "white-space: pre",
    color: "purple",
    details: [
      "This is the default behavior (same as above with no CSS applied)",
      "Long lines extend outside the bounding box (BRAVO)",
      "Multiple consecutive white space characters are preserved (CHARLIE)",
      "Long strings extend outside the bounding box (HOTEL)",
      "Long strings do not break on hyphens (JULIETT)",
    ]
  },

  {
    name: "white-space: break-spaces",
    color: "olive",
    details: [
      "Long lines are broken at spaces",
      "Long lines are wrapped inside the bounding box (BRAVO)",
      "Multiple consecutive white space characters are preserved (CHARLIE)",
      "Long white space is preserved after a break (DELTA) - this is the main difference between 'break-spaces' and 'pre-wrap'",
      "Long strings extend outside the bounding box (HOTEL)",
      "Long strings break on hyphens (JULIETT)",
    ]
  },


  { 
    name: "white-space: normal",
    color: "brown",
    details: [
      "New lines in the source are ignored", 
      "Text is wrapped inside the bounding box",
      "Multiple consecutive white space characters are collapsed (CHARLIE)",
      "Long strings extend outside the bounding box (HOTEL)",
      "Long strings break on hyphens (JULIETT)",
    ]
  },

  { 
    name: "white-space: nowrap",
    color: "burlywood",
    details: [
      "New lines in source are ignored", 
      "A single line of text extends outside the bounding box",
      "Multiple consecutive white space characters are collapsed (CHARLIE)",
    ]
  },

  {
    name: "white-space: pre-line",
    color: "cadetblue",
    details: [
      "This is like 'pre-wrap' but white space is collapsed", 
      "Long lines are wrapped inside the bounding box (BRAVO)",
      "Multiple consecutive white space characters are collapsed (CHARLIE)",
      "Long white space is collapsed onto the same line (DELTA)",
      "Long strings extend outside the bounding box (HOTEL)",
      "Long strings break on hyphens (JULIETT)",
    ]
  },

  {
    name: "white-space: pre-wrap",
    color: "crimson",
    details: [
      "This is like 'pre-line' but white space is preserved", 
      "Long lines are wrapped inside the bounding box (BRAVO)",
      "Multiple consecutive white space characters are preserved (CHARLIE)",
      "Long white space is collapsed after breaking to a new line (DELTA) - this is the main difference between 'break-spaces' and 'pre-wrap'",
      "Long strings extend outside the bounding box (HOTEL)",
      "Long strings break on hyphens (JULIETT)",
    ]
  },


  {
    name: "white-space: pre-wrap, line-break: anywhere",
    color: "darkorchid",
    details: [
      "Same as 'pre-wrap' except words and strings break in the middle if they would break the bounding box (KILO)",
      "The 'line-break' property is listed as being designed for Chinese, Japanese, or Korean (CJK) texts"
    ]
  },

  {
    name: "white-space: pre-wrap, hyphens: auto",
    color: "darkcyan",
    details: [
      "Same as 'pre-wrap' except the browser inserts hyphens and breaks to new lines on them based on language specific hyphenation rules",
      "Compare (HOTEL) for an example",
    ]
  },

  {
    name: "white-space: pre-wrap, overflow-x: auto",
    color: "darkgoldenrod",
    details: [
      "Link 'pre-wrap' but long strings don't wrap",
      "Nothing is seem beyond the bounding box",
      "Strings longer than the bounding box introduce a horizontal scroll to see the initially non-visible content",
    ]
  },

  {
    name: "white-space: pre-wrap, overflow-x: auto, overscroll-behavior-x: none",
    color: "darkgoldenrod",
    details: [
      "Link 'white-space: pre-wrap, overflow-x: auto', but prevents scroll chaining",
      "Scroll chaining is when scrolling in one element reaching its boundary and the parent starts scrolling",
      "There is also a 'overscroll-behavior: contains'. The 'none' is listed as preventing scroll to refresh in browsers while 'contains' does not",
      "Testing the difference between 'none' and 'contains' is left as an exercise for the reader", 
      "I'm using the '-x' version which allows vertical scrolling in the parent", 
    ]
  },


  {
    name: "white-space: pre-wrap, overflow-x: auto, overscroll-behavior: none, height: 150px",
    color: "darkgoldenrod",
    details: [
      "Same as 'overscroll-behavior-x' but applies to both x and y as demonstrated by setting an explicit height", 
    ]
  },

  {
    name: "white-space: pre-wrap, overflow-wrap: break-word",
    color: "darkgreen",
    details: [
      "Overflow wrap is the primary name of the property. 'word-wrap' is alaised to it as well",
      "Same as 'pre-wrap' except the browser words are broken at the point they would otherwise break the bounding box",
      "Compare (HOTEL) for an example",
    ]
  },

  {
    name: "white-space: pre, overflow-x: auto, overscroll-behavior-x: none",
    color: "mediumvioletred",
    details: [
      "Basic 'pre' but contents scrolls instead of breaking the boundary",
      "Scrolling doesn't chain up once the edge of the bounding box is reached",
      "Look at the DELTA line in example 11 for the white space collapse difference"
    ]
  },

]

const addExamples = () => {
  const sa = []
  const a = []

  config.forEach((conf, confIndex) => {
    a.push(`<section class="exampleSection">`)
    const parts = conf.name.split(", ")
    sa.push(`#demo${confIndex} `)
    sa.push("{")
    parts.forEach((style, styleIndex) => {
      sa.push(`${style};`)
    })
    sa.push(`color: ${conf.color};`)
    sa.push("}")

    a.push(`<h2>${confIndex + 1}. ${conf.name}</h2>`)

    if (conf.details.length > 0) {
      a.push(`<h3 class="detailsHeading">Details</h3>`)
      a.push(`<ul class="detailsList">`)
      conf.details.forEach((detail) => {
        a.push(`<li>${detail}</li>`)
      })
      a.push("</ul>")
    }
    a.push(`<pre id="demo${confIndex}" class="preExample">${example}</pre>`)
    a.push(`</section>`)
  })
  demoArea.innerHTML = a.join("")

  const sheet = document.createElement("style")
  sheet.innerHTML = sa.join("\n");
  document.head.appendChild(sheet)
}


document.addEventListener("DOMContentLoaded", () => {
  addExamples()
})


-- css
-- show
-- id: basePageStyles
-- title: Base Page Styles

*,
*::before,
*::after {
  box-sizing: border-box;
}

* {
  margin: 0;
}

li {
 margin-top: 0.7rem;
}

#basePageStyles {
  padding: 1rem;
  border: 1px solid #333;
  border-radius: 0.3rem;
  margin-top: 3.2rem;
}

#pageWrapper {
  width: min(100% - 3rem, 60ch);
  margin-inline: auto;
}

.detailsHeading {
  margin-top: 0.7rem;
  padding-bottom: 0.7rem;
}

.exampleSection {
  padding: 1rem;
  border: 1px solid #333;
  border-radius: 0.3rem;
  margin-top: 3.2rem;
}

.pageNotes {
  padding: 1rem;
  border: 1px solid #333;
  border-radius: 0.3rem;
  margin-top: 3.2rem;
}

.preExample {
  width: 48ch;
  outline: 1px solid green;
  font-size: 0.55rem;
  margin-top: 1.6rem;
}

.titleHeadline {
  margin-top: 0.9rem;
  margin-bottom: 1.4rem;
}

/* Colors */

a {
  color: var(--main-clr-primary-base);
  text-decoration: none;
}

body {
  background-color: var(--main-clr-background-base);
  color: var(--main-clr-text);
  line-height: 1.5;
  font-family: var(--main-ff-base);
  font-size: var(--main-fs-step--1-base);
}

html {
  color-scheme: dark light;
}

.referencesSection {
  margin-top: 1.7rem;
}

-- ref
-- title: pre: The Preformatted Text element
-- subtitle: - MDN
-- url: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/pre

-- ref 
-- title: Prevent line breaking after explicit hyphens
-- url: https://github.com/w3c/csswg-drafts/issues/3434

-- ref 
-- title: CSS: hyphens
-- subtitle: - MDN
-- url: https://developer.mozilla.org/en-US/docs/Web/CSS/hyphens

-- ref 
-- title: CSS: line-break
-- subtitle: - MDN
-- url: https://developer.mozilla.org/en-US/docs/Web/CSS/line-break

-- ref
-- title: CSS: overflow
-- subtitle: - MDN
-- url: https://developer.mozilla.org/en-US/docs/Web/CSS/overflow

-- ref
-- title: CSS: overscroll-behavior
-- subtitle: - MDN
-- url: https://developer.mozilla.org/en-US/docs/Web/CSS/overscroll-behavior

-- ref
-- title: CSS: white-space
-- subtitle: - MDN
-- url: https://developer.mozilla.org/en-US/docs/Web/CSS/white-space


-- categories
-- CSS 
-- Examples

-- metadata
-- date: 2023-09-02 02:50:08
-- id: 2upxhczm
-- site: aws
-- type: css-experiment 
-- status: published