Front End Web Development

HTML elements, unite! The Voltron-like powers of combining elements.

Css Tricks - Fri, 09/14/2018 - 4:08am

Guides, resources and discussions about Semantic HTML are often focused around specific elements, like a heading, or a sectioning element, or a list. It’s not often that we talk specifically about how we can combine HTML elements to increase their effectiveness.

Normally, when we introduce HTML, we talk about how it is used to apply meaning to content in a document, and we do this by using examples like:

  • "Is it a paragraph?"
  • "Is it a heading?"
  • "Is it a numbered list"
  • "Is it a button"

We use these examples because they are easy to understand — it’s a single piece or chunk of the same content that needs to be represented in a particular way. This is useful, but it only scratches the surface of how we can use and combine elements to provide more context and meaning.

You remember Voltron, right? Each member of the Voltron force was powerful in their own right, but it was when they combined together to form a towering figure that their mighty powers became unstoppable.

The same is true of HTML elements. I have a few favorite combinations that I’ll take you through. They may seem obscure, but you’d be surprised at how often they come up when you take the time to think outside of divs and spans.

Abbreviations and Definitions

<abbr> and <dfn> are two of my favorite HTML elements. I particularly like them because they work really well together.

You can combine the abbreviation and definition elements to allow browsers, search bots, and other technologies to recognize that something is being defined and that the acronym is associated to that phrase.

<p> The <dfn><abbr title="International Good Dog Association">IGDA</abbr></dfn> is an international, not-for-profit organization responsible for determining that all dogs are good. </p>

In the above example, I’m defining that the acronym "IGDA" as "International Good Dogs Association." I do this by wrapping the acronym in an <abbr> element with a title attribute defining the full name. By adding the <dfn> element around the abbreviation, it indicates that the surrounding paragraph defines the term "International Good Dogs Association."

The <abbr> element is useful because it can provide a useful visual representation in the form of a tooltip explaining what the abbreviation is.

Visual representation of <abbr> and <dfn>. Keyboard, Sample and Variable

If you haven’t heard of these elements, then get ready to have your socks blown off, because they are awesome.

First up, the <kbd> element is used to represent text for a textual user input (e.g. from a keyboard). You can also nest multiple <kbd> elements to represent multiple keystrokes. I love this because, as developers, we find ourselves (hopefully) writing documentation, blog posts, and guides on a regular basis and HTML provides us with native ways to represent this content straight out of the box!

If I wanted to tell someone how you copy and paste with the keyboard, I could mark it up like the code below.

<p>I like to <kbd><kbd>Ctrl</kbd>+<kbd>C</kbd></kbd> and <kbd><kbd>Ctrl</kbd>+<kbd>V</kbd></kbd> a lot.</p>

It looks a bit nuts but the above code, when rendered, looks like the following without any styling applied to it. If you are wondering why kbd is nested inside another kbd element, what this does is specify that the key or input is part of a larger input. Even more combined superpowers!

See the Pen rZpNPy by CSS-Tricks (@css-tricks) on CodePen.

You can further target the <kbd> elements with CSS to make it look more like little keyboard controls. (Note: Browsers tend to render this by default with a monospace font.)

See the Pen gdoOqE by CSS-Tricks (@css-tricks) on CodePen.

If you’re wondering what the difference is between using <kbd> versus a span, I believe it comes down to information. I will repeat this sentiment a lot: we do not know how someone is going to consume our HTML, so give your content it’s best chance by representing it in the most meaningful and contextual way possible. If you are still not on board, then please go read my post about HTML as told by TypeScript.

The <samp> element is really cool because you can nest it inside the <kbd> element and vice versa. WHAT? I know, so versatile! Let’s have a look at some examples from MDN.

The following code is an example of nesting a <samp> element inside a <kbd> element. This is used to mark up content that represents input based on the text displayed by the system (e.g. button names).

<p>To save the image file, select <kbd><kbd><samp>File</samp></kbd> - <kbd><samp>Save as...</samp></kbd></kbd>. </p>

See the Pen YOYzbJ by CSS-Tricks (@css-tricks) on CodePen.

In the above code, we define our keyboard shortcuts the same as our previous example, but we also determine that the menu and menu item names (contained within both <kbd> and <samp>) are an input selected from something displayed by the system, e.g. a dialog or widget.

In other words, this piece of text is a message from the system which has some user inputs that you need to follow (like File and Save as…).

Whereas, when we nest <kbd> inside <samp>, we determine that the input has been echoed back to the user by the system.

<p><samp>yarn start:theproject does not exist, did you mean:</p> <blockquote><samp><kbd>yarn start:the-project</kbd></samp></blockquote>

Finally, the <var> element! This is used to mark up the name of a variable in math or programming, for example:

<var>E</var> = <var>m</var><var>c</var><sup>2</sup>. <samp>Error: <var>console<var> is undefined.</samp>

Here you can start to see how combining <var> with other elements like <pre>, <code>, <kbd> or <samp> starts to make your content’s markup more explicit by adding more context. Anything that interprets your HTML markup can start to derive more meaning from the elements you are using rather than just assuming that it’s all standard text.

If you put this content in a paragraph with some spans, there is no way for technology to distinguish this from any other old text on your page. You don’t have to resort to <span> or a <div> to represent this content because HTML already provides us with more semantically accurate elements we can use. HTML is not just about presentation; it’s about meaning. Various technologies outside of visual rendering engines rely on this meaning to make decisions about how to communicate our content in the most meaningful way (e.g. screen readers, text to voice, reading apps, bots, or the next big thing in the future).


Figures (<figure>) are a great example of a power combination element. Unfortunately, I think it is widely misused and under appreciated (much like <aside>, which I could talk about for hours). The obvious combination you are probably familiar with is using <figure> and <figcaption> together. We often use this duo to represent graphical content like images, illustrations and diagrams — but it can also be used for things like code, poems and quotes!

Because a figure is so flexible in what kind of content it represents, there are a bunch of different HTML elements you can use within a figure to provide more context around the type of content you are putting in your page.


The <figure> element is often seen with an optional <figcaption> which represents a caption or legend for a figure. It should be the first child or last child of the <figure> element. You can also use any flow content (e.g. paragraphs, headings, etc.) in the <figcaption> to provide more context and you can have multiple images inside a <figure> represented by a single <figcaption>.

<figure> <img src="jello.jpg" alt="Golden Retriever Puppy" /> <figcaption>Jello the Golden Retriever enjoying being carried home.</figcaption> </figure> Preformatted Text

The <pre> element is used to display preformatted text or code and is usually rendered using a monospace font. While <pre> can be used on its own, it can also be combined with <figure> and <figcaption>. By doing this, the content inside the <pre> element becomes more accessible to assistive technologies, like screen readers, since it allows us to use <figcaption> as a label for the text or code.

We can go even further by combining the <pre> and <code> elements to identify the pre- formatted content as code.

See the Pen QVaWVW by CSS-Tricks (@css-tricks) on CodePen.

Because <code> is considered flow content, it can also be used inside a <figcaption> to mark up inline references to code (i.e. a single phrase or line).

Cite and Blockquote

Quotations are something I use a lot and it honestly didn’t occur to me it could be used as part of a figure. But it still makes sense to use a cite or blockquote if the content they contain is relevant to the overall content, even if it is not part of the main document flow.

I like the example of using a figure for poems, mainly so I could share the amazing poem I wrote about my dog. Here I use the <cite> element inside the <figcaption>:

<figure> <p> Jello - A little fluffy dog. Hello! Squishy Jello - you little fluffy fellow. BOUNCY yellow Jello. A very mellow fellow. EATING MY MARSHMALLOW. </p> <figcaption><cite>Eating my Marshmallow by Mandy Michael</cite></figcaption> </figure>

It’s easy to fall into the trap of thinking that the figure element is just for images or image-like content, but you can use it for content like audio, video, charts, poems, quotations or even tables of statistics. Because the element is so versatile you can combine it with so many other elements to provide more and more context about the figure for assistive technology, browsers, and other technologies consuming your website.

Wrapping Up

These are just some of the ways HTML elements can be combined for better context. HTML elements are indeed useful and valuable on their own when used as isolated pieces — and using them this way is a good first step. But, like Voltron, when you combine HTML elements together, the individual pieces form a greater whole and gain much more meaning and power. It’s important that we don’t think of HTML as individual pieces of code, but parts of a whole because HTML is really a mass of totally amazing combinations.

You can combine and use HTML elements in any number of ways to best represent your content. Don’t simply stick to the same old things you know; take the time to explore HTML and learn about all it has to offer. Like any language, we should make the most of it and use it to its full potential.

The more accurate you are in marking up your content, the better that content will be represented across technologies, and the more prepared it will be for anything else that is used to interpret your HTML in the future.

So, go forth and HTML elements, unite!


In my opinion, the best resource for learning and understanding how to use HTML (outside of the spec itself) is the MDN Web Docs. It lists all the HTML elements you could ever need.

The following are among the elements covered in this post:

If you are a TypeScript fan and don’t understand why Semantic HTML is important, I wrote this post just for you: Understanding why Semantic HTML is important as told by TypeScript.

The post HTML elements, unite! The Voltron-like powers of combining elements. appeared first on CSS-Tricks.

Why Designers Don’t Want to Think When They Read

Css Tricks - Fri, 09/14/2018 - 4:08am

We've all seen articles like "The Top 5 Ways To Fix Your Sign Up Flow and Get On With Your Life." Articles like this aren't wrong or bad, they are just shallow and a bit junk food-y and BuzzFeed-y. Of course, a designer's actual job is complicated, nuanced, and difficult. But deep dives into all that are far less common.

Khoi Vinh has been writing about this and points to some heavy self-reflection from Fabricio Teixeira and Caio Braga, publishers of the very popular UX Collective.

It’s clear that the currency of design discourse is really concerned with the “how” of design, not the “why” of it. As Teixeira and Braga write:

While designers tend to be skeptical of magic formulas—we’re decidedly suspicious of self-help gurus, magic diets, or miraculous career advice—we have a surprisingly high tolerance for formulaic solutions when it comes to design.

That’s a pointed criticism but, from my perspective, it’s also quite accurate.

Direct Link to ArticlePermalink

The post Why Designers Don’t Want to Think When They Read appeared first on CSS-Tricks.

XOXO 2018

Css Tricks - Thu, 09/13/2018 - 9:34am

There’s not much talk about frameworks here. There’s no shaming about old techniques, or jokes about JavaScript. There’s just a couple hundred people all around me laughing and smiling and watching talks about making things on the web and it all feels so fresh and new to me. Unlike many other conferences I’ve visited, these talks are somehow inclusive and rather feel, well, there’s no other word for it: inspiring.

I’m sitting in a little room buried underneath the Veterans Memorial Coliseum in Portland and I’m here for my third XOXO. And I can’t stop smiling.

Although the festival is not entirely focused on coding and front-end development, there are a lot of developers here that make art on the web for fun. From Jenn Schiffer’s pixel art to Monica Dinculescu’s emoji projects and Nicole He’s buck-wild, there’s a lot of interesting discussions about coding — but! — it’s from a very different perspective than the one I’m familiar with.

Most conferences tend to focus on being practical. Here’s the newest technique! Here’s how to improve your career! Here’s the coolest new folks that you should be following! But it’s important to remember that the web isn’t only a serious place for serious work. It can be this entirely other thing, too.

The web can be for fun. It can be utterly weird and unexpected. And that’s what we’re all seeing in this little room right now at XOXO; websites that can’t be monetized, websites that can’t be controlled by corporate interests or giant ad networks.

Websites that are just for fun.

The post XOXO 2018 appeared first on CSS-Tricks.

What’s the difference between ./dogs.html and /dogs.html?

Css Tricks - Thu, 09/13/2018 - 4:00am

They are both URL paths. They have different names, though.

<!-- root-relative --> <a href="./dogs.html">Dogs</a> <!-- absolute --> <a href="/dogs.html">Dogs</a>

There are also fully-qualified URLs that would be like:

<!-- fully qualified --> <a href="">Dogs</a>

Fully-qualified URL's are pretty obvious in what they do — that link takes you to that exact place. So, let's look those first two examples again.

Say you have a directory structure like this on your site:

public/ ??? index.html ??? animals/ ??? cats.html ??? dogs.html

If you put a link on cats.html that links to /dogs.html (an "absolute" path), it's going to 404 — there is no dogs.html at the base/root level of this site! The / at the beginning of the path means "start at the very bottom level and go up from there" (with public/ being the very bottom level).

That link on cats.html would need to be written as either ./dogs.html (start one directory back and work up) or /animals/dogs.html (explicitly state which directory to start at).

Absolute URLs get longer, naturally, the more complex the directory structure.

public/ ??? animals/ ??? pets/ ??? c/ | ??? cats.html ??? d/ ??? dogs.html

With a structure like this, for dogs.html to link to cats.html, it would have to be either...

<!-- Notice the TWO dots, meaning back up another folder level --> <a href="../c/cats.html">cats</a> <!-- Or absolute --> <a href="/animals/pets/c/cats.html">cats</a>

It's worth noting in this scenario that if animals/ was renamed animal/, then the relative link would still work, but the absolute link would not. That can be a downside to using absolute links. When you're that specific, making a change to the path will impact your links.

We've only looked at HTML linking to HTML, but this idea is universal to the web (and computers, basically). For example, in a CSS file, you might have:

body { /* Back up one level from /images and follow this path */ background-image: url(./images/pattern.png); }

...which would be correct in this situation:

public/ ??? images/ | ??? pattern.png ???index.html ??? style.css

But if you were to move the CSS file...

public/ ??? images/ | ??? pattern.png ??? css/ | ??? style.css ??? index.html

...then that becomes wrong because your CSS file is now nested in another directory and is referencing paths from a deeper level. You'd need to back up another folder level again with two dots, like ../images/pattern.png.

One URL format isn't better than another — it just depends on what you think is more useful and intuitive at the time.

For me, I think about what is the least likely thing to change. For something like an image asset, I find it very unlikely that I'll ever move it, so linking to it with an absolute URL path (e.g. /images/pattern.png) seems the safest. But for linking documents together that all happen to be in the same directory, it seems safer to link them relatively.

The post What’s the difference between ./dogs.html and /dogs.html? appeared first on CSS-Tricks.

Visual. Intuitive. Unlike Anything Else.

Css Tricks - Thu, 09/13/2018 - 3:52am

(This is a sponsored post.)

This team management tool is exceptionally suitable for any industry sector and by any sized team. will perfectly serve a team of two or a team of hundreds spread around the globe, and it can manage multiple projects at once. promotes effortless collaboration and transparency, it's "cheetah fast," it displays status in as many as 20 different colors, and its status board can be customized to fit your needs and your workflow.

It serves as an excellent alternative to having to force fit your work to meet the demands of your project management tools or systems.

Start Free Trial

Direct Link to ArticlePermalink

The post Visual. Intuitive. Unlike Anything Else. appeared first on CSS-Tricks.

Updating a CSS Variable with JavaScript

Css Tricks - Wed, 09/12/2018 - 12:24pm

Here's a CSS variable (formally called a "CSS custom property"):

:root { --mouse-x: 0px; --mouse-y: 0px; }

Perhaps you use them to set a position:

.mover { left: var(--mouse-x); top: var(--mouse-y); }

To update those values from JavaScript, you'd:

let root = document.documentElement; root.addEventListener("mousemove", e => {'--mouse-x', e.clientX + "px");'--mouse-y', e.clientY + "px"); });

That's all.

See the Pen Set CSS Variable with JavaScript by Chris Coyier (@chriscoyier) on CodePen.

The post Updating a CSS Variable with JavaScript appeared first on CSS-Tricks.

Introducing Trashy.css

Css Tricks - Wed, 09/12/2018 - 4:54am

It began, as many things do, with a silly conversation. In this case, I was talking with our Front End Technology Competency Director (aka "boss man") Mundi Morgado.

It went something like this…

Mundi Morgado I want you to build a visual screen reader.

Nathan Smith Who what now?

Mundi Morgado I want a CSS library that allows you to see the structure of a document. It shouldn't use class so that you're forced to focus on semantics. Also, make it theme-able.

Nathan Smith Sure, let me see what I can come up with.

Fast-forward a week, and we've got what we are now calling:

Trashy.css: The throwaway CSS library with no class

Why throwaway? Well, it's not really meant to be a fully fledged, production-ready style framework. Rather, it's like training wheels for document semantics, with some bumper lanes (think: bowling) to keep you on the right track.

It's part of our ongoing effort at TandemSeven to promote code literacy throughout our organization. As more of our UX designers are beginning to share responsibility for the accessibility and semantics of a project, it makes sense that we would build in such a way that allows UX and development to be more collaborative.

There are four main aspects to Trashy.

Trashy: "Basic"

First is the base trashy.css file, which applies a passably basic look and feel to the majority of common HTML elements. Check out this example of a basic page.

Trashy: "Boxes"

Second, there is trashy.boxes.css. This visually distinguishes otherwise invisible semantic elements, such as: header, main, nav, etc. That way, one can see where those elements are (or aren't) as a page is being authored. Here’s a page with semantic boxes outlined.

Trashy: "Theme"

Thirdly, theming is possible via trashy.theme.css. This is mostly just an example — inspired by PaperCSS) — of how to make UI look "hand drawn," to prevent observers from being too fixated on the look and feel, rather than the semantics of a document. Here’s the example theme in action.

Trashy: "Debug"

Lastly, there is a trashy.debug.css file that highlights and calls out invalid and/or problematic markup. Here’s a gnarly example of "everything" going wrong on a single HTML page. This was inspired by a11y.css, though it diverges in what is considered noteworthy.

For instance, we call out "div-itis" when multiple div:only-child have been nested within one another. We're also opinionated about type="checkbox" being contained inside of a <label>. This is for maximum click-ability within an otherwise dead whitespace gap, between a checkbox (or radio) and its textual label.

Any or all of these CSS files can be applied individually or in conjunction with one another. There is also a bookmarklet (labeled "GET TRASHY!") on the Trashy home page you can use to get results for any webpage.

The bookmarklet will remotely pull in:

  • sanitize.css
  • trashy.css
  • trashy.boxes.css
  • trashy.debug.css
Our "reset" - Sanitize.css

A quick word on Santitize.css: It was created by my coworker Jonathan Neal (author of Normalize.css), as a way to have a semi-opinionated CSS "reset." Meaning, it puts in a lot of defaults that we find ourselves writing as developers anyway, so it makes for a good starting point.

Technically speaking

Okay, so now that we’ve covered the "why," let’s dig into the "how."

Basically, it all revolves around using (abusing?) the ::before and ::after pseudo elements. For instance, to show the name of a block level tag, we’re using this CSS.

Semantic tags (using ::before)

Here is an abbreviated version of the trashy.boxes.css file, for succinctness. It causes the <section> tag to have a dashed border, and to have its tag named displayed the top left corner.

section { border: 1px dashed #f0f; display: block; margin-bottom: 2rem; /* 20px. */ padding: 2rem; /* 20px. */ position: relative; } section > :last-child { margin-bottom: 0; } section::before { background: #fff; color: #f0f; content: "section"; font-family: "Courier", monospace; font-size: 1rem; /* 10px. */ letter-spacing: 0.1rem; /* 1px. */ line-height: 1.3; text-transform: uppercase; position: absolute; top: 0; left: 0.3rem; /* 3px. */ } Warning messages (using ::after)

Likewise, here’s a snippet of code from the trashy.debug.css file that drives the markup warning messages. This particular example causes <script> tags to be displayed, which may be further optimized or need the developer’s attention: inline JavaScript and/or external src without async.

In the case of inline JS, we set the font-size and line-height to 0 because we’re making the element visible. We yank the text off the page via text-indent: -99999px just to make sure it doesn’t show up. We wouldn’t want that random JS code displayed alongside legit page content.

(Please don’t ever do this for "real" content. It’s just a hack, mkay?)

To get our error message to show up though, we have to set the font-size and line-height back to non-zero values, and remove our text-indent. Then, with a bit more absolute positioning, we ensure the message is visible. This lets us see, amidst the rest of the page content, whereabouts to check (via DOM inspector) for the <script> insertion point.

script:not([src]), script[src]:not([async]), script[src^="http:"] { color: transparent; display: block; font-size: 0; height: 2rem; /* 20px. */ line-height: 0; margin-bottom: 2rem; /* 20px. */ position: relative; text-indent: -99999px; width: 100%; } script:not([src])::after, script[src]:not([async])::after, script[src^="http:"]::after { background: #f00; color: #fff; display: inline-block; font-family: Verdana, sans-serif; font-size: 1.1rem; /* 11px. */ font-weight: normal; left: 0; line-height: 1.5; padding-left: 0.5rem; /* 5px. */ padding-right: 0.5rem; /* 5px. */ pointer-events: none; position: absolute; text-decoration: none; text-indent: 0; top: 100%; white-space: nowrap; z-index: 1; } body script:not([src])::after, body script[src]:not([async])::after, body script[src^="http:"]::after { top: 0; } script:not([src])::after { content: 'Move inline <script> to external *.js file' ; } script[src]:not([async])::after { content: 'Consider [async] for <script> with [src="…"]' ; } script[src]:not([src=""]):not([async])::after { content: 'Consider [async] for <script> with [src="' attr(src) '"]' ; } script[src^="http:"]::after { content: 'Consider "https:" for <script> with [src="' attr(src) '"]' ; }

Note: Some scripts do need to be loaded synchronously. You wouldn’t want your "app" code to load before your "framework" code. Heck, some inline JS is probably fine too, especially if you’re doing some super speed optimization for the critical rendering path. These warnings are "dumb" in the sense that they match only via CSS selectors. Take ‘em with a grain of salt, your mileage may vary, etc.

JS bookmarklet

The aforementioned JS bookmarklet finds all <link rel="stylesheet"> and <style> tags in the page, and causes them to be ineffective. This allows us to add in our own CSS to take over, so that the only styles applied are those provided directly via Trashy.

The magic is accomplished by setting rel="stylesheet" to rel="". If an external stylesheet is not identified as such, even if it’s cached, the browser will not apply its styles to the page. Similarly, we destroy the contents of any inline <style> tags by setting the innerHTML to an empty string.

This leaves us with the tags themselves still intact, because we still want to validate that no <link> or <style> tags are present within <body>.

We also check that there aren’t too many <style> tags being used in the <head>. We allow for one, since it could be used for the critical rendering path. If there’s a build process to generate a page with consolidated inline styles, then it’s likely they’re being emitted through a single tag.

<a href="javascript:( function (d) { var f = Array.prototype.forEach; var linkTags = d.querySelectorAll('[rel=\'stylesheet\']'); var styleTags = d.querySelectorAll('style');, function (x) { x.rel = ''; });, function (x) { x.innerHTML = ''; }); var newLink = d.createElement('link'); newLink.rel = 'stylesheet'; newLink.href = ''; d.head.appendChild(newLink); } )(document);"> GET TRASHY! </a> Go forth, get Trashy!

Get Trashy

That pretty much covers it. It's a simple drop-in to help you visualize your document semantics and debug possibly problematic markup.

I have also found it to be super fun to use. A quick click of the bookmarklet on any given site usually yields lots of things that could be improved upon.

For instance, here's what CNN's site looks like with Trashy applied…

P.S. Call security!

If you try this with Twitter’s site, you might wonder why it doesn’t work. We were initially perplexed by this, too. It has to do with the site's Content Security Policy (CSP). This can be used to disallow CSS and/or JavaScript from being loaded externally, and can whitelist safe domains.

This can be set either at the server level, or by a <meta> tag in the <head>.

<meta http-equiv="Content-Security-Policy" content="…" />

Read more about CSP here.

I know what you’re thinking...

Can’t you just destroy that meta tag with JS?

In the case of Twitter, it’s emitted from the server. Even if it were in the HTML, destroying it has no effect on the actual browser behavior. It’s locked in.

Okay, so...

Can’t you insert your own security meta tag and override it?

You’d think so. But, thankfully, no. Once a CSP been accepted by the browser for that page, it cannot be overridden. That’s probably a good thing, even though it ruins our fun.

I suppose that’d be like wishing for more wishes. It’s against the genie rules!

The post Introducing Trashy.css appeared first on CSS-Tricks.

The Low Hanging Fruit of Web Performance

Css Tricks - Wed, 09/12/2018 - 4:39am

I kicked off a really poppin' Twitter thread the other day:

What are the LOWEST hanging fruit of web performance? Nothing fancy, anyone can do, big impact.

Gzip. Optimize stuff. Reduce requests...

What are other big ones?

— Chris Coyier (@chriscoyier) August 17, 2018

So, I decided to round up all the ideas (both my own and yours) around that in a post over on the Media Temple blog.

These are the things we dive into in that post:

  1. Reduce Requests
  2. Optimize Assets
  3. Make sure you’re gzipping
  4. Make sure you’re browser caching
  5. Use a CDN
  6. Lazy Load and Defer Loading of Things
  7. Use responsive images (or at least use reasonable sizes)
  8. Mind Your Fonts
  9. Good Hosting / HTTP2 / PHP7
  10. Turbolinks

Direct Link to ArticlePermalink

The post The Low Hanging Fruit of Web Performance appeared first on CSS-Tricks.

Changes on CSS Grid Layout in percentages and indefinite height

Css Tricks - Tue, 09/11/2018 - 8:12am

This is a wonderfully nerdy deep dive into a very specific CSS change by Manuel Rego Casasnovas. Here's a bit of terminology we should know:

First question is, what is an indefinite size? The simple answer is that a definite size is a size that you can calculate without taking into account the contents of the element. An indefinite size is the opposite, in order to compute it you need to check the contents first.

And then goes on to explain how complicated this all gets. The change, in a nutshell:

Percentages row tracks and gutters for indefinite height grid containers will be resolved against the intrinsic height instead of being treated as auto and zero respectively.

Manuel provides a nice visual demo:

See the Pen [css-grid] Percentage row tracks by Manuel Rego Casasnovas (@mrego) on CodePen.

Direct Link to ArticlePermalink

The post Changes on CSS Grid Layout in percentages and indefinite height appeared first on CSS-Tricks.

Supporting Global Type Happenings This Month

Nice Web Type - Tue, 09/11/2018 - 6:54am

From the UK to Spain to New York to San Francisco, we’re happy to support a handful of get togethers of font-loving folk this month.

TypeThursday San Francisco, photo by James Butler

ATypI in Antwerp

ATypI 2018 kicks off today, bringing its annual assortment of workshops, talks and symposiums to Antwerp. Find our own Frank Greißhammer on the Type toolmakers panel early on Wednesday. Later that morning Vinod Balakrishnan, our colleague on the Photoshop team, presents Evolution of digital typographic needs. Catch Frank at 9:25 am and Vinod at 11:40 am.

We’re also supporting the closing party on Saturday evening. Please join us there and hear some remarks from Frank and Taro Yamamoto around 10 pm.

TypeThursday in Barcelona — and beyond

TypeThursday adds its second European chapter this month, when Barcelona launches on September 20th.

Looking for a type event in a different city? Additional evenings of socializing and type crit continue in:

Will you be joining in? Let us know, and see you soon!

Old Timey Terminal Styling

Css Tricks - Tue, 09/11/2018 - 5:32am

I saw a little demo the other day called HTML5 Terminal. It has some functionality, but it seems like it's just kinda for fun. That said, I loved the aesthetic of it! Blurry monospace type with visible monitor lines and a glowing green background — nice!

Let's re-create that, bit-by-bit.

A radial gradient is perfect for the glowing green background:

body { background-color: black; background-image: radial-gradient( rgba(0, 150, 0, 0.75), black 120% ); height: 100vh; }

I'm so used to using <pre><code> to display space-formatted text (like code), but you could say terminal text isn't always code, so I like the use of <pre><output> here.

Might as well use a nice monospace font:

body { ... color: white; font: 1.3rem Inconsolata, monospace; }

The text on the demo appears a bit blurry. We could go with a slight filter like filter: blur(0.6px);, but it seems blurring that way comes out either too blurry or not blurry enough. Let's try using text-shadow instead:

body { ... text-shadow: 0 0 5px #C8C8C8; }

Now on to those monitor lines! Ideally, they should sit on top of the text, so let's use an ::after pseudo-element that's absolutely positioned over the whole area and use a repeating linear gradient for the lines (because it's always nice to avoid using images if we can):

body::after { content: ""; position: absolute; top: 0; left: 0; width: 100vw; height: 100vh; background: repeating-linear-gradient( 0deg, rgba(black, 0.15), rgba(black, 0.15) 1px, transparent 1px, transparent 2px ); }

You can see these faint black lines on white here:

And then over our original green burst background to complete the look:

It's a nice touch to add a fun selection style and remove the blurring for clarity when selecting:

::selection { background: #0080FF; text-shadow: none; }

Complete demo:

See the Pen Terminal Output by Chris Coyier (@chriscoyier) on CodePen.

The post Old Timey Terminal Styling appeared first on CSS-Tricks.

Jetpack’s Social Integration Features

Css Tricks - Tue, 09/11/2018 - 5:30am

One of the many things we use Jetpack for here on CSS-Tricks is all of its features related to social media integration. For example, Jetpack can automatically share published content to different social media accounts simultaneously, add sharing buttons to your site's theme, and allow for social login on the comment form. There is even more than that, but let's dig into these three as we use them.

Auto-Sharing Posts

I like the idea that everything we published goes out to social media. Many people only follow the site that way, so they should see what we're writing. We're specifically into Twitter and Facebook.

With Jetpack installed connected to, I can now flip on the setting:

Then authenticate the services you want to connect:

Now as we publish new articles, there are Publicize controls right there allowing us to send it to the services we want along with a custom message and the featured image:


If you want to get even fancier with social sharing, you can schedule social media posts and do re-sharing through the interface.

Sharing Buttons

Social Media sites tend to have official buttons for features like sharing content on their site or following accounts. You can always add those buttons manually to a theme (it's a bit of HTML the site will give you):

But it's nice to leave this kind of functionality to a plugin, where you can easily configure them and flip them on and off. Jetpack does this. After I've toggled on "Add sharing buttons" in my Jetpack settings, I now have Sharing settings like this where I can get everything as I want them:

I like the "text only" option there which have just about zero performance overhead. Here's an example of simple little buttons capping off an article:

Social Login for Comments

So much of the type-a-reaction we all do these days has super low friction. We reply to a tweet or Facebook post. If it's a blog post comment, a lot of times even those are powered by Facebook or a system like Disqus that has social login. Rarely do we need to manually type our name, email, and website to leave a comment. Yet that's the default for WordPress comments. It's great that is possible, but for increased engagement, allowing people to have a one-click social login is great for a comment form.

If the user is already logged into Twitter, Facebook, Google, or, it is quite literally one-click and they don't need to fill out three additional fields. Even if they aren't, it's likely they have a password manager or it is easier for them to type out their log in credentials quicker than it is to fill out those three fields.

Yay for well managed community discussions!

If you're interested in learning more about Jetpack, this link is great at explaining all it offers. Plus, we go into more detail about the features we use right here on this page.

Here's me with a quick endorsement and explaination of the three things we covered above:

The post Jetpack’s Social Integration Features appeared first on CSS-Tricks.

Customise radio buttons without compromising accessibility

Css Tricks - Mon, 09/10/2018 - 12:03pm

Here’s a nifty post by Chen Hui Jing where she walks us through her process for making radio buttons accessible via keyboard. I particularly enjoyed this bit where she discusses the four options that are available to us to hide the radio input and replace them with a selection of cards that act like toggles instead:

Most of us mess up the keyboard navigation portion of things when we hide the input element. There are several ways to make something invisible or hidden:

  • clip-path: polygon(0 0)
  • display: none
  • opacity: 0
  • visibility: hidden

For custom radios (or checkboxes), option 2 and 4 are not recommended because screen readers won’t be able to read the default radio element. This also prevents us from using the :focus pseudo-element on the hidden input, so those are out of the picture.

Which leaves us with option 1 and option 3. I sort of like option 1, because clip-path is fun. Clip-path creates a clipping region which defines what portion of an element is visible. This clipping region can be a basic shape or a url referencing a clipping path element.

And, while we're on the topic of styling and accessibility, it's worth checking out Scott O'Hara's repo of accessibility-focused styled form components and Dave Rupert's nutrition cards for accessible components.

Direct Link to ArticlePermalink

The post Customise radio buttons without compromising accessibility appeared first on CSS-Tricks.

Creating sliding effects using sticky positioning

Css Tricks - Mon, 09/10/2018 - 4:06am

Sticky elements are predominantly used for keeping something shown on the screen throughout scrolling. As cool as that is, we can also hide elements in the same way!

Here’s a typical (um) sticky situation:

See the Pen position:sticky (CSS) by Preethi Sam (@rpsthecoder) on CodePen.

Sticky elements (position: sticky;) are very similar to fixed elements ( position: fixed;) in that they both maintain their position on the screen, even as the user scrolls up or down the page. The difference? A sticky element remains confined to the parent container it is in. Compare sticky example above with this one that uses the same concept using a fixed element instead:

See the Pen position:sticky (CSS) by CSS-Tricks (@css-tricks) on CodePen.

Say we want to create an effect where elements either slide in or out of view on scroll — sort of like parallax. For example, a header that slides out and a footer that slides in:

Well, guess what? We can do that with sticky elements!

See the Pen Slide In and Out Effect using "position:sticky" by Preethi Sam (@rpsthecoder) on CodePen.

How do we do that? Glad you asked. Let’s break it down.

HTML setup

There are three sticky elements in our example:

  • The first one is the category header that slides under the body of the article once it reaches the top of the screen.
  • The second is the title of the article and it stays visible at the top of the screen, while the body of the content disappears behind it on scroll (which is the typical sticky element behavior).
  • The third element is a footer that slides out of the article and is revealed when the article is scrolled above a certain threshold.

Let’s see how it’s done. Here’s the HTML we’re working with… basically two articles:

<article> <div class="category">Category Header</div> <h1 class="title">Article 1 Title</h1> <p>Body content would go here.</p> <!-- More content --> <div class="footer"> <p>Article 1 Footer</p> </div> </article> <article> <div class="category">Category Header</div> <h1 class="title">Article 2 Title</h1> <p>Body content would go here.</p> <!-- More content --> <div class="footer"> <p>Article 2 Footer</p> </div> </article> The sticky CSS

The .category, .title, and .footer elements will get position:sticky; along with a placement property saying where on the screen they’ll start "sticking" when scrolled.

.category, .title, .footer { position: -webkit-sticky; /* Required for Safari */ position: sticky; height: 50px; } .category { top: 0; } .title { top: 0; } .footer { bottom: 100px; z-index: -1; }

I’m not doing much to the sticky elements, except styling them. They’re already doing what they need to do: stick to the screen. All that’s left is to create a cover and some space for the elements to come in and leave as the page scrolls.

There are probably a bunch of ways we can create a cover on the article that sticky elements can pass and hide under on a page — I went with a background-image.

article { background-image: linear-gradient( to bottom, transparent 50px, #F5A623 50px, #F5A623 calc(100% - 50px), transparent 0 ); margin: auto auto 50px auto; }

The background linear gradient is applied to the article and runs from top to bottom, starting with 50px of transparency and a color change with a hard stop at 50px. The calc stuff? That’s how I’m telling the color to continue but leave 50px at the bottom. Then we go transparent again. That means we have two 50px transparent stripes, one at the top and one at the bottom with equal heights matching the heights of the category heading and the footer.

The category header and the article footer are the elements that slide in and out of the text, so their heights are the ones that determine how long the transparent stripes will be at the top and bottom of the gradient.

How this all comes together is that both the category header and article title stick to the screen when their tops align with the top of the viewport. The title stacks on top of the category header and, when it starts sticking at the top of the viewport, hides the category header altogether.

As for the footer, it’s already stuck 100px above the bottom of the screen (within the article’s boundary), but you won’t see it since it’s pushed behind the content using z-index:-1. It’ll be visible once we scroll past the beginning of the last transparent stripe of article’s background.

.footer { bottom: 100px; margin: 50px auto auto auto; z-index: -1; }

Because the category header is just content with nothing to conceal with but the text itself, it’s a good idea to give the last sticky element (the footer) a top margin of 50px (to keep things equal) so that you won’t see it behind the category header while scrolling.

That’s it!

Now, of course, you’ll want to make this your own and change it up, like the dimensions, number of elements, and type of content. The key is to create those covers that allow your sticky elements to hide behind and be revealed as they pass through — again, probably different ways to go about that, but I went with transparent stripes in a gradient.

What, another example? Sure!

Here’s another example with horizontal scrolling (and a horizontal gradient), that might be ideal for applying this concept to mobile devices:

See the Pen Horizontal slide in and out effect using sticky elements by Preethi Sam (@rpsthecoder) on CodePen.

See how the food gets revealed as one article leaves the viewport and then is hidden when the next article passes over it?

Same sort of HTML setup:

<article> <div class="title">Article 1 Title</div> <p>Article content goes here.</p> <img class="image" src="/path/to/revealed/image.png"> </article> <article> <div class="title">Article 2 Title</div> <p>Article content goes here.</p> <img class="image" src="/path/to/revealed/image.png"> </article>

I’m going to my linear gradient solution for creating the covers, this time going from left-to-right to account for a horizontal scroll:

article { background-image: linear-gradient( to right, transparent 50px, #F5A623 50px, #F5A623 calc(100% - 50px), transparent 0 ); } .title, .image { position: sticky; position: -webkit-sticky; z-index: -1; width: 50px; } .title { left: 20px; margin-right: 52px; } .image { left: 150px; }

Notice again that we’re going with the same two 50px transparent stripes as before — the only difference being that we’re applying it to the width instead of the height.

Both of the sticky elements (the title and image) will slide under and through the article. So, in order to avoid overlapping them during scroll, the title gets a right margin that’s equal to the image’s width, which is 50px (plus an additional 2px for a cleaner line in Chrome).

Here’s what’s going on: as we scroll horizontally, the title sticks 20px from the screen’s left edge and the image sticks 150px from the same. Because they both have z-index: -1;, they’ll disappear under the article (well, the background gradient) — they are hidden as they pass through the solid color of the gradient and are revealed by the transparent stripes.

OK, one more example

Before wrapping up, let me show you one more example that inspired this post. It’s a site footer that reveals itself on scroll. I first saw this design at Ryan Seddon’s website a long time ago.

This design is usually done by using a "fixed" footer that’s given some space at the end of the page to come out to, using margin. I thought if fixed elements can do that for the whole page, then maybe sticky elements can do something similar for individual elements — and hence what I came up with so far.

Consequently, we can accomplish this same effect using the sticky techniques we’ve covered so far.

First, our HTML:

<main> <h1>Site Title</h1> <p>Site content</p> </main> <footer> Site Footer </footer> html { background-color: #fff; } body { background-image: linear-gradient( to top, transparent 60px, #fff 60px, #fff 0 ); } footer { position: -webkit-sticky; position: sticky; bottom: 0; height: 50px; padding: 5px 0; z-index: -1; }

See the Pen Page footer slide-out using "position:sticky" by Preethi Sam (@rpsthecoder) on CodePen.

A sticky footer and background gradient on the body does the trick.

The post Creating sliding effects using sticky positioning appeared first on CSS-Tricks.

Interactive Introduction to CSS Houdini

Css Tricks - Mon, 09/10/2018 - 4:06am

This is a great explanatory microsite by Sam Richard.

CSS Houdini will let authors tap in to the actual CSS engine, finally allowing us to extend CSS, and do so at CSS speeds. Much like Service Workers are a low-level JavaScript API for the browser's cache, Houdini introduces low-level JavaScript APIs for the browser's render engines.

What's important to know is that Houdini is broken up into these different parts, each of which will be implemented separately. We have an intro to the paint API here and a number of other articles that touch on it. Here's a very cool collection Dan Wilson put together of Houdini + Custom Properties.

Direct Link to ArticlePermalink

The post Interactive Introduction to CSS Houdini appeared first on CSS-Tricks.

“Killing the URL”

Css Tricks - Fri, 09/07/2018 - 1:05pm

It was Safari who first started hiding the complete URL. Here's what CSS-Tricks looks like even when you're on an article page by default in Safari:

The full URL path is hidden.

You can only fix it (YES, FIX IT) by checking "Show full website address" in settings.

Preferences > Advanced

We've already damaged the sanctity of URLs in a way with URL shorteners. Thankfully, those are used less and less with social networks, like Twitter, not counting the URL toward the total tweet character count anymore.

Now, Lily Hay Newman reports Chrome sees problems as well:

"People have a really hard time understanding URLs," says Adrienne Porter Felt, Chrome's engineering manager. "They’re hard to read, it’s hard to know which part of them is supposed to be trusted, and in general I don’t think URLs are working as a good way to convey site identity. So we want to move toward a place where web identity is understandable by everyone—they know who they’re talking to when they’re using a website and they can reason about whether they can trust them. But this will mean big changes in how and when Chrome displays URLs. We want to challenge how URLs should be displayed and question it as we’re figuring out the right way to convey identity."

I'm not seeing the same research they are. Anecdotally, I'm not sure I've met anyone who doesn't understand a URL. I wonder if there is something else weird afoot here. URLs are the single greatest feature of the web. I know nobody is arguing about removing them (just visually hiding them by default), but it doesn't feel like a step in the right direction. It also seems slightly at odds with the celebration of the web in Chrome's 10-year anniversary post by Paul Kinlan:

We can thank all the browser vendors for their continued work to create and iterate on specs, using streamlined processes like those defined by the WICG and based on the principles in the Extensible Web Manifesto. We’ll continue our commitment to work with browser vendors and the developer ecosystem to prioritize features that users need, and to ensure that those capabilities arrive in a “webby” way.

I'd say seeing URL's is pretty "webby."

The post “Killing the URL” appeared first on CSS-Tricks.

Shadow DOM in Ionic

Css Tricks - Fri, 09/07/2018 - 1:05pm

Mike Hartington glows about how good and useful the Shadow DOM is:

[Shadow DOM is] actually built on two simple ideas, isolation and location. Need to create a bit of DOM that is isolated from the global scope? Shadow DOM is here to help. Need to specify the exact location of a piece of DOM? Shadow DOMs scope API is what you need!

It can be helpful to think of components that use Shadow DOM as modules for HTML. Markup and styles are isolated to their own DOM tree, and removed from the global context.

Last time we talked about it around here, I showed how Twitter is using it for embedded tweets — which is a pretty awesome use case — and how it can fall back to an iframe. Mike says they polyfill it in unsupported situations.

I suspect isolated styles is the primary selling point for any of the CSS-in-JS approaches, and having wide support for a native implementation of that will eventually take over. But... you have to make use of web components to use this, which means your framework-created components need to be web components. That's totally possible; I just don't see it that often.

Direct Link to ArticlePermalink

The post Shadow DOM in Ionic appeared first on CSS-Tricks.

Working With Events in React

Css Tricks - Fri, 09/07/2018 - 4:01am

Most of the behavior in an application revolves around events. User enters a value in the registration form? Event. User hits the submit button? Another event. Events are triggered a number of ways and we build applications to listen for them in order to do something else in response.

You may already be super comfortable working with events based on your existing JavaScript experience. However, React has a distinct way of handling them. Rather than directly targeting DOM events, React wraps them in their own event wrapper. But we’ll get into that.

Let’s go over how to create, add and listen for events in React.

Creating Events

We’ll start by creating a form that has an input and a button. An event will be triggered when a value is entered. The button is used to call a function which will reverse that value.

Here’s how it'll work:

  • An empty input field allows the user to enter text.
  • An onChange event is triggered when values are entered in the input. This calls a function — handleChange() — that is used to set a new state for the input.
  • When the "Reverse Text" button is clicked, another event is triggered. This calls a function — handleReverse() — to set a new state for reversedText.

Here’s that translated into code:

class App extends React.Component { state = { /* Initial State */ input: "", reversedText: "" }; /* handleChange() function to set a new state for input */ handleChange = event => { const value =; this.setState({ input: value }); }; /* handleReverse() function to reverse the input and set that as new state for reversedText */ handleReverse = event => { event.preventDefault(); const text = this.state.input; this.setState({ reversedText: text .split("") .reverse() .join("") }); }; render() { return ( <React.Fragment> { /* handleReverse() is called when the form is submitted */ } <form onSubmit={this.handleReverse}> <div> { /* Render input entered */} <label>Text: {this.state.input}</label> </div> <div> { /* handleChange() is triggered when text is entered */ } <input type="text" value={this.state.input} onChange={this.handleChange} placeholder="Enter a text" /> </div> <div> <button>Reverse Text</button> </div> </form> { /* Render reversed text */} <p>Reversed Text: {this.state.reversedText}</p> </React.Fragment> ); } }}

See the Pen React Event Pen - form by Kingsley Silas Chijioke (@kinsomicrote) on CodePen.

Listening to component events

Let’s say you have a component like this;

class IncrementButton extends React.Component{ render() { return ( <React.Fragment> <button>+</button> </React.Fragment> ) } }

Will including it in your App component like this work?

class App extends React.Component{ state = { count: 0 } handleIncrement = (event) => { this.setState({ count: this.state.count + 1}) } render() { return( <React.Fragment> <h1>{this.state.count}</h1> <IncrementButton onClick={this.handleIncrement} /> </React.Fragment> ) } }

No, it won’t because you can only listen to events on DOM elements. We touched on this at the beginning of the post, but React components are wrappers for DOM elements. That means we essentially have a layer that we need to pass through to listen for the event.

The way around this is to pass the event handler as a prop to the child component. Then the prop is passed down to the click event as an attribute like so:

class IncrementButton extends React.Component{ render() { return ( <React.Fragment> <button onClick={this.props.increaseButton}>+</button> </React.Fragment> ) } } class App extends React.Component{ state = { count: 0 } handleIncrement = (event) => { this.setState({ count: this.state.count + 1}) } render() { return( <React.Fragment> <h1>{this.state.count}</h1> <IncrementButton increaseButton={this.handleIncrement} /> </React.Fragment> ) } }

See the Pen React Event Pen - Component Events by Kingsley Silas Chijioke (@kinsomicrote) on CodePen.

You could make use of a stateless functional component instead:

const IncrementButton = (props) => { return ( <React.Fragment> <button onClick={props.increaseButton}>+</button> </React.Fragment> ) } Adding event listeners

There may be times when you want to make use of certain DOM events that are triggered when the component is mounted. Let’s see this using the resize event — we want to see the width of the window whenever it is resized.

class App extends React.Component{ state = { windowWith: window.innerWidth } handleResize = (event) => { this.setState({ windowWith: window.innerWidth }) } render() { return( <React.Fragment> <h1>Window Width</h1> <h1>{this.state.windowWith}</h1> </React.Fragment> ) } }

If we create a component and try it out like we have below, then the event will not be triggered. We’ll need to add the event listener (handleResize() in this case) and the event type like we have here:

class App extends React.Component{ state = { windowWith: window.innerWidth } handleResize = (event) => { this.setState({ windowWith: window.innerWidth }) } componentDidMount() { window.addEventListener('resize', this.handleResize) } componentDidUnmount() { window.removeEventListener('resize', this.handleResize) } render() { return( <React.Fragment> <h1>Window Width</h1> <h1>{this.state.windowWith}</h1> </React.Fragment> ) } }

See the Pen React Event Pen - addEventListener by Kingsley Silas Chijioke (@kinsomicrote) on CodePen.

Now, the event listener will be added when the component mounts. That means our component is actively listening to the browser window and will display its width when it updates.

In summary

OK, so we covered quite a bit of ground in a very small amount of space. We learned that React does not connect directly to a DOM event, but rather Synthetic Events that are wrappers for DOM events. We dug into the process for creating event listeners so that they attach to Synthetic Events and, from there, made sure that a component will update when those events are triggered.

Additional resources

The post Working With Events in React appeared first on CSS-Tricks.

New on Typekit: Heading back to school with more fonts

Nice Web Type - Thu, 09/06/2018 - 9:08am

Just in time to get you sorted for a new school year, we’ve got more fonts in the library!

New fonts from Adam Ladd

Adam Ladd’s eye for graphic design is clear in the fonts he’s designed, and we’re excited to add these to our collection. For designs that might otherwise feel a little flat, Active adds a visual texture and contains plenty of alternate character styles to play with.

For a more personal touch than bold Active, try the gentle script Braisetto. This one stands up on its own, especially for packaging and branding uses, but can also be paired with bolder fonts to add a warm contrast. We’ve got two weights of this to work with, too.

See everything we’ve added from Adam Ladd on his foundry page.

Source Serif Italics

The long awaited Italic complement to our popular Source Serif by Frank Grießhammer. Why were the italics released four years after the upright style? See Frank’s blog post where he walks through the design process. Source Serif is available open source on GitHub as well.

Rounding out Hidden Treasures with Reross

The Hidden Treasures of the Bauhaus Dessau collection is now complete with all five typefaces available for you to use. If you need an excuse to try them out, the design challenge is open until September 9.

Hundreds more from Monotype

We’re still reeling from this, to be honest — we added over 600 new fonts from Monotype to our library last month. In our roundup we walked through a few of the highlights, but there wasn’t time or space to give all the fonts their due recognition. You may recognize quite a few classics in there! Check out the Monotype foundry page for the full rundown.

New foundry partners, new Japanese fonts

Our freshest news comes at the end — just this week we welcomed two new Japanese foundry partners to Typekit. Learn more about Kinuta Font Factory and Skill Information”S” in our blog post, or go directly to the foundry pages to check out the new fonts.

Looking for new inspiration? You can always sort our font collection by Newest to catch anything we’ve added recently.

The Complete CSS Demo for OpenType Features

Css Tricks - Thu, 09/06/2018 - 8:47am

I'm very glad a guide for these features exists because we already know there are so many weird things that variable fonts can do — well done, Tunghsiao Liu!

There are quite a few possible values for font-feature-settings, like, ya know:

aalt, swsh, cswh, calt, hist, hlig, locl, rand, nalt, cv01-cv99, salt, subs, sups, titl, rvrn, liga, dlig, size, ornm, ccmp, kern, mark, mkmk, smcp, c2sc, pcap, c2pc, unic, cpsp, case, ital, ordn, lnum, onum, pnum, tnum, frac, afrc, dnom, numr, sinf, zero, mgrk, flac, dtls, ssty, ss01-ss20, smpl, trad, tnam, expt, hojo, nlck, jp78, jp83, jp90, jp04, hngl, ljmo, tjmo, vjmo, fwid, hwid, halt, twid, qwid, pwid, palt, pkna, ruby, hkna, vkna, rlig, init, medi, and fina name a few.

Direct Link to ArticlePermalink

The post The Complete CSS Demo for OpenType Features appeared first on CSS-Tricks.

Syndicate content
©2003 - Present Akamai Design & Development.