Breakout blades

Framework-agnostic utilities for breaking out images and figures beyond their container width.

Use the .breakout class to allow elements to extend beyond their parent container:

<div class="breakout">
  <img src="image.jpg" alt="Description" />
</div>

The breakout container has 10% inline padding and a max-width of calc(10% + 65ch + 10%). The breakout utilities support images, pictures, figures, canvas, audio, video, tables, pre, iframe, and other media elements. Tables inside .breakout are specifically enhanced for horizontal scrolling and full-bleed mobile display. This is automatically included when you import the stylesheet.

How it works
.breakout,
.breakout-all {
  /* Prepare the container for breakout elements */
  padding-inline: 10%;
  max-width: calc(10% + 65ch + 10%);

  /* Breakout direct children only */
  & > * {
    &:is(
      table,
      pre,
      figure, video, iframe, canvas,
      img, picture,
      /* Custom utility classes for other tags that need to be broken out */
      .breakout-item,
      .breakout-item-max
    ) {
      width: fit-content;
      min-width: 100%;
      max-width: 125%;
      margin-left: 50%;
      transform: translateX(-50%);
    }

    /* Respect img/picture min-width */
    &:is(img, picture) {
      min-width: auto;
    }

    /* Max out the width of the element */
    &.breakout-item-max {
      width: 125% !important; /* !important is for cases like figure.breakout-item-max @TODO */
    }
  }
}

.breakout-all > * {
  &:is(h2, h3, h4, h5, h6, hr):not([class]) {
    position: relative;

    &::before {
      content: "";
      display: block;
      position: absolute;
      background: gray;
      opacity: 12.5%;
    }
  }

  &:is(h2, h3, h4, h5, h6):not([class]) {
    &::before {
      width: 10em;
      right: 100%;
      margin-right: 0.8ch;
      height: 0.25em;
      top: 50%;
      transform: translateY(-50%);
      background: linear-gradient(to left, gray, transparent);
    }

    /* @TODO: add to tricks-wiki why `*` works here, but `&` fails */
    &:where(hr + *) {
      &::before {
        display: none !important;
      }
    }
  }
  &:is(hr) {
    height: 0.5rem;
    border: none;
    overflow: visible;

    &::before {
      width: 100vw;
      left: 50%;
      height: 100%;
      transform: translateX(-50%);
    }
  }
}