cssAudio - Activefile-genericCSS - ActiveGeneric - ActiveHTML - ActiveImage - ActiveJS - ActiveSVG - ActiveText - Activefile-genericVideo - ActiveLovehtmlicon-new-collectionicon-personicon-teamlog-outoctocatpop-outspinnerstartv

Pen Settings

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

You're using npm packages, so we've auto-selected Babel for you here, which we require to process imports and make it all work. If you need to use a different JavaScript preprocessor, remove the packages in the npm tab.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Use npm Packages

We can make npm packages available for you to use in your JavaScript. We use webpack to prepare them and make them available to import. We'll also process your JavaScript with Babel.

⚠️ This feature can only be used by logged in users.

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

            
              <main>
  <h1>Variable Font Demo</h1>
  
  <p>
    This expirement is meant to allow a reader to play around with assorted settings for a typeface to potentially make it easier to read. In particular, I am using this as the first step in exploring the kinds of font traits an author can tweak to make content easier to read for users with dyslexia.
  </p>
  
  <p>
    The font is <a href="https://github.com/Manuel87/NobotoFlex">Noboto Flex</a>. I am not using all the features of the font as some of them do not appear to contribute directly to readability. Chrome/Blink, Edge browsers only.
  </p>
  
  <h2>Generic Text from Wikipedia</h2>

  <p>
    OpenType variable fonts are an adaptation of Apple's TrueType GX font variations to OpenType, with integration into key aspects of the OpenType format including OpenType Layout tables and both TrueType and CFF glyph outline formats. It also surpasses
    TrueType GX by providing better interoperability between different fonts and between variable fonts and font-formatting specification such as are found in Cascading Style Sheets. The technology allows software to access any design instance for a continuous
    range of designs defined within the font. When a specific design instance has been selected, the glyph outlines or other data values for that design instance are computed as font data is being processed during text layout and rasterization.
  </p>
  <p>
    The technology uses interpolation and extrapolation mechanisms that have been supported in font-development tools and used by font designers for many years. In that paradigm, the font designer creates a variable design, but then chooses specific instances
    to generate as static, non-variable fonts that get distributed to customers. With variable fonts, however, the font produced and distributed by the font designer can have built-in variability, and the interpolation mechanisms can now be built into
    operating systems and Web browsers or other applications, with specific design instances selected at time of use.
  </p>
  <p>
    One of the key benefits of the technology is that it can significantly reduce the combined size of font data whenever multiple styles are in use. On the Web, this may allow a site to use more font styles while at the same time reducing page load times.
    A further benefit is that it give access to a continuous range of style variations, which can provide benefits for responsive design.
  </p>
  <p>
    The technology has been compared to Adobe's multiple master fonts (MM fonts) technology, also from the 1990s, which used on-the-fly generation of font designs from master files by interpolation and extrapolation. Multiple master fonts, however, required
    the user to generate a specific "instance" of the font for particular variation-axis values before it could be used. This is not required for OpenType variable fonts, however: named or arbitrary design instances can be selected and used on demand.
  </p>
</main>

<aside>
  <form id="FontToggle">
    <h2>Font Settings <button type="button" aria-label="Reset all." onclick="changeAxis('WGHT','140','wght',1);changeAxis('SPAC','80','SPAC',1);changeAxis('HEIG','400','HEIG',1);changeAxis('ASCE','600','ASCE',1);changeAxis('DESC','600','DESC',1);changeAxis('DIAC','0','DIAC',1);changeAxis('MONO','0','MONO',1);changeAxis('CURV','0','CURV',1);this.focus();">&#8634;</button></h2>
    <p>
      <label for="WGHT">Weight <span aria-hidden="true">(currently <output for="WGHT" form="FontToggle" id="WGHTVal">140</output>)</span>:</label>
      <span>
        <span>54</span>
        <input type="range" id="WGHT" step="1" min="54" max="322" value="140" aria-valuemin="54" aria-valuemax="322" aria-valuenow="140" oninput="changeAxis(this.id,value,'wght');">
        <span>322</span>
        <span><button type="button" aria-label="Reset weight." onclick="changeAxis('WGHT','140','wght',1);">&#8634;</button></span>
      </span>
    </p>
    <p>
      <label for="SPAC">Spacing / tracking <span aria-hidden="true">(currently <output for="SPAC" form="FontToggle" id="SPACVal">80</output>)</span>:</label>
      <span>
        <span>0</span>
        <input type="range" id="SPAC" step="1" min="0" max="200" value="80" aria-valuemin="0" aria-valuemax="200" aria-valuenow="80" oninput="changeAxis(this.id,value,'SPAC');">
        <span>200</span>
        <span><button type="button" aria-label="Reset spacing / tracking." onclick="changeAxis('SPAC','80','SPAC',1);">&#8634;</button></span>
      </span>
    </p>
    <p>
      <label for="HEIG">Height <span aria-hidden="true">(currently <output for="HEIG" form="FontToggle" id="HEIGVal">400</output>)</span>:</label>
      <span>
        <span>165</span>
        <input type="range" id="HEIG" step="1" min="165" max="456" value="400" aria-valuemin="165" aria-valuemax="456" aria-valuenow="400" oninput="changeAxis(this.id,value,'HEIG');">
        <span>456</span>
        <span><button type="button" aria-label="Reset height." onclick="changeAxis('HEIG','400','HEIG',1);">&#8634;</button></span>
      </span>
    </p>
    <p>
      <label for="ASCE">Ascenders <span aria-hidden="true">(currently <output for="ASCE" form="FontToggle" id="ASCEVal">600</output>)</span>:</label>
      <span>
        <span>456</span>
        <input type="range" id="ASCE" step="1" min="456" max="1000" value="600" aria-valuemin="456" aria-valuemax="1000" aria-valuenow="600" oninput="changeAxis(this.id,value,'ASCE');">
        <span>1000</span>
        <span><button type="button" aria-label="Reset ascenders." onclick="changeAxis('ASCE','600','ASCE',1);">&#8634;</button></span>
      </span>
    </p>
    <p>
      <label for="DESC">Descenders <span aria-hidden="true">(currently <output for="DESC" form="FontToggle" id="DESCVal">600</output>)</span>:</label>
      <span>
        <span>456</span>
        <input type="range" id="DESC" step="1" min="456" max="1000" value="600" aria-valuemin="456" aria-valuemax="1000" aria-valuenow="600" oninput="changeAxis(this.id,value,'DESC');">
        <span>1000</span>
        <span><button type="button" aria-label="Reset descenders." onclick="changeAxis('DESC','600','DESC',1);">&#8634;</button></span>
      </span>
    </p>
    <p>
      <label for="DIAC">Diacritics distance <span aria-hidden="true">(currently <output for="DIAC" form="FontToggle" id="DIACVal">0</output>)</span>:</label>
      <span>
        <span>0</span>
        <input type="range" id="DIAC" step="1" min="0" max="100" value="0" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0" oninput="changeAxis(this.id,value,'DIAC');">
        <span>100</span>
        <span><button type="button" aria-label="Reset diacritics distance." onclick="changeAxis('DIAC','0','DIAC',1);">&#8634;</button></span>
      </span>
    </p>
    <p>
      <label for="MONO">Monospace <span aria-hidden="true">(currently <output for="MONO" form="FontToggle" id="MONOVal">0</output>)</span>:</label>
      <span>
        <span>0</span>
        <input type="range" id="MONO" step="1" min="0" max="100" value="0" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0" oninput="changeAxis(this.id,value,'MONO');">
        <span>100</span>
        <span><button type="button" aria-label="Reset monospace." onclick="changeAxis('MONO','0','MONO',1);">&#8634;</button></span>
      </span>
    </p>
    <p>
      <label for="CURV">Curvature <span aria-hidden="true">(currently <output for="CURV" form="FontToggle" id="CURVVal">0</output>)</span>:</label>
      <span>
        <span>0</span>
        <input type="range" id="CURV" step="1" min="0" max="100" value="0" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0" oninput="changeAxis(this.id,value,'CURV');">
        <span>100</span>
        <span><button type="button" aria-label="Reset curvature." onclick="changeAxis('CURV','0','CURV',1);">&#8634;</button></span>
      </span>
    </p>
    <p>
      <a href="https://s.codepen.io/aardrian/debug/yEZvpr" target="_top">Variable Font Demo Using Amstelvar Alpha</a>
    </p>
  </form>
</aside>
            
          
!
            
              :root {
  --page-bg: #eee;
}

/* FF Meta Variable Demo Font */
@font-face {
  font-family: "Noboto Flex";
  src: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/2729/NobotoFlex-VF.ttf")
    format("truetype");
}

body {
  background-color: var(--page-bg);
  font-size: 125%;
  color: #333;
  font-family: "Noboto Flex", sans-serif;
  padding: 0;
  margin: 0;
}

main, aside {
  display: block;
  box-sizing: border-box;
  width: 90%;
  max-width: 38em;
  margin: 1em auto;
  padding: 1em 2em;
  line-height: 1.5;
  color: #333;
  background-color: rgba(255, 255, 255, 0.7);
  border-radius: 0.5em;
  /*   font-variation-settings: "wght" 400, "ital" 1; */
}

aside {
  max-width: 20em;
  padding: 0;
  background-color: transparent;
}

h1, h2 {
  font-weight: 600;
}

form {
  font-family: sans-serif;
  font-size: 90%;
  background-color: rgba(255, 255, 255, 0.7);
/*   background-color: var(--page-bg); */
/*   background-image: linear-gradient(to bottom, #f0f0f0, var(--page-bg)); */
  border-radius: 0.2em;
  padding: 1em;
}

input,
button,
textarea,
select {
  font-size: 100%;
  color: #333;
  font-family: "FF Meta VF", sans-serif;
}

form > h2 {
  display: flex;
  align-items: flex-start
}

input[type="range"] {
  width: calc(100% - 4.3em);
  width: 80%;
}

form p {
  margin-top: 2em;
}

form p:first-child {
  margin-top: 0;
}

form p:last-child {
  margin-bottom: 0;
}

form p > span {
  display: flex;
  justify-content: space-between;
}

form p > span > span {
  font-size: 85%;
}

form button {
  background-color: transparent;
  padding: 0.25em 0.5em;
  margin-left: 0.5em;
  border: none;
  border-radius: 50%;
}

form button:focus,
form button:hover {
  color: #eee;
  background-color: #333;
  outline: none;
}

@media screen and (min-width: 50em) {
  body {
    display: grid;
    grid-template-columns: 2fr 1fr;
    grid-gap: 0;
  }
}

/* The animation */

@keyframes TOOLTIP {
  from {
    bottom: 1em;
    background-color: rgba(0,0,0,0);
    border: .05em solid rgba(255,255,255,0);
    color: rgba(255,255,255,0);
    box-shadow: 0 0 0 rgba(0,0,0,1);
  }
  to {
    bottom: 2em;
    background-color: rgba(0,0,0,.85);
    border: .05em solid rgba(255,255,255,1);
    color: rgba(255,255,255,1);
    box-shadow: .15em .15em .5em rgba(0,0,0,1);
  }
}

/* Style for the tool-tip */

button[aria-label] {
  position: relative;
}

button[aria-label]:focus::after,
button[aria-label]:hover::after {
  position: absolute;
  display: block;
  z-index: 1;
  bottom: 2em;
  right: 0;
  width: 6em;
  max-width: 12em;
  padding: .5em .75em;
  border: .05em solid rgba(255,255,255,1);
  border-radius: .2em;
  box-shadow: .15em .15em .5em rgba(0,0,0,1);
  content: attr(aria-label);
  background-color: rgba(0,0,0,.85);
  color: rgba(255,255,255,1);
  font-size: .8rem;
  text-align: left;
  animation: TOOLTIP .1s ease-out 1;
}
            
          
!
            
              var pageMain = document.querySelector('main');
var wghtVal = '"wght" 140';
var spacVal = '"SPAC" 80';
var heigVal = '"HEIG" 400';
var asceVal = '"ASCE" 600';
var descVal = '"DESC" 600';
var diacVal = '"DIAC" 0';
var monoVal = '"MONO" 0';
var curvVal = '"CURV" 0';
setStyles();

function setStyles() {
  pageMain.setAttribute('style','font-variation-settings: ' + wghtVal + ', ' + spacVal + ', ' + heigVal + ', ' + asceVal + ', ' + descVal + ', ' + diacVal + ', ' + monoVal + ', ' + curvVal + ';');
}

function changeAxis(eID,num,axis,fldReset) {
  document.querySelector('#' + eID + 'Val').value = num;
  document.querySelector('#' + eID).setAttribute('aria-valuenow',num);
  tmpVal = '"' + axis + '" ' + num;
  // Open to another approach that allows me to dump eval
  // eval(axis.toLowerCase() +"Val  = tmpVal");
  // Thanks to Aaron Smith for the non-eval fix
  // https://twitter.com/basiphobe/status/1013801568360189952
  new Function(axis.toLowerCase() +"Val  = tmpVal")();
  setStyles();
  if (fldReset == '1') {
    document.querySelector('#' + eID).value = num;
    document.getElementById(eID).focus();
  }
}

            
          
!
999px
🕑 One or more of the npm packages you are using needs to be built. You're the first person to ever need it! We're building it right now and your preview will start updating again when it's ready.
Loading ..................

Console