Variable fonts guide - CSS: Cascading Style Sheets

Variable fonts guide
====================

**Variable fonts** are an evolution of the OpenType font specification that enables many different variations of a typeface to be incorporated into a single file, rather than having a separate font file for every width, weight, or style. They let you access all the variations contained in a given font file via CSS and a single `@font-face` reference. This article will give you all you need to know to get you started using variable fonts.

**Note:** To use variable fonts on your operating system, you need to make sure that it is up to date. For example, Linux OSes need the latest Linux Freetype version, and macOS prior to High Sierra (10.13) does not support variable fonts. If your operating system is not up to date, you will not be able to use variable fonts in web pages or the Firefox Developer Tools.

Variable Fonts: what they are, and how they differ
--------------------------------------------------

To better understand what's different about variable fonts, it is worth reviewing what non-variable ones are like and how they compare.

### Standard (or Static) fonts

In the past, a typeface would be produced as several individual fonts, and each font would represent one specific width/weight/style combination. So you would have separate files for 'Roboto Regular', 'Roboto Bold', and 'Roboto Bold Italic' — meaning that you could end up with 20 or 30 different font files to represent a complete typeface (it could be several times that for a large typeface that has different widths as well).

In such a scenario, to use a typeface for typical use on a site for body copy you would need at least four files: regular, italic, bold, and bold italic. If you wanted to add more weights, like a lighter one for captions or a heavier one for extra emphasis, that would mean several more files. This results in more HTTP requests, and more data being downloaded (usually around 20k or more per file).

### Variable fonts

With a variable font, all of those permutations can be contained in a single file. That file would be larger than a single font, but in most cases smaller or about the same size as the 4 you might load for body copy. The advantage in choosing the variable font is that you have access to the entire range of weights, widths, and styles available, rather than being constrained to only the few that you previously would have loaded separately.

This allows for common typographic techniques such as setting different size headings in different weights for better readability at each size or using a slightly narrower width for data-dense displays. For comparison, it is typical in a typographic system for a magazine to use 10–15 or more different weight and width combinations throughout the publication — giving a much wider range of styles than currently typical on the web (or indeed practical for performance reasons alone).

#### A note about font families, weights, and variants

You might notice that we have been talking about having a specific font file for every weight and style (i.e. bold and italic and bold italic), rather than relying upon the browser to synthesize them. The reason for this is that most typefaces have very specific designs for bolder weights and italics that often include completely different characters (lower-case 'a' and 'g's are often quite different in italics, for example). To most accurately reflect the typeface design and avoid differences between browsers and how they may or may not synthesize the different styles, it's more accurate to load the specific font files where needed when using a non-variable font.

You may also find that some variable fonts come split into two files: one for uprights and all their variations, and one containing the italic variations. This is sometimes done to reduce the overall file size in cases where the italics aren't needed or used. In all cases, it is still possible to link them with a common `font-family` name so you can call them using the same `font-family` and appropriate `font-style`.

Introducing the 'variation axis'
--------------------------------

The heart of the new variable fonts format is the concept of an **axis of variation** describing the allowable range of that particular aspect of the typeface design. So the 'weight axis' describes how light or how bold the letterforms can be; the 'width axis' describes how narrow or how wide they can be; the 'italic axis' describes if italic letterforms are present and can be turned on or off accordingly, etc. Note that an axis can be a range or a binary choice. Weight might range from 1–999, whereas italic might be 0 or 1 (off or on).

As defined in the specification, there are two kinds of axes: **registered** and **custom**:

* Registered axes are those that are most frequently encountered, and common enough that the authors of the specification felt it was worth standardizing. The five currently registered axes are weight, width, slant, italic, and optical size. The W3C has undertaken to map them to existing CSS attributes, and in one case introduced a new one, which you'll see below.
* Custom axes are limitless: the typeface designer can define and scope any axis they like and are just required to give it a four-letter **tag** to identify it within the font file format itself. You can use these four-letter tags in CSS to specify a point along that axis of variation, as will be shown in the code examples below.
### Registered axes and existing CSS attributes

In this section we'll demonstrate the five registered axes defined with examples and the corresponding CSS. Where possible, both the standard and lower-level syntax are included. The lower-level syntax (`font-variation-settings`) was the first mechanism implemented to test the early implementations of variable font support and is necessary to utilize new or custom axes beyond the five registered ones. However, the W3C's intent was for this syntax not to be used when other attributes are available. Therefore wherever possible, the appropriate property should be used, with the lower-level syntax of `font-variation-settings` only being used to set values or axes not available otherwise.

#### Notes

1. When using `font-variation-settings` it is important to note that axis names are case-sensitive. The registered axis names must be in lower case, and custom axes must be in upper case. For example:

```css
font-variation-settings:
  "wght" 375,
  "GRAD" 88;
```

`wght` (weight) is a registered axis, and `GRAD` (grade) is a custom one.
2. If you have set values using `font-variation-settings` and want to change one of those values, you must redeclare all of them (in the same way as when you set OpenType font features using `font-feature-settings`). You can work around this limitation by using CSS Custom Properties (CSS variables) for the individual values, and modifying the value of an individual custom property. Example code follows at the end of the guide.
### Weight

Weight (represented by the `wght` tag) defines the design axis of how thin or thick (light or heavy, in typical typographic terms) the strokes of the letterforms can be. For a long time in CSS there has existed the ability to specify this via the `font-weight` property, which takes numeric values ranging from 100 to 900 in increments of 100, and keywords like `normal` or `bold`, which are aliases for their corresponding numeric values (400 and 700 in this case). These are still applied when dealing with non-variable or variable fonts, but with variable ones, any number from 1 to 1000 is now valid.

It should be noted that at this point there is no way in the `@font-face` declaration to 'map' a specific point on the variation axis of a variable font to the keyword `bold` (or any other keyword). This can generally be resolved fairly easily, but does require an extra step in writing your CSS:

```css
font-weight: 375;

font-variation-settings: "wght" 375;
```

The following live example's CSS can be edited to allow you to play with font-weight values.

### Width

Width (represented by the `wdth` tag) defines the design axis of how narrow or wide (condensed or extended, in typographic terms) the letterforms can be. This is typically set in CSS using the `font-stretch` property, with values expressed as a percentage above or below 'normal' (100%), any number greater than 0 is technically valid—though it is far more likely that the range would fall closer to the 100% mark, such as 75%-125%. If a number value supplied is outside the range encoded in the font, the browser should render the font at the closest value allowed.

**Note:** The % symbol is not used when utilizing `font-variation-settings`.

```css
font-stretch: 115%;

font-variation-settings: "wdth" 115;
```

The following live example's CSS can be edited to allow you to play with font width values.

### Italic

The Italic (`ital`) axis can be set in the range `[0-1]`, where `0` specifies "not italic," `0.5` specifies "halfway italic," and `1` specifies "fully italic." Italic designs often include dramatically different letterforms from their upright counterparts, so in the transition from upright to italic, several glyph (or character) substitutions usually occur. Italic and oblique are often used somewhat interchangeably, but in truth are quite different. Oblique is defined in this context with the term `slant` (see the below section), and a typeface would typically have one or the other, but not both.

In CSS, both italic and oblique are applied to text using the `font-style` property. Also note the introduction of `font-synthesis: none;` — which will prevent browsers from accidentally applying the variation axis and a synthesized italic. This can be used to prevent faux-bolding as well.

```css
font-style: italic;

font-variation-settings: "ital" 1;

font-synthesis: none;
```

The following live example's CSS can be edited to allow you to play with font italics.

### Slant

Slant (represented by the `slnt` tag), or as it's often referred to, 'oblique' — is different from true italics in that it changes the angle of the letterforms but doesn't perform any kind of character substitution. It is also variable, in that it is expressed as a numeric range. This allows the font to be varied anywhere along that axis. The allowed range is generally 0 (upright) to 20 degrees — any number value along that range can be supplied, so the font can be slanted just a tiny bit. However, any value from -90 to 90 degrees is valid.

**Note:** The `deg` keyword is not used when utilizing `font-variation-settings`.

```css
font-style: oblique 14deg;

font-variation-settings: "slnt" 14;
```

The following live example's CSS can be edited to allow you to play with font slant/oblique values.

### Optical size

This is something new to digital fonts and CSS, but is a centuries-old technique in designing and creating metal type. Optical sizing refers to the practice of varying the overall stroke thickness of letterforms based on physical size. If the size was very small (such as an equivalent to 10 or 12px), the characters would have an overall thicker stroke, and perhaps other small modifications to ensure that it would reproduce and be readable at a physically smaller size. Conversely, when a much larger size was being used (like 48 or 60px), there might be much greater variation in thick and thin stroke weights, showing the typeface design more in line with the original intent.

While this was originally done to compensate for the ink and paper printing process (very thin lines at small sizes often didn't print, giving the letterforms a broken appearance), it translates well to digital displays when compensating for screen quality and physical size rendering.

Optical size values are generally intended to be automatically applied corresponding to `font-size`, but can also be manipulated using the lower-level `font-variation-settings` syntax.

There is a new attribute, `font-optical-sizing`, created to support variable fonts in CSS. When using `font-optical-sizing`, the only allowed values are `auto` or `none` — so this attribute only allows for turning optical sizing on or off. However when using `font-variation-settings: 'opsz' <num>`, you can supply a numeric value. In most cases you would want to match the `font-size` (the physical size the type is being rendered) with the `opsz` value (which is how optical sizing is intended to be applied when using `auto`). The option to provide a specific value is provided so that should it be necessary to override the default — for legibility, aesthetic, or some other reason — a specific value can be applied.

```css
font-optical-sizing: auto;

font-variation-settings: "opsz" 36;
```

The following live example's CSS can be edited to allow you to play with optical size values.

### Custom axes

Custom axes are just that: they can be any axis of design variation that the typeface designer imagines. There may be some that become fairly common — or even become registered — but only time will tell.

### Grade

Grade may become one of the more common custom axes as it has a known history in typeface design. The practice of designing different grades of a typeface was often done in reaction to intended use and printing technique. The term 'grade' refers to the relative weight or density of the typeface design, but differs from traditional 'weight' in that the physical space the text occupies does not change, so changing the text grade doesn't change the overall layout of the text or elements around it. This makes grade a useful axis of variation as it can be varied or animated without causing a reflow of the text itself.

```css
font-variation-settings: "GRAD" 88;
```

The following live example's CSS can be edited to allow you to play with font grade values.

### Using a variable font: @font-face changes

The syntax for loading variable fonts is very similar to any other web font, with a few notable differences, which are provided via upgrades to the traditional `@font-face` syntax now available in modern browsers.

The basic syntax is the same, but the font technology can be specified, and allowable ranges for descriptors like `font-weight` and `font-stretch` can be supplied, rather than named according to the font file being loaded.

#### Example for a standard upright (Roman) font

```css
@font-face {
  font-family: "MyVariableFontName";
  src: url("path/to/font/file/myvariablefont.woff2") format("woff2-variations");
  font-weight: 125 950;
  font-stretch: 75% 125%;
  font-style: normal;
}
```

#### Example for a font that includes both upright and italics

```css
@font-face {
  font-family: "MyVariableFontName";
  src: url("path/to/font/file/myvariablefont.woff2") format("woff2-variations");
  font-weight: 125 950;
  font-stretch: 75% 125%;
  font-style: oblique 0deg 20deg;
}
```

**Note:** there is no set specific value for the upper-end degree measurement in this case; they indicate that there is an axis so the browser can know to render upright or italic (remember that italics are only on or off)

#### Example for a font that contains only italics and no upright characters

```css
@font-face {
  font-family: "MyVariableFontName";
  src: url("path/to/font/file/myvariablefont.woff2") format("woff2-variations");
  font-weight: 125 950;
  font-stretch: 75% 125%;
  font-style: italic;
}
```

#### Example for a font that contains an oblique (slant) axis

```css
@font-face {
  font-family: "MyVariableFontName";
  src: url("path/to/font/file/myvariablefont.woff2") format("woff2-variations");
  font-weight: 125 950;
  font-stretch: 75% 125%;
  font-style: oblique 0deg 12deg;
}
```

**Note:** Not all browsers have implemented the full syntax for font format, so test carefully. All browsers that support variable fonts will still render them if you set the format to just the file format, rather than format-variations (i.e. `woff2` instead of `woff2-variations`), but it's best to use the proper syntax if possible.

**Note:** Supplying value ranges for `font-weight`, `font-stretch`, and `font-style` will keep the browser from attempting to render an axis outside that range if you are using the appropriate attribute (i.e. `font-weight` or `font-stretch`), but will not block you from supplying an invalid value via `font-variation-settings`, so use with care.

Working with older browsers
---------------------------

Variable font support can be checked with CSS Feature Queries (see `@supports`), so it's possible to use variable fonts in production and scope the CSS calling the variable fonts inside a feature query block.

```css
h1 {
  font-family: some-non-variable-font-family;
}

@supports (font-variation-settings: "wdth" 115) {
  h1 {
    font-family: some-variable-font-family;
  }
}
```

Sample pages
------------

The following example pages show two different ways to structure your CSS. The first uses the standard attributes wherever possible. The second example uses CSS Custom Properties to set values for a `font-variation-settings` string and shows how you can more easily update single variable values by overriding a single variable rather than rewriting the whole string. Note the hover effect on the `h2`, which only alters the grade axis custom property value.

Resources
---------

* W3C CSS Fonts Module 4 Specification (editor's draft)
* W3C GitHub issue queue
* Microsoft Open Type Variations introduction
* Microsoft OpenType Design-Variation Axis Tag Registry
* Wakamai Fondue (a site that will tell you what your font can do via a simple drag-and-drop inspection interface)
* Axis Praxis (the original variable fonts playground site)
* V-Fonts.com (a catalog of variable fonts and where to get them)
* Font Playground (another playground for variable fonts with some very unique approaches to user interface)


OpenType font features guide - CSS: Cascading Style Sheets

OpenType font features guide
============================

Font features or variants refer to different glyphs or character styles contained within an OpenType font. These include things like ligatures (special glyphs that combine characters like 'fi' or 'ffl'), kerning (adjustments to the spacing between specific letterform pairings), fractions, numeral styles, and several others. These are all referred to as OpenType Features, and are made available to use on the web via specific properties and low-level control properties — `font-feature-settings`. This article provides you with all you need to know about using OpenType font features in CSS.

Some fonts will have one or more of these features enabled by default (kerning and default ligatures are common examples), while others are left to the designer or developer to choose to enable in specific scenarios.

In addition to broad feature sets like ligatures or lining figures (numerals that line up evenly as opposed to 'oldstyle', which look more like lower-case letters), there are also very specific ones such as stylistic sets (which might include several specific variants of glyphs meant to be used together), alternates (which might be one or more variants of the letter 'a'), or even language-specific alterations for East Asian languages. In the latter case, these alterations are actually necessary to properly express the language, so they go beyond the more stylistic preference of most other OpenType features.

**Warning:** There are many CSS attributes defined to leverage font features, but unfortunately many are not fully implemented. They are all defined and shown here, but many will only work using the lower-level `font-feature-settings` property. It's possible to write CSS to work both ways but this can become cumbersome. The issue with using `font-feature-settings` for everything is that every time you want to change one of the individual features, you have to redefine the entire string (similar to manipulating variable fonts with `font-variation-settings`).

Discovering availability of features in fonts
---------------------------------------------

This is sometimes the trickiest thing to work out if you don't have any documentation that came with the fonts (many type designers and foundries will provide sample pages and CSS just for this very reason). But there are some sites that make it easier to figure out. You can visit wakamaifondue.com, drop your font file on the circle where instructed, and in a few moments you'll have a full report on all the capabilities and features of your font. Axis-praxis.org also offers a similar capability, with the ability to click on the features to turn them on or off in a given text block.

Why you would use them?
-----------------------

Given that these features take a bit of work to discover and use, it may seem a fair question to ask why one would bother to use them. The answer lies in the specific features that will make a site more useful, readable, and polished:

* **Ligatures** like 'ff' or 'fi' make letter spacing and reading more even and smooth.
* **Fractions** can make home improvement and recipe sites much easier to read and understand.
* **Numerals** within paragraphs of text set as 'oldstyle' sit more comfortably between lower-case letters, and likewise setting them as 'tabular numbers' will make them line up better when setting a list of costs in a table say. 'lining' figures on the other hand sit more uniformly on their own or in front of capitalized words.

While none of these features individually will render a site useless due to their absence, each of them in turn can make a site easier to use and more memorable for its attention to detail.

>
> OpenType features are like secret compartments in fonts. Unlock them and you'll find ways to make fonts look and behave differently in subtle and dramatic ways. Not all OpenType features are appropriate to use all of the time, but some features are critical for great typography. *-- Tim Brown, Head of Typography at Adobe*.
>
>
>

### Sometimes it's substance, not just style

There are some cases — like with `font-variant-east-asian` — that OpenType features are directly tied to using different forms of certain glyphs, which can impact meaning and readability. In cases such as these, it's more than just a nicety, but rather an integral part of the content itself.

The font features
-----------------

There are a number of different features to consider. They are grouped and explained here according to the main attributes and options covered in the W3C specifications.

**Note:** The examples below show the properties and some example combinations, along with the lower-level syntax equivalents. They may not match exactly due to browser implementation inconsistencies, but in many cases, the first example will match the second. The typefaces shown are Playfair Display, Source Serif Pro, IBM Plex Serif, Dancing Script, and Kokoro (all available and free to use, most are on Google Fonts and other services).

### Kerning

Associated CSS property: `font-kerning`

This refers to the spacing between specific glyph pairings. This is generally on by default (as recommended by the OpenType specification). It should be noted that if `letter-spacing` is also set on your text, that is applied after kerning.

### Alternates

Associated CSS property: `font-variant-alternates`

Fonts can supply a number of different alternatives for various glyphs, such as different styles of lower case 'a' or more or less elaborate swashes in a script typeface. This property can activate an entire set of alternates or just a specific one, depending on the values supplied. The example below is showing several different aspects of working with alternate characters. Fonts with alternate glyphs can make them available across the board or individually in separate stylistic sets, or even individual characters. In this example you can see two different typefaces, and the introduction of the `@font-feature-values` at-rule. This is used to define shortcuts or named options that can be defined per font family. This way you can create a named option that applies to only a single font, or one that is shared and can be applied more generally

In this case, `@stylistic(alternates)` will show all the alternate characters for either font). Applying this to just the word 'My' alters the way the 'M' renders, and applying `@styleset(alt-a)` only changes the lower case 'a'.

Try changing the line

```css
font-variant-alternates: styleset(alt-a);
```

to

```css
font-variant-alternates: styleset(alt-g);
```

and notice that the lower case 'a' reverts to its regular form and the lower case 'g's changes instead.

#### More about alternates

* https://www.w3.org/TR/css-fonts-4/#propdef-font-variant-alternates
* https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant-alternates
### Ligatures

Associated CSS property: `font-variant-ligatures`

Ligatures are glyphs that replace two or more separate glyphs in order to represent them more smoothly (from a spacing or aesthetic perspective). Some of the most common are letters like 'fi', 'fl', or 'ffl' — but there are many other possibilities. There are the most frequent ones (referred to as common ligatures), and there are also more specialized categories like 'discretionary ligatures', 'historical ligatures', and 'contextual alternates'. While these last ones are not technically ligatures, they are generally similar in that they replace specific combinations of letters when they appear together.

While more common in script typefaces, in the below example they are used to create arrows:

### Position

Associated CSS property: `font-variant-position`

Position variants are used to enable typographic superscript and subscript glyphs. These are designed to work with the surrounding text without altering the baseline or line spacing. This is especially useful with the `<sub>` or `<sup>` elements.

### Capitals

Associated CSS property: `font-variant-caps`

One of the more common use cases for OpenType features is proper small caps. These are capital letters sized to fit better amongst lower case letters and are generally used for acronyms and abbreviations.

### Numerals

Associated CSS property: `font-variant-numeric`

There are several different styles of numerals commonly included in fonts:

* 'Lining' figures are all the same height and on the same baseline.
* 'Oldstyle' figures are mixed height and designed to have the appearance of ascenders and descenders like other lower case letters. These are designed to be used inline with a copy so the numerals visually blend with the surrounding glyphs in a similar fashion to small caps.

There is also the notion of spacing. Proportional spacing is the normal setting, whereas tabular spacing lines up numerals evenly regardless of character width, making it more appropriate for lining up tables of numbers in financial tables.

There are two types of fractions supported through this property:

* Diagonal slashed fractions.
* Vertically stacked fractions.

Ordinals are also supported (such as '1st' or '3rd'), as is a slashed zero if present in the font.

#### Lining and old-style figures

#### Fractions, ordinals, and slashed zero

### East Asian

Associated CSS property: `font-variant-east-asian`

This allows access to various alternate forms of glyphs within a font. The example below shows a string of glyphs with only the OpenType set 'jis78' enabled. Uncheck the box below and you'll see more characters displayed.

**Note:** these glyphs were copied out of a font sample and are not intended as prose.

### Font variant shorthand

The `font-variant` property is the shorthand syntax for defining all of the above. Setting a value of `normal` resets all properties to their initial value. Setting a value of `none` sets `font-variant-ligatures` to none and all other properties to their initial value. (Meaning that if kerning is on by default, it will still be on even with a value of `none` being supplied here.)

Font feature settings
---------------------

`font-feature-settings` is the 'low level syntax' that allows explicit access to every named available OpenType feature. This gives a lot of control but has some disadvantages in how it impacts inheritance and — as mentioned above — if you wish to change one setting, you have to redeclare the entire string (unless you're using CSS custom properties to set the values). Because of this, it's best to use the standard properties shown above wherever possible.

There are a huge number of possible features. You can see examples of a number of them above, and there are several resources available for finding more of them.

The general syntax looks like this:

```css
.small-caps {
  font-feature-settings: "smcp", "c2sc";
}
```

According to the specification you can either supply just the 4-character feature code or supply a 1 following the code (for enabling that feature) or a 0 (zero) to disable it. This is helpful if you have a feature like ligatures enabled by default but you would like to turn them off like so:

```css
.no-ligatures {
  font-feature-settings:
    "liga" 0,
    "dlig" 0;
}
```

### More on font-feature-settings codes

* 'The Complete CSS Demo for OpenType Features' (can't vouch for the truth of the name, but it's pretty big)
* A list of OpenType features on Wikipedia
Using CSS feature detection for implementation
----------------------------------------------

Since not all properties are evenly implemented, it's good practice to set up your CSS using feature detection to utilize the correct properties, with `font-feature-settings` as the fallback.

For example, small caps can be set several ways, but if you want to ensure that no matter what the underlying capitalization is that you end up with everything in small caps, it requires 2 settings with `font-feature-settings` versus a single property value using `font-variant-caps`.

```css
.small-caps {
  font-feature-settings: "smcp", "c2sc";
}

@supports (font-variant-caps: all-small-caps) {
  .small-caps {
    font-feature-settings: normal;
    font-variant-caps: all-small-caps;
  }
}
```

See also
--------

### Demos of CSS OpenType features in CSS

* The Complete CSS Demo for OpenType Features
### Web font analysis tools

* Wakamai Fondue
* Axis Praxis
### W3C Specifications

* Font Feature Properties in CSS Fonts Module Level 3
* font-variant-alternatives in CSS Fonts Module Level 4
### Other resources

* Using OpenType features by Tim Brown, Head of Typography, Adobe
* Adobe's Syntax for OpenType features in CSS


The Web Open Font Format (WOFF) - CSS: Cascading Style Sheets

The Web Open Font Format (WOFF)
===============================

Baseline Widely available
-------------------------

This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2016.

* Learn more
* See full compatibility
* Report feedback
**WOFF** (the **Web Open Font Format**) is a web font format developed by Mozilla in concert with Type Supply, LettError, and other organizations. It uses a compressed version of the same table-based `sfnt` structure used by TrueType, OpenType, and Open Font Format, but adds metadata and private-use data structures, including predefined fields allowing foundries and vendors to provide license information if desired.

There are three main benefits to using WOFF:

1. The font data is compressed, so sites using WOFF will use less bandwidth and will load faster than if they used equivalent uncompressed TrueType or OpenType files.
2. Many font vendors that are unwilling to license their TrueType or OpenType format fonts for use on the web will license WOFF format fonts. This improves availability of fonts to site designers.
3. Both proprietary and free software browser vendors like the WOFF format, so it has the potential of becoming a truly universal, interoperable font format for the web, unlike other current font formats.

There are two versions of WOFF: WOFF and WOFF2. They mostly differ in regard to the compression algorithm used. In `@font-face` they are identified by the `'woff'` and `'woff2'` format descriptor respectively.

Using WOFF
----------

You can use the `@font-face` CSS property to use WOFF fonts for text in web content. It works exactly like OpenType and TrueType format fonts do, except it will likely let your content download more efficiently due to the addition of compression.

Tools for working with WOFF fonts
---------------------------------

* Tools for working with WOFF fonts are available. `sfnt2woff` and `woff2sfnt` convert between WOFF and OpenType.
Specifications
--------------

| Specification |
| --- |
| WOFF File Format 1.0 # OverallStructure |
| WOFF File Format 2.0 # FileStructure |

Browser compatibility
---------------------

### css.at-rules.font-face.WOFF

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

### css.at-rules.font-face.WOFF\_2

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `@font-face`


scroll() - CSS: Cascading Style Sheets

scroll()
========

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`scroll()`** CSS function can be used with `animation-timeline` to indicate a scrollable element (*scroller*) and scrollbar axis that will provide an anonymous scroll progress timeline for animating the current element. The scroll progress timeline is progressed through by scrolling the scroller between top and bottom (or left and right). The position in the scroll range is converted into a percentage of progress — 0% at the start and 100% at the end.

**Note:** If the indicated axis does not contain a scrollbar, then the animation timeline will be inactive (have zero progress).

**Note:** Each use of `scroll()` corresponds to its own unique instance of `ScrollTimeline` in the Web Animations API.

Syntax
------

```css
/\* Function with no parameters set \*/
animation-timeline: scroll();

/\* Values for selecting the scroller element \*/
animation-timeline: scroll(nearest); /\* Default \*/
animation-timeline: scroll(root);
animation-timeline: scroll(self);

/\* Values for selecting the axis \*/
animation-timeline: scroll(block); /\* Default \*/
animation-timeline: scroll(inline);
animation-timeline: scroll(y);
animation-timeline: scroll(x);

/\* Examples that specify scroller and axis \*/
animation-timeline: scroll(block nearest); /\* Default \*/
animation-timeline: scroll(inline root);
animation-timeline: scroll(x self);
```

### Parameters

scroller

The value for indicating the scroller element that will provide the scroll progress timeline can be any one of the following:

`nearest`

The nearest ancestor of the current element that has scrollbars on either axis. This is the default value.

`root`

The root element of the document.

`self`

The current element itself.

axis

The scrollbar axis value can be any one of the following:

`block`

The scrollbar on the block axis of the scroll container, which is the axis in the direction perpendicular to the flow of text within a line. For horizontal writing modes, such as standard English, this is the same as `y`, while for vertical writing modes, it is the same as `x`. This is the default value.

`inline`

The scrollbar on the inline axis of the scroll container, which is the axis in the direction parallel to the flow of text in a line. For horizontal writing modes, this is the same as `x`, while for vertical writing modes, this is the same as `y`.

`y`

The scrollbar on the vertical axis of the scroll container.

`x`

The scrollbar on the horizontal axis of the scroll container.

**Note:** The scroller and axis values can be specified in any order.

### Formal syntax
```

<scroll()> =
  scroll( [ <scroller> || <axis> ]? )

<scroller> =
  root     |
  nearest  |
  self

<axis> =
  block   |
  inline  |
  x       |
  y

```

Examples
--------

### Setting an anonymous scroll progress timeline

 In this example, the `#square` element is animated using an anonymous scroll progress timeline, which is applied to the element to be animated using the `scroll()` function.
 The timeline in this particular example is provided by the nearest parent element that has (any) scrollbar, from the scrollbar in the block direction.

#### HTML

The HTML for the example is shown below.

```html
<div id="container">
  <div id="square"></div>
  <div id="stretcher"></div>
</div>
```

#### CSS

 The CSS below defines a square that rotates in alternate directions according to the timeline provided by the `animation-timeline` property.
 In this case, the timeline is provided by `scroll(block nearest)`, which means that it will select the scrollbar in the block direction of the nearest ancestor element that has scrollbars; in this case the vertical scrollbar of the "container" element.

**Note:** `block` and `nearest` are actually the default parameter values, so we could have used just `scroll()`.

```css
#square {
  background-color: deeppink;
  width: 100px;
  height: 100px;
  margin-top: 100px;
  position: absolute;
  bottom: 0;

  animation-name: rotateAnimation;
  animation-duration: 1ms; /\* Firefox requires this to apply the animation \*/
  animation-direction: alternate;
  animation-timeline: scroll(block nearest);
}

@keyframes rotateAnimation {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
```

 The CSS for the container sets its height to 300px and we also set the container to create a vertical scrollbar if it overflows.
 The "stretcher" CSS sets the block height to 600px, which forces the container element to overflow.
 These two together ensure that the container has a vertical scrollbar, which allows it to be used as the source of the anonymous scroll progress timeline.

```css
#container {
  height: 300px;
  overflow-y: scroll;
  position: relative;
}

#stretcher {
  height: 600px;
}
```

#### Result

Scroll to see the square element being animated.

Specifications
--------------

| Specification |
| --- |
| Scroll-driven Animations # scroll-notation |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* CSS scroll-driven animations
* Using CSS animations
* `animation-timeline`


view() - CSS: Cascading Style Sheets

view()
======

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`view()`** CSS function can be used with `animation-timeline` to indicate a subject element that will provide an anonymous view progress timeline to animate. The view progress timeline is progressed through by a change in visibility of the subject element inside the nearest ancestor scroller. The visibility of the subject inside the scroller is tracked — by default, the timeline is at 0% when the subject is first visible at one edge of the scroller, and 100% when it reaches the opposite edge.

The function parameters can specify the scrollbar axis along which timeline progress will be tracked and an inset that adjusts the position of the box in which the subject is deemed to be visible.

**Note:** If the indicated axis does not contain a scrollbar, then the animation timeline will be inactive (have zero progress).

**Note:** Each use of `view()` corresponds to its own unique instance of `ViewTimeline` in the Web Animations API.

Syntax
------

```css
/\* Function with no parameters set \*/
animation-timeline: view();

/\* Values for selecting the axis \*/
animation-timeline: view(block); /\* Default \*/
animation-timeline: view(inline);
animation-timeline: view(y);
animation-timeline: view(x);

/\* Values for the inset \*/
animation-timeline: view(auto); /\* Default \*/
animation-timeline: view(20%);
animation-timeline: view(200px);
animation-timeline: view(20% 40%);
animation-timeline: view(20% 200px);
animation-timeline: view(100px 200px);
animation-timeline: view(auto 200px);

/\* Examples that specify axis and inset \*/
animation-timeline: view(block auto); /\* Default \*/
animation-timeline: view(inline 20%);
animation-timeline: view(x 200px auto);
```

### Parameters

axis

The scrollbar axis value can be any one of the following:

`block`

 The scrollbar on the block axis of the scroll container, which is the axis in the direction perpendicular to the flow of text within a line.
 For horizontal writing modes, such as standard English, this is the same as `y`, while for vertical writing modes, it is the same as `x`. This is the default value.

`inline`

 The scrollbar on the inline axis of the scroll container, which is the axis in the direction parallel to the flow of text in a line.
 For horizontal writing modes, this is the same as `x`, while for vertical writing modes, this is the same as `y`.

`y`

The scrollbar on the vertical axis of the scroll container.

`x`

The scrollbar on the horizontal axis of the scroll container.

inset

The inset value can be one or two values, which can be either `auto` or a `<length-percentage>`. It specifies an inset (positive) or outset (negative) adjustment of the scrollport. The inset is used to determine whether the element is in view which determines the length of the animation timeline. In other words, the animation lasts as long as the element is in the inset-adjusted view.

start

Inward offset from beginning of the scrollport.

end

Inward offset from end of the scrollport.

**Note:** The scroller and inset values can be specified in any order.

### Formal syntax
```

<view()> =
  view( [ <axis> || <'view-timeline-inset'> ]? )

<axis> =
  block   |
  inline  |
  x       |
  y

```

Examples
--------

### Setting an anonymous view progress timeline

An anonymous view progress timeline is set on an element with class `subject` using `animation-timeline: view()`. The result is that the `subject` element animates as it moves upwards through the document as it is scrolled.

#### HTML

The HTML for the example is shown below.

```html
<div class="content">
  <h1>Content</h1>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
    tempor incididunt ut labore et dolore magna aliqua. Risus quis varius quam
    quisque id. Et ligula ullamcorper malesuada proin libero nunc consequat
    interdum varius. Elit ullamcorper dignissim cras tincidunt lobortis feugiat
    vivamus at augue.
  </p>

  <p>
    Dolor sed viverra ipsum nunc aliquet. Sed sed risus pretium quam vulputate
    dignissim. Tortor aliquam nulla facilisi cras. A erat nam at lectus urna
    duis convallis convallis. Nibh ipsum consequat nisl vel pretium lectus.
    Sagittis aliquam malesuada bibendum arcu vitae elementum. Malesuada bibendum
    arcu vitae elementum curabitur vitae nunc sed velit.
  </p>

  <div class="subject-container">
    <div class="subject animation"></div>
  </div>

  <p>
    Adipiscing enim eu turpis egestas pretium aenean pharetra magna ac. Arcu
    cursus vitae congue mauris rhoncus aenean vel. Sit amet cursus sit amet
    dictum. Augue neque gravida in fermentum et. Gravida rutrum quisque non
    tellus orci ac auctor augue mauris. Risus quis varius quam quisque id diam
    vel quam elementum. Nibh praesent tristique magna sit amet purus gravida
    quis. Duis ultricies lacus sed turpis tincidunt id aliquet. In egestas erat
    imperdiet sed euismod nisi. Eget egestas purus viverra accumsan in nisl nisi
    scelerisque. Netus et malesuada fames ac.
  </p>
</div>
<div class="overlay top">inset start 50%</div>
<div class="overlay bottom">inset end 10%</div>
```

#### CSS

The `subject` element and `content` elements are minimally styled and the text content is given some basic font settings:

```css
.subject {
  width: 300px;
  height: 200px;
  background-color: deeppink;
}

.content {
  width: 75%;
  max-width: 800px;
  margin: 0 auto;
}

p {
  font-size: 1.5rem;
  line-height: 1.8;
}
```

To aid the understanding of the result, extra elements `subject-container`, `top`, and `bottom` have been used. The `subject-container` shows the bounds of the animation. And semi-transparent `top` and `bottom` overlays mark inset offsetted scrollport.

```css
.subject-container {
  border: 2px dashed black;
  width: 300px;
  margin: 0 auto;
}

.overlay {
  position: fixed;
  width: 100%;
  background-color: #f5deb3aa;
  display: flex;
  font-size: 1.2rem;
  font-weight: bold;
  color: red;
  justify-content: flex-end;
}

.top {
  top: 0;
  height: 244px;
  align-items: end;
}

.bottom {
  top: 432px;
  height: 48px;
}
```

In the following code, the `<div>` with the class of `subject` is also given a class of `animation`. The `grow` animation causes the `subject` element to grow or shrink. The `animation-timeline: view(block 55% 10%)` is set to declare that it will be animated as it progresses through the view progress timeline provided by its scrolling ancestor (in this case the document's root element).

While scrolling down, note how the inset value of `50% 10%` causes the animation to start at 10% from the bottom and finish at 50% from the top. As animation moves forward along the timeline the `subject` grows. Conversely, when scrolling up the animation proceeds in the reverse direction, starting at 50% from the top, moving backward through the animation, and ending at 10% from the bottom. So, as the animation happens backwards the `subject` shrinks.

An important point to remember is that the animation lasts as long as the `subject` element is in the view which has been set and to be offset using `50% 10%` inset values.

```css
.animation {
  animation-timeline: view(block 50% 10%);

  animation-name: grow;
  animation-fill-mode: both;
  animation-duration: 1ms; /\* Firefox requires this to apply the animation \*/
  animation-timing-function: linear;
}

@keyframes grow {
  from {
    transform: scaleX(0);
  }

  to {
    transform: scaleX(1);
  }
}
```

#### Result

Scroll to see the subject element being animated.

Specifications
--------------

| Specification |
| --- |
| Scroll-driven Animations # view-notation |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* CSS scroll-driven animations
* Using CSS animations
* `animation-timeline`


Introduction to using XPath in JavaScript - XPath

Introduction to using XPath in JavaScript
=========================================

This document describes the interface for using XPath in JavaScript. Mozilla implements a fair amount of the DOM 3 XPath, which means that XPath expressions can be run against both HTML and XML documents.

The main interface to using XPath is the evaluate function of the document object.

document.evaluate()
-------------------

This method evaluates XPath expressions against an XML based document (including HTML documents), and returns a `XPathResult` object, which can be a single node or a set of nodes. The existing documentation for this method is located at document.evaluate, but it is rather sparse for our needs at the moment; a more comprehensive examination will be given below.

```js
const xpathResult = document.evaluate(
  xpathExpression,
  contextNode,
  namespaceResolver,
  resultType,
  result,
);
```

### Parameters

The `evaluate()` method takes a total of five parameters:

* `xpathExpression`: A string containing the XPath expression to be evaluated.
* `contextNode`: A node in the document against which the `xpathExpression` should be evaluated, including any and all of its child nodes. The document node is the most commonly used.
* `namespaceResolver`: A function that will be passed any namespace prefixes contained within `xpathExpression` which returns a string representing the namespace URI associated with that prefix. This enables conversion between the prefixes used in the XPath expressions and the possibly different prefixes used in the document. The function can be either:
    + Created by using the `createNSResolver` method of a `XPathEvaluator` object. You should use this virtually all the time.
    + `null`, which can be used for HTML documents or when no namespace prefixes are used. Note that, if the `xpathExpression` contains a namespace prefix, this will result in a `DOMException` being thrown with the code `NAMESPACE_ERR`.
    + A custom user-defined function. See the Using a User Defined Namespace Resolver section in the appendix for details.
* `resultType`: A constant that specifies the desired result type to be returned as a result of the evaluation. The most commonly passed constant is `XPathResult.ANY_TYPE` which will return the results of the XPath expression as the most natural type. There is a section in the appendix which contains a full list of the available constants. They are explained below in the section "Specifying the Return Type."
* `result`: If an existing `XPathResult` object is specified, it will be reused to return the results. Specifying `null` will create a new `XPathResult` object.
### Return Value

Returns `xpathResult`, which is an `XPathResult` object of the type specified in the `resultType` parameter. The `XPathResult` Interface is defined here.

### Implementing a Default Namespace Resolver

We create a namespace resolver using the `createNSResolver` method of the document object.

```js
const nsResolver = document.createNSResolver(
  contextNode.ownerDocument === null
    ? contextNode.documentElement
    : contextNode.ownerDocument.documentElement,
);
```

Or alternatively by using the `createNSResolver` method of a `XPathEvaluator` object.

```js
const xpEvaluator = new XPathEvaluator();
const nsResolver = xpEvaluator.createNSResolver(
  contextNode.ownerDocument === null
    ? contextNode.documentElement
    : contextNode.ownerDocument.documentElement,
);
```

And then pass `document.evaluate`, the `nsResolver` variable as the `namespaceResolver` parameter.

Note: XPath defines QNames without a prefix to match only elements in the null namespace. There is no way in XPath to pick up the default namespace as applied to a regular element reference (e.g., `p[@id='_myid']` for `xmlns='http://www.w3.org/1999/xhtml'`). To match default elements in a non-null namespace, you either have to refer to a particular element using a form such as `['namespace-uri()='http://www.w3.org/1999/xhtml' and name()='p' and @id='_myid']` (this approach works well for dynamic XPath's where the namespaces might not be known) or use prefixed name tests, and create a namespace resolver mapping the prefix to the namespace. Read more on how to create a user-defined namespace resolver, if you wish to take the latter approach.

### Notes

Adapts any DOM node to resolve namespaces so that an XPath expression can be easily evaluated relative to the context of the node where it appeared within the document. This adapter works like the DOM Level 3 method `lookupNamespaceURI` on nodes in resolving the `namespaceURI` from a given prefix using the current information available in the node's hierarchy at the time `lookupNamespaceURI` is called. Also correctly resolves the implicit `xml` prefix.

### Specifying the Return Type

The returned variable `xpathResult` from `document.evaluate` can either be composed of individual nodes (simple types), or a collection of nodes (node-set types).

#### Simple Types

When the desired result type in `resultType` is specified as either:

* `NUMBER_TYPE` - a double
* `STRING_TYPE` - a string
* `BOOLEAN_TYPE` - a boolean

We obtain the returned value of the expression by accessing the following properties respectively of the `XPathResult` object.

* `numberValue`
* `stringValue`
* `booleanValue`

##### Example

The following uses the XPath expression `count(//p)` to obtain the number of `<p>` elements in an HTML document:

```js
const paragraphCount = document.evaluate(
  "count(//p)",
  document,
  null,
  XPathResult.ANY\_TYPE,
  null,
);

console.log(
  `This document contains ${paragraphCount.numberValue} paragraph elements.`,
);
```

Although JavaScript allows us to convert the number to a string for display, the XPath interface will not automatically convert the numerical result if the `stringValue` property is requested, so the following code will **not** work:

```js
const paragraphCount = document.evaluate(
  "count(//p)",
  document,
  null,
  XPathResult.ANY\_TYPE,
  null,
);

console.log(
  `This document contains ${paragraphCount.stringValue} paragraph elements.`,
);
```

Instead, it will return an exception with the code `NS_DOM_TYPE_ERROR`.

#### Node-Set Types

The `XPathResult` object allows node-sets to be returned in 3 principal different types:

* Iterators
* Snapshots
* First Nodes

##### Iterators

When the specified result type in the `resultType` parameter is either:

* `UNORDERED_NODE_ITERATOR_TYPE`
* `ORDERED_NODE_ITERATOR_TYPE`

The `XPathResult` object returned is a node-set of matched nodes which will behave as an iterator, allowing us to access the individual nodes contained by using the `iterateNext()` method of the `XPathResult`.

Once we have iterated over all of the individual matched nodes, `iterateNext()` will return `null`.

Note however, that if the document is mutated (the document tree is modified) between iterations that will invalidate the iteration and the `invalidIteratorState` property of `XPathResult` is set to `true`, and a `NS_ERROR_DOM_INVALID_STATE_ERR` exception is thrown.

```js
const iterator = document.evaluate(
  "//phoneNumber",
  documentNode,
  null,
  XPathResult.UNORDERED\_NODE\_ITERATOR\_TYPE,
  null,
);

try {
  let thisNode = iterator.iterateNext();

  while (thisNode) {
    console.log(thisNode.textContent);
    thisNode = iterator.iterateNext();
  }
} catch (e) {
  console.error(`Error: Document tree modified during iteration ${e}`);
}
```

##### Snapshots

When the specified result type in the `resultType` parameter is either:

* `UNORDERED_NODE_SNAPSHOT_TYPE`
* `ORDERED_NODE_SNAPSHOT_TYPE`

The `XPathResult` object returned is a static node-set of matched nodes, which allows us to access each node through the `snapshotItem(itemNumber)` method of the `XPathResult` object, where `itemNumber` is the index of the node to be retrieved. The total number of nodes contained can be accessed through the `snapshotLength` property.

Snapshots do not change with document mutations, so unlike the iterators, the snapshot does not become invalid, but it may not correspond to the current document, for example, the nodes may have been moved, it might contain nodes that no longer exist, or new nodes could have been added.

```js
const nodesSnapshot = document.evaluate(
  "//phoneNumber",
  documentNode,
  null,
  XPathResult.ORDERED\_NODE\_SNAPSHOT\_TYPE,
  null,
);

for (let i = 0; i < nodesSnapshot.snapshotLength; i++) {
  console.log(nodesSnapshot.snapshotItem(i).textContent);
}
```

##### First Node

When the specified result type in the `resultType` parameter is either:

* `ANY_UNORDERED_NODE_TYPE`
* `FIRST_ORDERED_NODE_TYPE`

The `XPathResult` object returned is only the first found node that matched the XPath expression. This can be accessed through the `singleNodeValue` property of the `XPathResult` object. This will be `null` if the node set is empty.

Note that, for the unordered subtype the single node returned might not be the first in document order, but for the ordered subtype you are guaranteed to get the first matched node in the document order.

```js
const firstPhoneNumber = document.evaluate(
  "//phoneNumber",
  documentNode,
  null,
  XPathResult.FIRST\_ORDERED\_NODE\_TYPE,
  null,
);

console.log(
  `The first phone number found is ${firstPhoneNumber.singleNodeValue.textContent}`,
);
```

#### The ANY\_TYPE Constant

When the result type in the `resultType` parameter is specified as `ANY_TYPE`, the `XPathResult` object returned, will be whatever type that naturally results from the evaluation of the expression.

It could be any of the simple types (`NUMBER_TYPE, STRING_TYPE, BOOLEAN_TYPE`), **but**, if the returned result type is a node-set then it will **only** be an `UNORDERED_NODE_ITERATOR_TYPE`.

To determine that type after evaluation, we use the `resultType` property of the `XPathResult` object. The constant values of this property are defined in the appendix.

Examples
--------

### Within an HTML Document

The following code is intended to be placed in any JavaScript fragment within or linked to the HTML document against which the XPath expression is to be evaluated.

To extract all the `<h2>` heading elements in an HTML document using XPath, the `xpathExpression` is '`//h2`'. Where, `//` is the Recursive Descent Operator that matches elements with the nodeName `h2` anywhere in the document tree. The full code for this is: link to introductory xpath doc

```js
const headings = document.evaluate(
  "//h2",
  document,
  null,
  XPathResult.ANY\_TYPE,
  null,
);
```

Notice that, since HTML does not have namespaces, we have passed `null` for the `namespaceResolver` parameter.

Since we wish to search over the entire document for the headings, we have used the document object itself as the `contextNode`.

The result of this expression is an `XPathResult` object. If we wish to know the type of result returned, we may evaluate the `resultType` property of the returned object. In this case, that will evaluate to `4`, an `UNORDERED_NODE_ITERATOR_TYPE`. This is the default return type when the result of the XPath expression is a node set. It provides access to a single node at a time and may not return nodes in a particular order. To access the returned nodes, we use the `iterateNext()` method of the returned object:

```js
let thisHeading = headings.iterateNext();

let alertText = "Level 2 headings in this document are:\n";

while (thisHeading) {
  alertText += `${thisHeading.textContent}\n`;
  thisHeading = headings.iterateNext();
}
```

Once we iterate to a node, we have access to all the standard DOM interfaces on that node. After iterating through all the `h2` elements returned from our expression, any further calls to `iterateNext()` will return `null`.

Appendix
--------

### Implementing a User Defined Namespace Resolver

This is an example for illustration only. This function will need to take namespace prefixes from the `xpathExpression` and return the URI that corresponds to that prefix. For example, the expression:
```

'//xhtml:td/mathml:math'
```

will select all MathML expressions that are the children of (X)HTML table data cell elements.

In order to associate the '`mathml:`' prefix with the namespace URI '`http://www.w3.org/1998/Math/MathML`' and '`xhtml:`' with the URI '`http://www.w3.org/1999/xhtml`' we provide a function:

```js
function nsResolver(prefix) {
  const ns = {
    xhtml: "http://www.w3.org/1999/xhtml",
    mathml: "http://www.w3.org/1998/Math/MathML",
  };
  return ns[prefix] || null;
}
```

Our call to `document.evaluate` would then look like:

```js
document.evaluate(
  "//xhtml:td/mathml:math",
  document,
  nsResolver,
  XPathResult.ANY\_TYPE,
  null,
);
```

### Implementing a default namespace for XML documents

As noted in the Implementing a Default Namespace Resolver previously, the default resolver does not handle the default namespace for XML documents. For example with this document:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <entry />
    <entry />
    <entry />
</feed>
```

`doc.evaluate('//entry', doc, nsResolver, XPathResult.ANY_TYPE, null)` will return an empty set, where `nsResolver` is the resolver returned by `createNSResolver`. Passing a `null` resolver doesn't work any better, either.

One possible workaround is to create a custom resolver that returns the correct default namespace (the Atom namespace in this case). Note that you still have to use some namespace prefix in your XPath expression, so that the resolver function will be able to change it to your required namespace. E.g.:

```js
function resolver() {
  return "http://www.w3.org/2005/Atom";
}
doc.evaluate("//myns:entry", doc, resolver, XPathResult.ANY\_TYPE, null);
```

Note that a more complex resolver will be required if the document uses multiple namespaces.

An approach which might work better (and allow namespaces not to be known ahead of time) is described in the next section.

### Using XPath functions to reference elements with a default namespace

Another approach to match default elements in a non-null namespace (and one which works well for dynamic XPath expressions where the namespaces might not be known), involves referring to a particular element using a form such as `[namespace-uri()='http://www.w3.org/1999/xhtml' and name()='p' and @id='_myid']`. This circumvents the problem of an XPath query not being able to detect the default namespace on a regularly labeled element.

### Getting specifically namespaced elements and attributes regardless of prefix

If one wishes to provide flexibility in namespaces (as they are intended) by not necessarily requiring a particular prefix to be used when finding a namespaced element or attribute, one must use special techniques.

While one can adapt the approach in the above section to test for namespaced elements regardless of the prefix chosen (using `local-name()` in combination with `namespace-uri()` instead of `name()`), a more challenging situation occurs, however, if one wishes to grab an element with a particular namespaced attribute in a predicate (given the absence of implementation-independent variables in XPath 1.0).

For example, one might try (incorrectly) to grab an element with a namespaced attribute as follows: `const xpathlink = someElements[local-name(@*)="href" and namespace-uri(@*)='http://www.w3.org/1999/xlink'];`

This could inadvertently grab some elements if one of its attributes existed that had a local name of "`href`", but it was a different attribute which had the targeted (XLink) namespace (instead of `@href`).

In order to accurately grab elements with the XLink `@href` attribute (without also being confined to predefined prefixes in a namespace resolver), one could obtain them as follows:

```js
const xpathEls =
  'someElements[@\*[local-name() = "href" and namespace-uri() = "http://www.w3.org/1999/xlink"]]'; // Grabs elements with any single attribute that has both the local name 'href' and the XLink namespace
const thislevel = xml.evaluate(xpathEls, xml, null, XPathResult.ANY\_TYPE, null);
let thisitemEl = thislevel.iterateNext();
```

#### XPathResult Defined Constants

| Result Type Defined Constant | Value | Description |
| --- | --- | --- |
| ANY\_TYPE | 0 | A result set containing whatever type naturally results from the evaluation of the expression. Note that if the result is a node-set then UNORDERED\_NODE\_ITERATOR\_TYPE is always the resulting type. |
| NUMBER\_TYPE | 1 | A result containing a single number. This is useful for example, in an XPath expression using the `count()` function. |
| STRING\_TYPE | 2 | A result containing a single string. |
| BOOLEAN\_TYPE | 3 | A result containing a single boolean value. This is useful for example, in an XPath expression using the `not()` function. |
| UNORDERED\_NODE\_ITERATOR\_TYPE | 4 | A result node-set containing all the nodes matching the expression. The nodes may not necessarily be in the same order that they appear in the document. |
| ORDERED\_NODE\_ITERATOR\_TYPE | 5 | A result node-set containing all the nodes matching the expression. The nodes in the result set are in the same order that they appear in the document. |
| UNORDERED\_NODE\_SNAPSHOT\_TYPE | 6 | A result node-set containing snapshots of all the nodes matching the expression. The nodes may not necessarily be in the same order that they appear in the document. |
| ORDERED\_NODE\_SNAPSHOT\_TYPE | 7 | A result node-set containing snapshots of all the nodes matching the expression. The nodes in the result set are in the same order that they appear in the document. |
| ANY\_UNORDERED\_NODE\_TYPE | 8 | A result node-set containing any single node that matches the expression. The node is not necessarily the first node in the document that matches the expression. |
| FIRST\_ORDERED\_NODE\_TYPE | 9 | A result node-set containing the first node in the document that matches the expression. |

See also
--------

* XPath
* XML Path Language from *What is XSLT?* by G. Ken Holman
Original Document Information
-----------------------------

* Based upon an original document by James Graham.
* Other Contributors: James Thompson.


Functions - XPath

Functions
=========

The following is an annotated list of core XPath functions and XSLT-specific additions to XPath, including a description, syntax, a list of arguments, result-type, source in the appropriate W3C Recommendation. For further information on using XPath/XSLT functions, please see the For Further Reading page.

* boolean()
* ceiling()
* choose()
* concat()
* contains()
* count()
* current() *XSLT-specific*
* document() *XSLT-specific*
* element-available()
* false()
* floor()
* format-number() *XSLT-specific*
* function-available()
* generate-id() *XSLT-specific*
* id()
* key() *XSLT-specific*
* lang()
* last()
* local-name()
* name()
* namespace-uri()
* normalize-space()
* not()
* number()
* position()
* round()
* starts-with()
* string()
* string-length()
* substring()
* substring-after()
* substring-before()
* sum()
* system-property() *XSLT-specific*
* translate()
* true()
* unparsed-entity-url() *XSLT-specific*


Axes - XPath

Axes
====

There are thirteen different axes in the XPath specification. An axis represents a relationship to the context node, and is used to locate nodes relative to that node on the tree.

For further information on using XPath expressions, please see the For Further Reading section at the end of Transforming XML with XSLT document. Also see the 'axes' section in the xpath spec.

`ancestor`

Indicates all the ancestors of the context node beginning with the parent node and traveling through to the root node.

`ancestor-or-self`

Indicates the context node and all of its ancestors, including the root node.

`attribute`

Indicates the attributes of the context node. Only elements have attributes. This axis can be abbreviated with the at sign (`@`).

`child`

Indicates the children of the context node. If an XPath expression does not specify an axis, this is understood by default. Since only the root node or element nodes have children, any other use will select nothing.

`descendant`

Indicates all the children of the context node, and all of their children, and so forth. Attribute and namespace nodes are **not** included - the `parent` of an `attribute` node is an element node, but `attribute` nodes are not the children of their parents.

`descendant-or-self`

Indicates the context node and all of its descendants. Attribute and namespace nodes are **not** included - the `parent` of an `attribute` node is an element node, but `attribute` nodes are not the children of their parents.

`following`

Indicates all the nodes that appear after the context node, except any `descendant`, `attribute`, and `namespace` nodes.

`following-sibling`

Indicates all the nodes that have the same parent as the context node and appear after the context node in the source document.

`namespace` *(not supported)*

Indicates all the nodes that are in scope for the context node. In this case, the context node must be an element node.

`parent`

Indicates the single node that is the parent of the context node. It can be abbreviated as two periods (`..`).

`preceding`

Indicates all the nodes that precede the context node in the document except any `ancestor`, `attribute` and `namespace` nodes.

`preceding-sibling`

Indicates all the nodes that have the same parent as the context node and appear before the context node in the source document.

`self`

Indicates the context node itself. It can be abbreviated as a single period (`.`).


Comparison of CSS Selectors and XPath - XPath

Comparison of CSS Selectors and XPath
=====================================

This article seeks to document the difference between CSS Selectors and XPath for web developers to be able to better choose the right tool for the right job.

| XPath feature | CSS equivalent |
| --- | --- |
| `ancestor`, `parent` or `preceding-sibling` axis | `:has()` selector
Experimental
 |
| `attribute` axis | Attribute selectors |
| `child` axis | Child combinator |
| `descendant` axis | Descendant combinator |
| `following-sibling` axis | Subsequent-sibling combinator or Next-sibling combinator |
| `self` axis | `:scope` or `:host` selector |


XPath snippets - XPath

XPath snippets
==============

This article provides some XPath code snippets — simple examples of how to a few simple **utility functions** based on standard interfaces from the DOM Level 3 XPath specification that expose XPath functionality to JavaScript code. The snippets are functions you can use in the real world in your own code.

### Node-specific evaluator function

The following custom utility function can be used to evaluate XPath expressions on given XML nodes. The first argument is a DOM node or Document object, while the second is a string defining an XPath expression.

#### Example: Defining a custom node-specific `evaluateXPath()` utility function

```js
// Evaluate an XPath expression aExpression against a given DOM node
// or Document object (aNode), returning the results as an array
// thanks wanderingstan at morethanwarm dot mail dot com for the
// initial work.
function evaluateXPath(aNode, aExpr) {
  const xpe = new XPathEvaluator();
  const nsResolver = xpe.createNSResolver(
    aNode.ownerDocument === null
      ? aNode.documentElement
      : aNode.ownerDocument.documentElement,
  );
  const result = xpe.evaluate(aExpr, aNode, nsResolver, 0, null);
  const found = [];
  let res;
  while ((res = result.iterateNext())) found.push(res);
  return found;
}
```

Note that `createNSResolver` should only be used if you are sure the namespace prefixes in the XPath expression match those in the document you want to query (and that no default namespace is being used (though see document.createNSResolver for a workaround)). Otherwise, you have to provide your own implementation of XPathNSResolver.

#### Sample usage

Assume we have the following XML document (see also How to Create a DOM tree and Parsing and serializing XML):

##### Example: An XML document to use with the custom `evaluateXPath()` utility function

```xml
<?xml version="1.0"?>
<people>
  <person first-name="eric" middle-initial="H" last-name="jung">
    <address street="321 south st" city="denver" state="co" country="usa"/>
    <address street="123 main st" city="arlington" state="ma" country="usa"/>
  </person>

  <person first-name="jed" last-name="brown">
    <address street="321 north st" city="atlanta" state="ga" country="usa"/>
    <address street="123 west st" city="seattle" state="wa" country="usa"/>
    <address street="321 south avenue" city="denver" state="co" country="usa"/>
  </person>
</people>
```

You can now "query" the document with XPath expressions. Although walking the DOM tree can achieve similar results, using XPath expressions is much quicker and more powerful. If you can rely on `id` attributes, `document.getElementById()` is still powerful, but it's not nearly as powerful as XPath. Here are some examples.

##### Example: JavaScript code with the custom `evaluateXPath()` utility function

```js
// display the last names of all people in the doc
let results = evaluateXPath(people, "//person/@last-name");
for (const i in results)
  console.log(`Person #${i} has the last name ${results[i].value}`);

// get the 2nd person node
results = evaluateXPath(people, "/people/person[2]");

// get all the person nodes that have addresses in denver
results = evaluateXPath(people, "//person[address/@city='denver']");

// get all the addresses that have "south" in the street name
results = evaluateXPath(people, "//address[contains(@street, 'south')]");
console.log(results.length);
```

### docEvaluateArray

The following is a simple utility function to get (ordered) XPath results into an array, regardless of whether there is a special need for namespace resolvers, etc. It avoids the more complex syntax of `document.evaluate()` for cases when it is not required as well as the need to use the special iterators on `XPathResult` (by returning an array instead).

#### Example: Defining a simple `docEvaluateArray()` utility function

```js
// Example usage:
// const els = docEvaluateArray('//a');
// console.log(els[0].nodeName); // gives 'A' in HTML document with at least one link

function docEvaluateArray(expr, doc, context, resolver) {
  let i;
  const a = [];
  doc = doc || (context ? context.ownerDocument : document);
  resolver = resolver || null;
  context = context || doc;

  const result = doc.evaluate(
    expr,
    context,
    resolver,
    XPathResult.ORDERED\_NODE\_SNAPSHOT\_TYPE,
    null,
  );
  for (let i = 0; i < result.snapshotLength; i++) {
    a.push(result.snapshotItem(i));
  }
  return a;
}
```

### getXPathForElement

The following function allows one to pass an element and an XML document to find a unique string XPath expression leading back to that element.

#### Example: Defining a `getXPathForElement()` utility function

```js
function getXPathForElement(el, xml) {
  let xpath = "";
  let pos, tempitem2;

  while (el !== xml.documentElement) {
    pos = 0;
    tempitem2 = el;
    while (tempitem2) {
      if (tempitem2.nodeType === 1 && tempitem2.nodeName === el.nodeName) {
        // If it is ELEMENT\_NODE of the same name
        pos += 1;
      }
      tempitem2 = tempitem2.previousSibling;
    }

    xpath = `\*[name()='${el.nodeName}' and namespace-uri()='${
 el.namespaceURI ?? ""
 }'][${pos}]/${xpath}`;

    el = el.parentNode;
  }
  xpath = `/\*[name()='${xml.documentElement.nodeName}' and namespace-uri()='${
 el.namespaceURI ?? ""
 }']/${xpath}`;
  xpath = xpath.replace(/\/$/, "");
  return xpath;
}
```

### Resources

* XPath
* Forum discussion on this topic
See also
--------

* Introduction to using XPath in JavaScript


substring-after - XPath

substring-after
===============

The `substring-after` function returns a string that is the rest of a given string after a given substring.

### Syntax
```

substring-after( haystack, needle )
```

### Arguments

`haystack`

The string to be evaluated. Part of this string will be returned.

`needle`

The substring to search for. Everything after the first occurrence of `needle` in `haystack` will be returned.

### Returns

A string.

### Examples

| XPath Example | Output |
| --- | --- |
| `substring-after('aa-bb','-')` | `bb` |
| `substring-after('aa-bb','a')` | `a-bb` |
| `substring-after('aa-bb','b')` | `b` |
| `substring-after('aa-bb','q')` | (empty string) |

### Defined

XPath 1.0 4.2

### Gecko support

Supported.


ceiling - XPath

ceiling
=======

The `ceiling` function evaluates a decimal number and returns the smallest integer greater than or equal to the decimal number.

### Syntax
```

ceiling( number )
```

### Arguments

`number`

The number to be evaluated.

### Returns

The nearest integer greater than or equal to `number`.

for example:

`ceiling (5.2)` = *6*

`ceiling (-5.2)` = *-5*

### Defined

XPath 1.0 4.4

### Gecko support

Supported.


boolean - XPath

boolean
=======

The `boolean` function evaluates an expression and returns true or false.

Syntax
------

```js
boolean( expression )
```

Arguments
---------

`expression`

The expression to be evaluated. The expression can refer to numbers and node-sets as well as booleans.

Returns
-------

Boolean `true` or `false` after evaluating `expression`.

Notes
-----

* A number evaluates to false if it is positive or negative zero or `NaN`. Otherwise, it evaluates true.
* A node-set evaluates to true if it is non-empty.
* A string evaluates to false if it an empty string. Otherwise, it evaluates to true.
* An object of a type other than the four basic types is converted to a boolean in a way that is dependent on that type.
Defined
-------

XPath 1.0 4.3

Gecko support
-------------

Supported.


starts-with - XPath

starts-with
===========

The `starts-with` checks whether the first string starts with the second string and returns true or false.

### Syntax
```

starts-with(haystack, needle)
```

### Arguments

`haystack`

The string to look in.

`needle`

The string to look for.

### Returns

`true` if `haystack` starts with `needle`. Otherwise, `false`.

### Defined

XPath 1.0 4.2

### Gecko support

Supported.


position - XPath

position
========

The `position` function returns a number equal to the context position from the expression evaluation context.

### Syntax
```

position()
```

### Returns

An integer equal to the context position from the expression evaluation context.

### Notes

* Note that a node's position in a context is not zero-based. The first node has a position of 1.
* The context is determined by the rest of the path.

```xml
<xsl:template match="//a[position() = 5]">
  <!-- this template matches the fifth a element
 anywhere in the document. -->
</xsl:template>
```

```xml
<xsl:template match="//div[@class='foo']/bar[position() = 1]">
  <!-- this template matches the first bar element that is
 a child of a div element with a class attribute equal to "foo" -->
</xsl:template>
```

### Defined

XPath 1.0 4.1

### Gecko support

Supported.


number - XPath

number
======

The `number` function converts an object to a number and returns the number.

### Syntax
```

number( [object] )
```

### Arguments

`object` (optional)

The object to be converted to a number. If this argument is omitted, the current context node will be used.

### Returns

The resulting number after converting the object.

### Notes

* Strings are converted to a number by stripping the leading whitespace in the string before the number and ignoring whitespace after the number. If the string does not match this pattern, then the string is converted to NaN.
* Boolean true is converted to 1. False is converted to 0.
* A node-set is first converted to a string as if by a call to the string() function and then converted in the same way as a string argument.
* An object of a type other than the four basic types is converted to a number in a way that is dependent on that type.
### Defined

XPath 1.0 4.4

### Gecko support

Supported.


round - XPath

round
=====

The `round` function returns a number that is the nearest integer to the given number.

### Syntax
```

round( decimal )
```

### Arguments

`decimal`

The decimal number to be rounded.

### Returns

The nearest integer less then, greater than, or equal to `decimal`.

### Notes

* -0.5 rounds to negative zero. 0.4 rounds to positive zero.
### Defined

XPath 1.0 4.4

### Gecko support

Supported.


lang - XPath

lang
====

The `lang` function determines whether the context node matches the given language and returns boolean true or false.

### Syntax
```

lang(string )
```

### Arguments

`string`

The language code or localization (language and country) code to be matched.

### Returns

`true` if the context node matches the given languages. Otherwise, `false`.

### Notes

* A node's language is determined by its `xml:lang` attribute. If the current node does not have an `xml:lang` attribute, then the value of the `xml:lang` attribute of the nearest ancestor that has an `xml:lang` attribute will determine the current node's language. If the language cannot be determined (no ancestor has an `xml:lang` attribute), this function will return false.
* If the given `string` does not specify a country code, this function will match nodes of that language with any country code. The converse is not true.

Given this fragment of XML:

```xml
<p xml:lang="en">I went up a floor.</p>
<p xml:lang="en-GB">I took the lift.</p>
<p xml:lang="en-US">I rode the elevator.</p>
```

And this part of an XSL template:

```xml
<xsl:value-of select="count(//p[lang('en')])" />
<xsl:value-of select="count(//p[lang('en-GB')])" />
<xsl:value-of select="count(//p[lang('en-US')])" />
<xsl:value-of select="count(//p[lang('de')])" />
```

The output might be:
```

3
1
1
0
```

### Defined

XPath 1.0 4.3

### Gecko support

Supported.


sum - XPath

sum
===

The `sum` function returns a number that is the sum of the numeric values of each node in a given node-set.

### Syntax
```

sum(node-set)
```

### Arguments

`node-set`

The node-set to be evaluated. Each node in this node-set is evaluated as if it were passed to the number() function, and a sum of the resulting numbers is returned.

### Returns

A number.

### Notes

None.

### Defined

XPath 1.0 4.3

### Gecko support

Supported.


name - XPath

name
====

The `name` function returns a string representing the QName of the first node in a given node-set.

### Syntax
```

name( [node-set] )
```

### Arguments

`node-set` (optional)

The QName of the first node in this node-set will be returned. If this argument is omitted, the current context node will be used.

### Returns

A string representing the QName of a node.

### Notes

* The QName is the node's qualified name, including its namespace prefix and its local name.
### Defined

XPath 1.0 4.1

### Gecko support

Supported.


contains - XPath

contains
========

The `contains` function determines whether the first argument string contains the second argument string and returns boolean true or false.

### Syntax
```

contains(haystack, needle)
```

### Arguments

`haystack`

The string to be searched

`needle`

The string to look for as a substring of `haystack`

### Returns

`true` if `haystack` contains `needle`. Otherwise, `false`.

### Defined

XPath 1.0 4.2

### Gecko support

Supported.


false - XPath

false
=====

The `false` function returns boolean false.

### Syntax
```

false()
```

### Returns

Boolean `false`.

### Notes

This function is useful part of a comparison:

```xml
<xsl:if test="boolean((1 > 2) = false())">
  The expression evaluates as true
</xsl:if>
```

### Defined

XPath 1.0 4.3

### Gecko support

Supported.


unparsed-entity-url - XPath

unparsed-entity-url
===================

The `unparsed-entity-url()` function returns the URI of the unparsed entity with the given name. This is non-XML data referenced in the DTD of the source document.

### Syntax
```

string unparsed-entity-url(string)
```

### Arguments

The name of the unparsed entity. If the argument is not a string, it is converted using the rules of the string() function. The name should be an XML Name.

### Returns

The URI of the unparsed entity retrieved from the DTD, if it exists. Otherwise an empty string.

### Defined

XSLT 1.0 12.4

### Gecko support

Not supported.


string-length - XPath

string-length
=============

The `string-length` function returns a number equal to the number of characters in a given string.

### Syntax
```

string-length( [string] )
```

### Arguments

`string` (optional)

The string to evaluate. If omitted, string used will be the same as the context node converted to a string.

### Returns

An integer equal to the number of characters in the string.

### Defined

XPath 1.0 4.2

### Gecko support

Supported.


function-available - XPath

function-available
==================

The `function-available` function determines if a given function is available and returns boolean true or false.

### Syntax
```

function-available( name )
```

### Arguments

`name`

The name of the function to test.

### Returns

Boolean `true` or `false`.

### Defined

XSLT 1.0 15

### Gecko support

Supported.


normalize-space - XPath

normalize-space
===============

The `normalize-space` function strips leading and trailing white-space from a string, replaces sequences of whitespace characters by a single space, and returns the resulting string.

### Syntax
```

normalize-space( [string] )
```

### Arguments

`string` (optional)

The string to be normalized. If omitted, string used will be the same as the context node converted to a string.

### Returns

The normalized string.

### Defined

XPath 1.0 4.2

### Gecko support

Supported.


namespace-uri - XPath

namespace-uri
=============

The `namespace-uri` function returns a string representing the namespace URI of the first node in a given node-set.

### Syntax
```

namespace-uri( [node-set] )
```

### Arguments

`node-set` (optional)

The namespace URI of the first node in this node-set will be returned. If this argument is omitted, the current context node will be used.

### Returns

A string representing URI of the namespace in which the given node resides.

### Notes

* If the given node does not have a specified namespace, the returned string will be an empty string.
* For nodes other than element and attribute nodes, the returned string will always be an empty string.
### Defined

XPath 1.0 4.1

### Gecko support

Supported.


last - XPath

last
====

The `last` function returns a number equal to the context size from the expression evaluation context.

### Syntax
```

last()
```

### Returns

An integer equal to the context size from the expression evaluation context.

### Notes

* This is often used with the position() function to determine if a particular node is the last in a node-set.
### Defined

XPath 1.0 4.1

### Gecko support

Supported.


element-available - XPath

element-available
=================

The `element-available` function determines if an element is available and returns true or false.

### Syntax
```

element-available( QName )
```

### Arguments

`QName`

Must evaluate to a valid QName. The QName is expanded into an expanded-name using the namespace declarations in scope for the expression.

### Returns

Returns true if and only if the expanded-name is the name of an instruction. If the expanded-name has a namespace URI equal to the XSLT namespace URI, then it refers to an element defined by XSLT. Otherwise, it refers to an extension element. If the expanded-name has a null namespace URI, the element-available function will return false.

### Defined

XSLT 1.0 15

### Gecko support

Supported.


generate-id - XPath

generate-id
===========

The `generate-id` function generates a unique id for the first node in a given node-set and returns a string containing that id.

### Syntax
```

generate-id( [node-set] )
```

### Arguments

`node-set` (optional)

An id will be generated for the first node in this node-set. If omitted, the current context node will be used.

### Returns

A string containing the generated id.

### Notes

* The same id must be generated every time for the same node in the current document in the current transformation.
* The generated id may not be the same in subsequent transformations.

This function is an XSLT-specific addition to XPath. It is not a part of the core XPath function library.

### Defined

XSLT 1.0 12.4

### Gecko support

Supported.


substring-before - XPath

substring-before
================

The `substring-before` function returns a string that is the part of a given string before a given substring.

### Syntax
```

substring-before( haystack, needle )
```

### Arguments

`haystack`

The string to be evaluated. Part of this string will be returned.

`needle`

The substring to search for. Everything before the first occurrence of `needle` in `haystack` will be returned.

### Returns

A string.

### Examples

| XPath Example | Output |
| --- | --- |
| `substring-before('aa-bb','-')` | `aa` |
| `substring-before('aa-bb','a')` | `(empty string)` |
| `substring-before('aa-bb','b')` | `aa-` |
| `substring-before('aa-bb','q')` | (empty string) |

### Defined

XPath 1.0 4.2

### Gecko support

Supported.


count - XPath

count
=====

The `count` function counts the number of nodes in a node-set and returns an integer.

### Syntax
```

count( node-set )
```

### Arguments

`node-set`

The node set to be counted.

### Returns

An integer representing the number of nodes in a node-set.

### Defined

XPath 1.0 4.1

### Gecko support

Supported.


string - XPath

string
======

The `string` function converts the given argument to a string.

### Syntax
```

string( [object] )
```

### Arguments

`object` (optional)

The object to convert to a string. If omitted, the context node is used.

### Returns

A string

### Notes

* If the object is a node-set, the string value of the first node in the set is returned.
* A number is converted as follows:
    + NaN is converted to the string NaN.
    + Positive zero is converted to the string 0.
    + Negative zero is converted to the string 0.
    + Positive infinity is converted to the string Infinity.
    + Negative infinity is converted to the string -Infinity.
    + Decimal numbers between -1 and 1 are converted to a string with a single leading 0 before the decimal point.
    + Boolean true is converted to the string true.
    + Boolean false is converted to the string false.
### Defined

XPath 1.0 4.2

### Gecko support

Supported.


substring - XPath

substring
=========

The `substring` function returns a part of a given string.

### Syntax
```

substring(string, start)
substring(string, start, length)
```

### Arguments

`string`

The string to evaluate.

`start`

The position within `string` the substring begins

`length` Optional

 The length of the substring.
 If omitted, the returned string will contain every character from the `start` position to the end of `string`.

### Returns

A string.

### Notes

As in other XPath functions, the position is not zero-based. The first character in the string has a position of 1, not 0.

### Defined

XPath 1.0 4.2

### Gecko support

Supported.


document - XPath

document
========

The `document` finds a node-set in an external document, or multiple external documents, and returns the resulting node-set.

### Syntax
```

document( URI [,node-set] )
```

### Arguments

`URI`

An absolute or relative URI of the document to be retrieved. The URI may also include a fragment identifier.

`node-set` (optional)

An expression pointing to a node-set in the external document that should be returned.

### Returns

A node-set.

### Notes

* If the URI contains a fragment identifier and that fragment can be identified in the external document, that fragment will be treated as the root in the `node-set` argument's expression. If the `node-set` argument is omitted, the entire fragment will be returned.
* If the `URI` argument is a node-set, and the second argument is present, each node in the node-set will be evaluated as a separate URI, and the returned node-set will be as if the `document` function has been called multiple times (each time with the same second argument just as given in the function call) and the resulting node-sets had been concatenated into a single node-set.
* Other specific conditions exist with specified behaviors. See the XSLT 1.0 documentation for details.
* Since the URI is relative to the XSL document, `document("")` would return the root node of the current document.

This function is an XSLT-specific addition to XPath. It is not a part of the core XPath function library.

### Defined

XSLT 1.0 12.1

### Gecko support

Supported.


translate - XPath

translate
=========

The `translate` function evaluates a string and a set of characters to translate and returns the translated string.

### Syntax
```

translate(string, abc, XYZ)
```

### Arguments

`string`

The string to evaluate.

`abc`

The string of characters that will be replaced.

`XYZ`

The string of characters used for replacement. The first character in `XYZ` will replace every occurrence of the first character in `abc` that appears in `string`.

### Returns

The translated string.

### Notes

XPath notes that the translate function is not a sufficient solution for case conversion in all languages. A future version of XPath may provide additional functions for case conversion.

However, this is the closest we have at present to a function that can convert a string to uppercase or lowercase.

Example

```xml
<xsl:value-of select="translate('The quick brown fox.', 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" />
```

Output
```

THE QUICK BROWN FOX.
```

* If `abc` is longer than `XYZ`, then every occurrence of characters in `abc` that do not have a corresponding character in `XYZ` will be removed.

Example

```xml
<xsl:value-of select="translate('The quick brown fox.', 'brown', 'red')" />
```

Output
```

The quick red fdx.
```

* If `XYZ` contains more characters than `abc`, the extra characters are ignored.
### Defined

XPath 1.0 4.2

### Gecko support

Supported.


floor - XPath

floor
=====

The `floor` function evaluates a decimal number and returns the largest integer less than or equal to the decimal number.

### Syntax
```

floor( number )
```

### Arguments

`number`

The decimal number to be evaluated.

### Returns

The nearest integer less than or equal to `number`.

### Defined

XPath 1.0 4.4

### Gecko support

Supported.


concat - XPath

concat
======

The `concat` function concatenates two or more strings and returns the resulting string.

### Syntax
```

concat( string1, string2 [,stringn]* )
```

### Arguments

`stringn`

This function accepts two or more arguments. Each of these arguments is a string.

### Returns

A single string that is the concatenation of all the strings passed to the function as arguments.

### Defined

XPath 1.0 4.2

### Gecko support

Supported.


id - XPath

id
==

The `id` function finds nodes matching the given ids and returns a node-set containing the identified nodes.

### Syntax
```

id( expression )
```

### Arguments

`expression`

 If `expression` is a node-set, then the string value of each node in the node-set is treated as an individual id. The returned node set is the nodes corresponding to those ids.
 If `expression` is a string, or anything other than a node-set, then `expression` is treated as a space-separated list of ids. The returned node set is the nodes corresponding to those ids.

### Returns

A node-set containing the node or nodes identified by the given id or ids.

### Notes

* The DTD of the XML document determines what attribute is an ID. See XPath 1.0 5.2.1
### Defined

XPath 1.0 4.1

### Gecko support

Partially supported.


format-number - XPath

format-number
=============

The `format-number` function evaluates a number and returns a string representing the number in a given format.

### Syntax
```

format-number(number, pattern)
format-number(number, pattern, decimalFormat)
```

### Parameters

`number`

The number to be formatted

`pattern`

A string in the format of the Java DecimalFormat class.

`decimalFormat` (optional)

The name of an `xsl:decimal-format` element that defines the number format to be used. If omitted, the default decimal-format will be used.

### Return value

A string representing the number in the new format.

### Notes

This function is an XSLT-specific addition to XPath. It is not a part of the core XPath function library.

### Defined

XSLT 1.0 12.3

### Gecko support

Supported.


choose - XPath

choose
======

The `choose` function returns one of the specified objects based on a boolean parameter.

**Note:** This method should be used instead of `if ()`, which has been deprecated.

### Syntax
```

choose( boolean, object1, object2 )
```

### Arguments

`boolean`

The boolean operation to use when determining which object to return.

`object1`

The first object to consider returning.

`object2`

The second object to consider returning.

### Returns

If the boolean parameter is true, the first object is returned; otherwise, the second object is returned.

**Note:** All parameters are evaluated, even the one that's not returned.

### Defined

XForms 1.1

### Gecko support

Supported.


true - XPath

true
====

The `true` function returns a boolean value of true.

### Syntax
```

true()
```

### Returns

Boolean `true`.

### Defined

XPath 1.0 4.3

### Gecko support

Supported.


key - XPath

key
===

The `key` function returns a node-set of nodes that have the given value for the given key.

### Syntax
```

key( keyname, value )
```

### Arguments

`keyname`

A string containing the name of the `xsl:key` element to be used.

`value`

The returned node-set will contain every node that has this value for the given key.

### Returns

A node set.

### Notes

* The `xsl:key` element defines what attribute on what given elements will be used to match the key.

This function is an XSLT-specific addition to XPath. It is not a part of the core XPath function library.

### Defined

XSLT 1.0 12.2

### Gecko support

Supported.


not - XPath

not
===

The `not` function evaluates a boolean expression and returns the opposite value.

### Syntax
```

not( expression )
```

### Arguments

`expression`

The expression is evaluated exactly as if it were passed as an argument to the boolean() function.

### Returns

True for an expression that evaluates to false; false for an expression that evaluates to true.

### Notes

* This function should behave similarly to the boolean() function except that it returns the opposite value.
* You can test if an element doesn't have some attribute.

```xml
<xsl:for-each match="//a[not(@name and @name = 'badname')]">
  <!-- iterates over any <a> element in the document, that
 either has no 'name' attribute at all, or it has one,
 but its value is not "badname". -->
</xsl:template>
```

### Defined

XPath 1.0 4.3

### Gecko support

Supported.


current - XPath

current
=======

The `current` function can be used to get the context node in an XSLT instruction.

### Syntax
```

current()
```

### Returns

A node-set containing only the current node.

### Notes

This function is an XSLT-specific addition to XPath. It is not a part of the core XPath function library.

For an outermost expression (an expression not occurring within another expression), the current node is always the same as the context node (which will be returned by the `.` or `self` syntax). The following two are semantically equivalent.

```xml
<xsl:value-of select="current()"/>
```

```xml
<xsl:value-of select="."/>
```

In an inner expression (e.g. in square brackets), the current node is still the same as it would have been in an outermost expression. Thus within all of the following three expressions the `current` function (not the entire expressions) returns the same node. Moreover, the latter two are semantically equivalent.

```xml
<xsl:value-of select="current()"/>
```

```xml
<xsl:value-of select="foo/bar[current() = X]"/>
```

```xml
<xsl:variable name="current" select="current()"/>
<xsl:value-of select="foo/bar[$current = X]"/>
```

And the next code is also semantically equivalent to the latter two, since the `.` occurs in an outermost expression.

```xml
<xsl:variable name="current" select="."/>
<xsl:value-of select="foo/bar[$current = X]"/>
```

But the `.` always relate to the narrowest context. Thus in

```xml
<xsl:value-of select="foo/bar[. = X]"/>
```

the `.` returns the `bar` node, which may be different from the current node.

### Defined

XSLT 1.0 12.4

### Gecko support

Supported.