CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-respond-js

Fast and lightweight polyfill for min/max-width CSS3 Media Queries for IE 6-8 and more

Pending
Overview
Eval results
Files

core-polyfill.mddocs/

Core Media Query Polyfill

The core respond.js polyfill enables CSS3 media queries in browsers that don't support them natively, particularly Internet Explorer 6-8. It works by parsing CSS files via AJAX, extracting media queries, and dynamically applying matching rules.

Capabilities

Global Respond Object

The main respond.js interface exposed on the window object.

/**
 * Main respond.js API object available globally
 */
interface Respond {
  /** 
   * Re-parse all stylesheets and update media query application
   * Useful when stylesheets are added dynamically to the page
   */
  update(): void;
  
  /** 
   * Get the pixel value of 1em for media query calculations
   * @returns Current pixel value of 1em
   */
  getEmValue(): number;
  
  /** 
   * Flag indicating if browser natively supports media queries
   * Set to true for browsers with native support (causes early exit)
   */
  mediaQueriesSupported: boolean;
  
  /** 
   * Internal AJAX function (exposed for testing)
   * @param url - URL to fetch
   * @param callback - Function called with response text
   */
  ajax(url: string, callback: (responseText: string) => void): void;
  
  /** 
   * Internal request queue (exposed for testing) 
   */
  queue: RequestItem[];
  
  /** 
   * Regular expressions used for CSS parsing 
   */
  regex: RespondRegex;
}

/**
 * Internal processing functions (exposed for testing)
 */
interface RespondInternals {
  /** 
   * Parse CSS text and extract media query rules
   * @param styles - CSS text content
   * @param href - Stylesheet URL for relative path resolution  
   * @param media - Media attribute from link element
   */
  translate(styles: string, href: string, media: string): void;
  
  /** 
   * Apply media query rules based on current viewport
   * @param fromResize - Whether called from resize event
   */
  applyMedia(fromResize?: boolean): void;
  
  /** 
   * Process request queue for CSS files
   * Recursively processes queued AJAX requests
   */
  makeRequests(): void;
  
  /** 
   * Scan and parse all stylesheets in the document
   * Main entry point for CSS processing
   */
  ripCSS(): void;
}

declare global {
  interface Window {
    respond: Respond;
  }
}

Update Method

Re-parses all stylesheets and updates media query application. Essential for single-page applications or when CSS is loaded dynamically.

/**
 * Re-parse all stylesheets and update media query application
 * Triggers a complete re-scan of all link elements and CSS parsing
 */
window.respond.update(): void;

Usage Example:

// After dynamically adding a stylesheet
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'responsive.css';
document.head.appendChild(link);

// Update respond.js to process the new stylesheet
window.respond.update();

Em Value Calculation

Returns the current pixel value of 1em for accurate media query calculations.

/**
 * Get the pixel value of 1em for media query calculations
 * Creates a temporary element to measure current em value
 * @returns Current pixel value of 1em
 */
window.respond.getEmValue(): number;

Usage Example:

// Get current em value in pixels
var emInPixels = window.respond.getEmValue();
console.log('1em = ' + emInPixels + 'px');

// Useful for JavaScript calculations that need to match CSS media queries
if (window.innerWidth >= (30 * emInPixels)) { // 30em breakpoint
  // Apply JavaScript behavior for larger screens
}

Media Query Support Detection

Flag indicating whether the browser natively supports CSS3 media queries.

/**
 * Flag indicating if browser natively supports media queries
 * Set to true for browsers with native support, causing respond.js to exit early
 */
window.respond.mediaQueriesSupported: boolean;

Usage Example:

if (window.respond.mediaQueriesSupported) {
  console.log('Browser has native media query support');
} else {
  console.log('Using respond.js polyfill');
}

// Conditional JavaScript behavior
if (!window.respond.mediaQueriesSupported) {
  // Add extra fallbacks for IE8 and below
  document.documentElement.className += ' no-mediaqueries';
}

CSS Processing Rules

Supported Media Query Features

Respond.js supports a focused subset of CSS3 media queries:

  • min-width queries with px or em units
  • max-width queries with px or em units
  • All media types (screen, print, projection, etc.)
  • Media attributes on link elements (when no internal queries exist)

CSS Parsing Behavior

// Supported patterns:
@media screen and (min-width: 480px) { /* styles */ }
@media print and (max-width: 600px) { /* styles */ }
@media (min-width: 30em) and (max-width: 60em) { /* styles */ }

// Link element media attributes:
<link rel="stylesheet" href="print.css" media="print" />
<link rel="stylesheet" href="mobile.css" media="screen and (max-width: 480px)" />

Limitations

  • @import stylesheets: Not parsed (must use <link> elements)
  • Inline <style> elements: Not processed (CSS must be in external files)
  • @font-face in media queries: Causes IE7/8 to hang (place outside queries)
  • Nested media queries: Not supported
  • Complex media features: Only min/max-width supported
  • File protocol: May not work on file:// URLs due to security restrictions
  • Redirected CSS: Fails silently if CSS returns non-200 status
  • UTF-8 BOM: Breaks functionality in IE7/8

Internal Architecture

CSS Processing Pipeline

  1. Stylesheet Discovery: Scans all <link rel="stylesheet"> elements
  2. AJAX Retrieval: Fetches CSS content via XMLHttpRequest
  3. Media Query Extraction: Uses regex to find @media blocks
  4. Rule Parsing: Extracts min/max-width values and media types
  5. Viewport Evaluation: Compares rules against current window dimensions
  6. Style Injection: Creates <style> elements for matching rules
  7. Resize Monitoring: Listens for window resize with 30ms throttling

Regular Expressions

interface RespondRegex {
  /** /@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi - Matches @media blocks */
  media: RegExp;
  
  /** /@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi - Matches @keyframes */
  keyframes: RegExp;
  
  /** /(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g - Matches CSS url() functions */
  urls: RegExp;
  
  /** /@media *([^\{]+)\{([\S\s]+?)$/ - Extracts media conditions and content */
  findStyles: RegExp;
  
  /** /(only\s+)?([a-zA-Z]+)\s?/ - Matches media type with optional "only" */
  only: RegExp;
  
  /** /\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/ - Matches min-width queries */
  minw: RegExp;
  
  /** /\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/ - Matches max-width queries */
  maxw: RegExp;
}

/** AJAX request queue item */
interface RequestItem {
  /** URL of CSS file to fetch */
  href: string;
  /** Media attribute from link element */
  media: string;
}

Install with Tessl CLI

npx tessl i tessl/npm-respond-js

docs

core-polyfill.md

cross-domain-proxy.md

index.md

matchmedia-listeners.md

matchmedia-polyfill.md

tile.json