or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

borders.mdcolor-functions.mdindex.mdlayout-positioning.mdtypography-display.mdutilities.mdvariables-constants.md
tile.json

typography-display.mddocs/

Typography & Display

Font loading, text utilities, and accessibility helpers for consistent typography and visual presentation. These mixins handle font-face declarations, text truncation, accessibility improvements, and text overflow behavior.

Capabilities

Font Face Mixin

Generates @font-face declarations with support for multiple font formats and Rails Asset Pipeline integration.

/**
 * Generates @font-face declarations
 * @param $font-family - The font family name
 * @param $file-path - Path to font files (without extension)
 * @param $file-formats - List of font formats to include (optional, defaults to setting)
 * @param $asset-pipeline - Enable Rails Asset Pipeline support (optional, defaults to setting)
 * @content - Additional CSS properties for the @font-face rule
 * @requires _font-source-declaration function
 * @requires _fetch-bourbon-setting function
 */
@mixin font-face(
  $font-family,
  $file-path,
  $file-formats: _fetch-bourbon-setting("global-font-file-formats"),
  $asset-pipeline: _fetch-bourbon-setting("rails-asset-pipeline")
);

Usage Examples:

// Basic font-face with default formats
@include font-face(
  "source-sans-pro",
  "fonts/source-sans-pro-regular"
) {
  font-style: normal;
  font-weight: 400;
}
// Result:
// @font-face {
//   font-family: "source-sans-pro";
//   src: url("fonts/source-sans-pro-regular.woff2") format("woff2"),
//        url("fonts/source-sans-pro-regular.woff") format("woff");
//   font-style: normal;
//   font-weight: 400;
// }

// Custom font formats
@include font-face(
  "custom-font",
  "fonts/custom-font-bold",
  ("woff2", "woff", "ttf")
) {
  font-weight: 700;
  font-display: swap;
}

// With Rails Asset Pipeline
@include font-face(
  "app-font",
  "app-font-regular",
  ("woff2", "woff"),
  true
) {
  font-style: normal;
  font-weight: 400;
}

Ellipsis Mixin

Truncates text with ellipsis using CSS text-overflow property.

/**
 * Truncates text with ellipsis
 * @param $width - Maximum width before truncation (optional, defaults to 100%)
 * @param $display - Display property value (optional, defaults to inline-block)
 */
@mixin ellipsis($width: 100%, $display: inline-block);

Usage Examples:

// Basic ellipsis
.title {
  @include ellipsis;
  // Result:
  // display: inline-block;
  // max-width: 100%;
  // overflow: hidden;
  // text-overflow: ellipsis;
  // white-space: nowrap;
}

// Custom width and display
.truncated-label {
  @include ellipsis(200px, block);
  // Result:
  // display: block;
  // max-width: 200px;
  // overflow: hidden;
  // text-overflow: ellipsis;
  // white-space: nowrap;
}

// Responsive ellipsis
.card-title {
  @include ellipsis(calc(100% - 2rem), block);
}

Hide Text Mixin

Hides text in an element while preserving its box model, typically used for image replacement techniques.

/**
 * Hides text in element (for image replacement)
 * Uses text-indent method for better performance and accessibility
 */
@mixin hide-text;

Usage Examples:

// Logo replacement
.logo {
  @include hide-text;
  background-image: url('logo.png');
  @include size(150px, 50px);
  // Result:
  // overflow: hidden;
  // text-indent: 101%;
  // white-space: nowrap;
}

// Icon buttons with text labels
.icon-button {
  @include hide-text;
  background: url('icon.svg') no-repeat center;
  @include size(32px);
}

Hide Visually Mixin

Hides elements visually while preserving them for screen readers and accessibility tools.

/**
 * Hides element visually while preserving accessibility
 * @param $toggle - "hide" or "unhide" (optional, defaults to "hide")
 */
@mixin hide-visually($toggle: "hide");

Usage Examples:

// Hide for visual users, keep for screen readers
.sr-only {
  @include hide-visually;
  // Result:
  // border: 0;
  // clip: rect(0, 0, 0, 0);
  // height: 1px;
  // margin: -1px;
  // overflow: hidden;
  // padding: 0;
  // position: absolute;
  // white-space: nowrap;
  // width: 1px;
}

// Show element again
.sr-only-focusable:focus {
  @include hide-visually("unhide");
  // Result: Resets all properties to their default values
}

// Skip links pattern
.skip-link {
  @include hide-visually;
  
  &:focus {
    @include hide-visually("unhide");
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1000;
  }
}

Overflow Wrap Mixin

Sets overflow-wrap (word-wrap) with legacy browser support.

/**
 * Sets overflow-wrap with legacy word-wrap fallback
 * @param $wrap - CSS overflow-wrap value (optional, defaults to "break-word")
 */
@mixin overflow-wrap($wrap: break-word);

Usage Examples:

// Default break-word behavior
.long-content {
  @include overflow-wrap;
  // Result:
  // word-wrap: break-word;
  // overflow-wrap: break-word;
}

// Normal wrapping
.normal-text {
  @include overflow-wrap(normal);
  // Result:
  // word-wrap: normal;
  // overflow-wrap: normal;
}

// Anywhere wrapping (where supported)
.break-anywhere {
  @include overflow-wrap(anywhere);
  // Result:
  // word-wrap: anywhere;
  // overflow-wrap: anywhere;
}

Configuration

Typography mixins can be configured globally:

$bourbon: (
  "global-font-file-formats": ("woff2", "woff", "ttf"),
  "rails-asset-pipeline": true
);

Set configuration before importing Bourbon.

Font Format Support

The font-face mixin supports these font formats:

  • WOFF2: Modern, compressed format (recommended)
  • WOFF: Widely supported web font format
  • TTF: TrueType fonts (fallback)
  • EOT: Internet Explorer legacy support
  • SVG: Legacy mobile Safari support

Accessibility Considerations

Hide Visually Best Practices

// Good: Provides context for screen readers
.icon-only-button {
  @include hide-visually;
  
  &::after {
    content: "Close dialog";
    @include hide-visually("unhide");
    position: absolute;
    // Position off-screen but accessible
  }
}

// Better: Use proper ARIA attributes
// <button aria-label="Close dialog">×</button>

Font Loading Performance

// Optimize font loading with font-display
@include font-face("body-font", "fonts/body-regular") {
  font-display: swap; // Improves perceived performance
}

// Preload critical fonts in HTML
// <link rel="preload" href="fonts/body-regular.woff2" as="font" type="font/woff2" crossorigin>

Common Patterns

// Responsive typography with ellipsis
.responsive-title {
  @include ellipsis(100%, block);
  font-size: clamp(1.2rem, 4vw, 2rem);
}

// Accessible skip navigation
.skip-nav {
  @include hide-visually;
  
  &:focus {
    @include hide-visually("unhide");
    position: fixed;
    top: 0;
    left: 0;
    background: #000;
    color: #fff;
    padding: 1rem;
    z-index: 9999;
  }
}

// Icon replacement with fallback
.social-icon {
  @include hide-text;
  @include size(32px);
  background: url('icon.svg') no-repeat center;
  background-size: contain;
  
  // Fallback for when images don't load
  &::before {
    content: attr(data-label);
    @include hide-visually("unhide");
    font-size: 0.8rem;
  }
}