CSS-Tricks

Subscribe to CSS-Tricks feed
Tips, Tricks, and Techniques on using Cascading Style Sheets.
Updated: 4 hours 22 min ago

Variable Fonts with Jason Pamental

Mon, 01/29/2018 - 22:03

We've already hit you with a one-two punch of variable fonts today. Robin shared Richard Rutter's post on real-world usage of them. Ollie Williams introduced us to the in's-and-out's of using them on the web.

I figured we'd make it a trifecta and link up our discussion about variable fonts with Jason Pamental. Dave and I talk with Jason for an entire hour digging into the real story, possibilities, and future of all this variable fonts business. Don't miss his or Mandy Michael's demo Collections either.

Direct Link to ArticlePermalink

Variable Fonts with Jason Pamental is a post from CSS-Tricks

One File, Many Options: Using Variable Fonts on the Web

Mon, 01/29/2018 - 14:12

In 2016, an important development in web typography was jointly announced by representatives from Adobe, Microsoft, Apple, and Google. Version 1.8 of the OpenType font format introduced variable fonts. With so many big names involved, it's unsurprising that all browsers are on-board and racing ahead with implementation.

Font weights can be far more than just bold and normal—most professionally designed typefaces are available in variants ranging from a thin hairline ultralight to a black extra-heavy bold. To make use of all those weights, we would need a separate file for each. While a design is unlikely to need every font-weight, a wider variety than bold and normal adds visual hierarchy and interest to a page.

The Google Fonts GUI makes clear: the more weights you choose, the slower your site

There’s more than various weights to consider. CSS3 introduced the font-stretch property, with values from ultra-condensed to ultra-expanded. Until now, these values only worked if you provided a separate file for each width. If you wanted every combination of weight and width in both normal and italic, you would need dozens of files.

The popular Gotham font, available in many width and weight combinations

With variable fonts, we can get all this variety with a single file.

The OpenType spec lists five standard axes of variation—all labeled by a four-character string. These are aspects of the typeface that we have control over.

  • wght - Weight is controlled by the CSS font-weight property. The value can be anything from 1 to 999. This will allow for a more granular level of control.
  • wdth - Width is controlled by the CSS font-stretch property. It can take a keyword or a percentage value. While it's long been possible to use a transform to scaleX or scaleY, that distorts the font in ugly ways unintended by the typographer. The width axis is defined by the font designer to expand or condense elegantly.
  • opsz - Optical sizing can be turned on or off using the new font-optical-sizing property. (I’ll explain what optical sizing is later on.)
  • ital - Italicization is achieved by setting the CSS font-style property to italic
  • slnt- Slant is controlled by setting the CSS font-style property set to oblique. It will default to a 20 degree slant but it can also accept a specified degree between -90deg and 90deg.

Unfortunately, not every variable font will necessarily make use of all five axes. It's entirely dependent on the creator of the particular typeface. After testing every variable font I could get my hands on, by far the most commonly implemented is weight, followed closely by width. Much of the time you will need two files: one for italic and one for regular, as the ital axis isn’t always implemented. As Frank Grießhammer of Adobe told me:

Italic and Roman styles have (often radically) different construction principles, therefore point structures may not always be compatible.

The browser can make any non-italic font emulate italics, but this is typographically ill-advised.

Typographers can define named instances within their variable font. A named instance is a preset—a particular variation the font is capable of accessing with a name (e.g. "Extra Light") rather than with numbers alone. In the current CSS spec, however, there is no way to access these named instances. It's important to note that when you use a value like extra-condensed or semi-expanded for font-stretch, the value maps to a percentage predefined in the CSS spec—not to any named instance chosen by the font creator. For font-weight, the bold value maps to 700 and normal to 400. As the spec puts it, "a font might internally provide its own mappings, but those mappings within the font are disregarded."

The CSS Fonts Module Level 4 spec introduces the new font-variation-settings property to control variable font options. The following two CSS declarations are equivalent:

h1 { font-weight: 850; font-style: italic; font-stretch: normal; } h1 { font-variation-settings: "wght" 850, "wdth" 100, "ital" 1; }

The spec strongly prefers using font-optical-sizing, font-style, font-weight and font-stretch over font-variation-settings for controlling any of the five standard axes. As Myles Maxfield kindly explained to me:

font-variation-settings is not identical to the other variation-aware properties, because with these other properties, the browser has insight into the meaning of the variations, and can therefore do things like applying them to other font file formats, or creating synthesized versions if the font file doesn’t support the axis.

Microsoft will register more standard axes tags over time. As new axes are added, we can also expect new CSS properties to control them. Font creators are also free to invent their own axes. This is why font-variation-settings was added to CSS—it is the only way to control custom axes. Lab DJR and Decovar are two typeface made with the express intention of demonstrating just how malleable a single variable font can be. Lab DJR, for example, offers four custom axes:

h1 { font-variation-settings: 'SIZE' 100, 'QUAD' 80, 'BEVL' 950, 'OVAL' 210; } Courtesy of David Jonathan Ross. David is by the typographer of Lab DJR and already has several variable fonts to his name.

These foundry-defined custom axes must use uppercase letters while the standardized axes always use lower case. With unique and unstandardized options, CSS authors must count on font developers to properly document their work.

The versatility of Decovar is the perfect showcase for the power of variable fonts being more than just a saved HTTP request Performance

You might download a variable font in TTF format rather than as a pre-compressed file. You’ll definitely want to convert it into .woff2. Google offer a command line tool predictably named woff2 to make it easy. If you cd into the folder containing your font while in the command line, you can type:

woff2_compress examplefont.ttf

We’ve established that we’ll only need one HTTP request per typeface (or possibly two to separate Roman and Italic styles). Because they’re doing so much work, you might expect the file size of a variable font to be far larger than a typical font file. Let's have a (not entirely scientific) look.

Here are some of the variable fonts I have hanging around my laptop, along with their file sizes:

Decovar is only 71 KB even though it has 15 axes

Let's compare that to single instances of a non-variable version of Source Sans:

Animation

Variable fonts also mean that, for the first time, font-weight (and any other axis) can be animated. While adding type animation may sound like a superfluous embellishment a website can happily survive without, something like adding weight on focus, for example, seems like a natural and intuitive way to denote state to the user. In the past, switching from a normal to a bold weight was utterly jarring. With variable fonts it can be smooth and graceful.

One Size Fits All?

While Lab DJR and Decovar are excitingly creative, variable fonts aren’t all about avant-garde experimentalism. Optical sizing should bring a better reading experience to the web. Currently, type on the web is size agnostic; you can change the font-size and it will still look the same. Optical sizing means making size-specific optimizations for a typeface where the variation of a letter's form at different sizes can improve readability. We don’t want larger text to look inelegant or clunky, while smaller text benefits from the removal of fine details. More open counters, the thickening of subtle serifs, and an increase in x-height, width, weight and letter-spacing all improve legibility at smaller sizes. The initial value is auto so if you are using a font that makes use of an optical sizing index, you get the benefit for free out of the box.

What Fonts Are Available?

This technology is quickly making its way into browsers. Making use of it requires you to find a variable font you actually want to use. Google Fonts Early Access has three available, with many more likely to follow. Adobe is remaking some of the most well-known families (i.e. Minion, Myriad, Acumin) to be variable. The open source fonts Source Sans and Source Serif have also been released. Monotype, one of the world's largest typography companies, has so far introduced beta versions of Avenir Next and Kairos Sans. Some independent type foundries have also started to release variable typefaces. With variable font support now available in all major font-creation software, we can expect the availability to greatly expand over 2018.

Using Your Font

Once you’ve found your font, you need to use @font-face to include it on your site.

We don’t want any browsers to download a font they can’t use. For that reason, we should specify the format inside the @font-face rule. Depending on the file type of your variable font, you can specify woff-variations, woff2-variations, opentype-variations or truetype-variations. As already mentioned, you should always use woff2.

@font-face { font-family: 'source sans'; src: url(SourceSansVariable.woff2) format("woff2-variations"), url(SourceSans.woff2) format("woff2"); /* for older browsers */ font-weight: normal; font-style: normal; } @font-face { font-family: 'source sans'; src: url(SourceSansVariable-italic.woff2) format("woff2-variations"), url(SourceSans-italic.woff2) format("woff2"); font-weight: normal; font-style: italic; }

A third @font-face is only necessary to provide a backup bold font for browsers that do not support variable fonts. Notice that we are using the same variable font file as for the first @font-face rule, as that file can be both bold and normal:

@font-face { font-family: 'source sans'; src: url(SourceSansVariable.woff2) format("woff2-variations"), url(SourceSans-bold.woff2) format("woff2"); font-weight: 700; font-style: normal; }

If the browser supports variable fonts, SourceSansVariable.woff2 and SourceSansVariable-italic.woff2 will be downloaded and used. If not, SourceSans.woff2, SourceSans-bold.woff2 and SourceSans-italic.woff2 will be downloaded instead.

From here, we can apply the font on an element as we normally would:

html { font-family: 'source sans', Verdana, sans-serif; } San Francisco

While variable fonts bring performance benefits, "web-safe" system fonts still remain the most performant option because the font is already installed and there is nothing to download. If you want to use a variable font without the need of downloading anything, Apple’s San Francisco, perhaps the prettiest of all system fonts, is also a variable font. Using system fonts no longer requires a massive font-stack:

html { font-family: system-ui, -apple-system; }

The system-ui value is the new standard to access system fonts, while -apple-system is non-standardized syntax that works on Firefox. Traditionally, system fonts have not come in a wide range of weights or widths. Hopefully more will be made available as variable fonts, bringing all the benefits of variable fonts without a single HTTP request.

Browser Support

Variable fonts have shipped in Chrome and Safari. They are already in the insider preview version of Edge and behind a flag in Firefox. At the current time, not all parts of the spec are fully implemented by Chrome. Using variable fonts in conjunction with font-style, font-stretch, font-weight and font-optical-sizing does not work in Chrome, so using font-variation-settings to control the five standard axes is necessary for the time being. Specifying the format as woff2-variations inside of @font-face also lacks support in Chrome (you can specify only woff2 and the font will still work, but then you are unable to have a non-variable woff2 fallback).

One File, Many Options: Using Variable Fonts on the Web is a post from CSS-Tricks

How to use variable fonts in the real world

Mon, 01/29/2018 - 14:11

Yesterday Richard Rutter posted a great piece that explores how the team at Clearleft built the new Ampersand conference website using variable fonts (that’s the technology that allows us to bundle multiple widths and weights into a single font file). Here’s the really exciting part though:

Two months ago browser support for variable fonts was only 7%, but as of this morning, support was at over 60%. This means font variations is a usable technology right now.

And the nifty thing is that there’s a relatively large number of variable fonts to experiment with, not only in browsers but also in desktop design apps, too:

Variable font capable software is already more pervasive than you might think. For example, the latest versions of Photoshop and Illustrator support them, and if you’re using macOS 10.13+ or iOS 11+ the system font San Francisco uses font variations extensively. That said, the availability of variable fonts for use is extremely limited. At the time of writing there are not really any commercial variable webfonts available, but there is a growing number of free and experimental variable webfonts, as showcased in the Axis Praxis playground.

Adobe also made a bunch of variable fonts available a while back, if you’re looking for more typefaces.

Direct Link to ArticlePermalink

How to use variable fonts in the real world is a post from CSS-Tricks

Tools for Thinking and Tools for Systems

Fri, 01/26/2018 - 14:43

I’ve been obsessed with design tools the past two years, with apps like as Sketch, Figma and Photoshop perhaps being the most prolific of the bunch. We use these tools to make high fidelity mockups and ensure high quality user experiences. These tools (and others) are awesome and are generally upping our game as designers and developers, but I believe that the way they’ve changed the way we produce work and define UX will soon produce yet another new wave of tools.

In the future, I predict two separate categories of design applications: tools for thinking and tools for systems.

Let me explain.

Tools for Thinking

A short while ago Oliver Reichenstein described why we like distractions and how, in order to make great things, we need dedicated moments of focus, discipline, and concentration:

Starting and finishing need courage. There is no app or tool that will give you courage. But there are environments that encourage distraction. And there are environments that encourage you to focus.

When I read that, I thought about how the design apps I use are wonderfully powerful and built for a specific purpose—but they also encourage distraction. I rarely need mockups of an interface to be as high fidelity as the apps are capable of producing, and any time spent moving pixels around in those apps is almost a complete waste on my part.

Instead, I need a tool to focus on the complex, UX sort of work that underpins all the visual aspects of a large website, and I desperately require focus to do that work. I don’t need to select a pretty typeface, I don’t want custom colors, and I don’t care about how accurate the typographic hierarchy is compared to what is actually released. At this stage of the design process, everything is a suggestion, everything is a sketch, and that’s okay. Also, the messier the sketch, the more freedom I’ve had to experiment wildly in all directions and, crucially, there’s a lot more time to truly understand the information that I’m manipulating.

Herein lies the problem: our current tools encourage me to design the finished product first. They beg me to mess with rounded corners, colors, typefaces and stroke styles. But it's only when I’m working within a strict design system that I ever need to declare those things.

Let’s say we have a half-decent component library where we’ve decided on our typographic hierarchy, our border-radius options, and what sort of background color our buttons have. Do we really need to be so specific in our mockups? Can we be intentionally vague without using pixel-perfect mockups and instead ditch those wireframes in favor of real-life working prototypes built with components from our libraries? Others have suggested this sort of process in the past, of course, but what I find interesting here is the framing, or rather the identification of this new category of tools and the concept that a design can slowly gain fidelity over time. I reckon we shouldn’t expect one tool to carry us through the entire design process.

I believe that Balsamiq is quite possibly the closest example that we have today of what I have in mind: tools that help us think and that remove distractions so that we can focus on the larger and more important architectural, organizational and content problems that we ought to deal with first.

But there will always be a need for another set of tools as well.

Tools for Systems

I hear an awful lot of arguments against using Balsamiq-esque, low fidelity design mockups. The main complaint seems to be that they’re far too imprecise to be useful; they’re not interactive and they’re not responsive. They’re merely drawings of the final app.

A short wile ago, Dan Eden wrote an interesting piece called "The Burden of Precision" which digs into this issue a little bit:

Without engineers, our products are mere static pictures of products. A pale shadow of the finished result. At best, our designs are sandboxed emulations of the real thing; complex prototypes that demonstrate a small fraction of the real-world states the product may encounter. We spend all this time and energy using precise tools to produce perfect caricatures of things we rarely understand the complexities of making real.

I completely agree with Dan here, especially where he argues that:

The precision is introduced by the engineer, where it rightfully belongs. After all, our designs are completely useless until they are built—what exists in the users’ hands is the final design, and nothing less.

This argument reminds me of the scene in Scott McCloud’s Understanding Comics where the author draws a number of faces on a line with a stickman drawing on one end and a realistic drawing of a human face on the other. McCloud argues that:

The ability of cartoons to focus our attention on an idea is, I think, an important part of their special power...

amzn_assoc_tracking_id = "csstricks-20"; amzn_assoc_ad_mode = "manual"; amzn_assoc_ad_type = "smart"; amzn_assoc_marketplace = "amazon"; amzn_assoc_region = "US"; amzn_assoc_design = "enhanced_links"; amzn_assoc_asins = "006097625X"; amzn_assoc_placement = "adunit"; amzn_assoc_linkid = "5b25672b1eb04d67cf22c6b254ad7924";

Likewise, with an app that provides the ability to focus on the necessary details can be hugely beneficial to improving the quality of the interfaces we create. If we already have a component library, then why do we need to make high fidelity mockups in the first place? We already have all those parts in place:

I think what we need are tools to help us translate our low fidelity mockups into real-life working code from component libraries. We can ditch a huge part of the design process that involves adding borders and choosing fonts, because all of those decisions have already been made before and we can lean on those previous decisions to focus on the UX instead.

</rant>

If we have tools to help us think, then the UX of our products, services and apps will improve exponentially because we’ll have an environment that encourages focus on the right things at the right time. We won’t be distracted by making pretty pictures.

Likewise, if we have tools to help us translate our low fidelity mockups into finished code examples—code from our own codebases mind you, not WYSIWYG generators—then we can work much faster and focus on improving our UI as a whole instead of burrowing our heads into one feature at a time. We’ll have fewer inconsistencies and our styleguides and component libraries can act as prototypes to test our designs quickly and iteratively. Airbnb’s recent explorations with Sketch is interesting but I can’t help but see those experiments as hacks on top of a complicated design tool. Instead, let us imagine an app built from the ground up that’s designed to do these sorts of system-y things and leaves the high fidelity mockup features behind.

With that being said, I think there’ll always be a demand for tools like Figma or Sketch and I know that I’ll certainly be using them for the foreseeable future. But I believe there are enormous opportunities to split our design tools up into the two categories I mentioned earlier: tools for thinking and tools for systems.

Tools for Thinking and Tools for Systems is a post from CSS-Tricks

Bend any Website’s CSS to Your Will With Stylish or Stylebot

Thu, 01/25/2018 - 21:35

As a self-professed CSS nerd, I take it upon myself to inject my own CSS onto websites when I need to to fix bugs or just fiddle them up to my liking.

This is a post that details how I do that using the Stylish and Stylebot browser extensions.

Direct Link to ArticlePermalink

Bend any Website’s CSS to Your Will With Stylish or Stylebot is a post from CSS-Tricks

New Features Coming Soon in Safari

Thu, 01/25/2018 - 21:30

Here’s a great thread by Ricky Mondello that outlines all of the nifty new features in the latest Safari across macOS and iOS. Some of my favorites include the ability to replace gifs with mp4s, the Payment Request API and support for the Web App Manifest.

Direct Link to ArticlePermalink

New Features Coming Soon in Safari is a post from CSS-Tricks

Routing and Route Protection in Server-Rendered Vue Apps Using Nuxt.js

Thu, 01/25/2018 - 19:55

This tutorial assumes basic knowledge of Vue. If you haven't worked with it before, then you may want to check out this CSS-Tricks guide on getting started.

You might have had some experience trying to render an app built with Vue on a server. The concept and implementation details of Server-Side Rendering (SSR) are challenging for beginners as well as experienced developers. The challenges get more daunting when you have to do things like data fetching, routing and protecting authenticated routes. This article will walk you through how to overcome these challenges with Nuxt.js.

What You will Learn

The title might have limited the scope of this article because you’re going to learn more than only routing and route protection. Here is a summarized list of what this article covers:

  • Why Server-Side Rendering?
  • Server-Side Rendering and SEO
  • Setting up a Nuxt.js project from scratch
  • Custom layouts
  • Webpacked and static global assets
  • Implicit routing and automatic code splitting
  • Nested and parameterized routes
  • Protecting routes with middleware

You can get the code samples from Github.

Why Should I Render to a Server?

If you already know why you should server-render and just want to learn about routing or route protection, then you can jump to Setting Up a Nuxt.js App from Scratch section.

SSR, also referred to as Universal Rendering or Isomorphic Rendering, is a concept that sprung lately from the JavaScript ecosystem to help mitigate the downsides of JavaScript frameworks.

When we had no JS frameworks or UI libraries like Angular, React, and Vue, the de facto way of building websites was to send an HTML (accompanied with some styles and JS) string as a response from a server which is then parsed and rendered by the browser. This means your views were server-rendered. The most we could do after the page was rendered was to begin the dirty job of manipulating its content using JavaScript or jQuery.

Interactive user interfaces were such nightmares to build using these patterns. In addition to the amount of work you had to do with the DOM via JS, you still needed to do the dirty jobs of poking the DOM, traversing it, and forcing contents and features into it. Worse still, this led to a lot of bad code and poor performing (slow) UIs.

The JavaScript frameworks introduced a few concepts like virtual DOM and declarative APIs which made it faster and more fun to work with the DOM. The problem with them is that the views are entirely controlled with JavaScript. You can say they are JavaScript-rendered. The implication is that unlike the previous era where views were server-rendered by default, JavaScript is required and you have to wait for it before your users see anything.

Here is what you should take away from this long talk:

  1. Server-rendered apps are faster because they do not rely on JavaScript to start painting the browser with content.
  2. JavaScript-rendered apps are preferred for better user experience. Unfortunately, this is only after JavaScript has been parsed and compiled.

We want the speed of the server-rendered app first paint to improve and create a better JS-rendered user experience. This is where the concept of SSR for JavaScript frameworks comes in.

SEO Problems

Another big problem that hits you when building apps with Vue is how to make them SEO friendly. For now, web crawlers don’t seek content to index in JavaScript. They just know about HTML. This is not the case for server-rendered apps because they already respond with the HTML that the crawler needs.

This is how things could go wrong:

The image above shows a simple front end app with some text. In all its simplicity, inspect the page source and you would be disappointed to find out that the text is not in the page source:

Nuxt.js for Server-Rendered Vue Apps

Sarah Drasner wrote a great post on what Nuxt.js is and why you should use it. She also showed off some of the amazing things you can do with this tool like page routing and page transitions. Nuxt.js is a tool in the Vue ecosystem that you can use to build server-rendered apps from scratch without being bothered by the underlying complexities of rendering a JavaScript app to a server.

Nuxt.js is an option to what Vue already offers. It builds upon the Vue SSR and routing libraries to expose a seamless platform for your own apps. Nuxt.js boils down to one thing: to simplify your experience as a developer building SSR apps with Vue.

We already did a lot of talking (which they say is cheap); now let’s get our hands dirty.

Setting Up a Nuxt.js App from Scratch

You can quickly scaffold a new project using the Vue CLI tool by running the following command:

vue init nuxt-community/starter-template <project-name>

But that’s not the deal, and we want to get our hands dirty. This way, you would learn the underlying processes that powers the engine of a Nuxt project.

Start by creating an empty folder on your computer, open your terminal to point to this folder, and run the following command to start a new node project:

npm init -y # OR yarn init -y

This will generate a package.json file that looks like this:

{ "name": "nuxt-shop", "version": "1.0.0", "main": "index.js", "license": "MIT" }

The name property is the same as the name of the folder you working in.

Install the Nuxt.js library via npm:

npm install --save nuxt # OR yarn add nuxt

Then configure a npm script to launch nuxt build process in the package.json file:

"scripts": { "dev": "nuxt" }

You can then start-up by running the command you just created:

npm run dev # OR yarn dev

It’s OK to watch the build fail. This is because Nuxt.js looks into a pages folder for contents which it wills serve to the browser. At this point, this folder does not exist:

Exit the build process then create a pages folder in the root of your project and try running once more. This time your should get a successful build:

The app launches on Port 3000 but you get a 404 when you try to access it:

Nuxt.js maps page routes to file names in the pages folder. This implies that if you had a file named index.vue and another about.vue in the pages folder, the will resolve to / and /about, respectively. Right now, / is throwing a 404 because, index.vue does not exist in the pages folder.

Create the index.vue file with this dead simple snippet:

<template> <h1>Greetings from Vue + Nuxt</h1> </template>

Now, restart the server and the 404 should be replaced with an index route showing the greetings message:

Project-Wide Layout and Assets

Before we get deep into routing, let’s take some time to discuss how to structure your project in such a way that you have a reusable layout as sharing global assets on all pages. Let’s start with the global assets. We need these two assets in our project:

  1. Favicon
  2. Base Styles

Nuxt.js provides two root folder options (depending on what you’re doing) for managing assets:

  1. assets: Files here are webpacked (bundled and transformed by webpack). Files like your CSS, global JS, LESS, SASS, images, should be here.
  2. static: Files here don’t go through webpack. They are served to the browser as is. Makes sense for robot.txt, favicons, Github CNAME file, etc.

In our case, our favicon belongs to static while the base style goes to the assets folder. Hence, create the two folders and add base.css in /assets/css/base.css. Also download this favicon file and put it in the static folder. We need normalize.css but we can install it via npm rather than putting it in assets:

yarn add normalize.css

Finally, tell Nuxt.js about all these assets in a config file. This config file should live in the root of your project as nuxt.config.js:

module.exports = { head: { titleTemplate: '%s - Nuxt Shop', meta: [ { charset: 'utf-8' }, { name: 'viewport', content: 'width=device-width, initial-scale=1' }, { hid: 'description', name: 'description', content: 'Nuxt online shop' } ], link: [ { rel: 'stylesheet', href: 'https://fonts.googleapis.com/css?family=Raleway' }, { rel: 'icon', type: 'image/x-icon', href: 'https://cdn.css-tricks.com/favicon.ico' } ] }, css: ['normalize.css', '@/assets/css/base.css'] };

We just defined our title template, page meta information, fonts, favicon and all our styles. Nuxt.js will automatically include them all in the head of our pages.

Add this in the base.css file and let’s see if everything works as expected:

html, body, #__nuxt { height: 100%; } html { font-size: 62.5%; } body { font-size: 1.5em; line-height: 1.6; font-weight: 400; font-family: 'Raleway', 'HelveticaNeue', 'Helvetica Neue', Helvetica, Arial, sans-serif; color: #222; }

You should see that the font of the greeting message has changed to reflect the CSS:

Now we can talk about layout. Nuxt.js already has a default layout you can customize. Create a layouts folder on the root and add a default.vue file in it with the following layout content:

<template> <div class="main"> <app-nav></app-nav> <!-- Mount the page content here --> <nuxt/> </div> </template> <style> /* You can get the component styles from the Github repository for this demo */ </style> <script> import nav from '@/components/nav'; export default { components: { 'app-nav': nav } }; </script>

I am omitting all the styles in the style tag but you can get them from the code repository. I omitted them for brevity.

The layout file is also a component but wraps the nuxt component. Everything in the this file is shared among all other pages while each page content replaces the nuxt component. Speaking of shared contents, the app-nav component in the file should show a simple navigation.

Add the nav component by creating a components folder and adding a nav.vue file in it:

<template> <nav> <div class="logo"> <app-h1 is-brand="true">Nuxt Shop</app-h1> </div> <div class="menu"> <ul> <li> <nuxt-link to="/">Home</nuxt-link> </li> <li> <nuxt-link to="/about">About</nuxt-link> </li> </ul> </div> </nav> </template> <style> /* You can get the component styles from the Github repository for this demo */ </style> <script> import h1 from './h1'; export default { components: { 'app-h1': h1 } } </script>

The component shows brand text and two links. Notice that for Nuxt to handle routing appropriately, we are not using the <a> tag but the <nuxt-link> component. The brand text is rendered using a reusable <h1> component that wraps and extends a <h1> tag. This component is in components/h1.vue:

<template> <h1 :class="{brand: isBrand}"> <slot></slot> </h1> </template> <style> /* You can get the component styles from the Github repository for this demo */ </style> <script> export default { props: ['isBrand'] } </script>

This is the output of the index page with the layout and these components added:

When you inspect the output, you should see the contents are rendered to the server:

Implicit Routing and Automatic Code Splitting

As mentioned earlier, Nuxt.js uses its file system to generate routes. All the files in the pages directory are mapped to a URL on the server. So, if I had this kind of directory structure:

pages/ --| product/ -----| index.vue -----| new.vue --| index.vue --| about.vue

...then I would automatically get a Vue router object with the following structure:

router: { routes: [ { name: 'index', path: '/', component: 'pages/index.vue' }, { name: 'about', path: '/about', component: 'pages/about.vue' }, { name: 'product', path: '/product', component: 'pages/product/index.vue' }, { name: 'product-new', path: '/product/new', component: 'pages/product/new.vue' } ] }

This is what I prefer to refer to as implicit routing.

On the other hand, each of these pages are not bundled in one
bundle.js. This would be the expectation when using webpack. In plain Vue projects, this is what we get and we would manually split the code for each route into their own files. With Nuxt.js, you get this out of the box and it’s referred to as automatic code splitting.

You can see this whole thing in action when you add another file in the pages folder. Name this file, about.vue with the following content:

<template> <div> <app-h1>About our Shop</app-h1> <p class="about">Lorem ipsum dolor sit amet consectetur adipisicing ...</p> <p class="about">Lorem ipsum dolor sit amet consectetur adipisicing ...</p> <p class="about">Lorem ipsum dolor sit amet consectetur adipisicing ...</p> <p class="about">Lorem ipsum dolor sit amet consectetur adipisicing ...</p> ... </div> </template> <style> ... </style> <script> import h1 from '@/components/h1'; export default { components: { 'app-h1': h1 } }; </script>

Now click on the About link in the navigation bar and it should take you to /about with the page content looking like this:

A look at the Network tab in DevTools will show you that no pages/index.[hash].js file was loaded, rather, a pages/about.[hash].js:

You should take out one thing from this: Routes === Pages. Therefore, you’re free to use them interchangeably in the server-side rendering world.

Data Fetching

This is where the game changes a bit. In plain Vue apps, we would usually wait for the component to load, then make a HTTP request in the created lifecycle method. Unfortunately, when you are also rendering to the server, the server is ready way before the component is ready. Therefore, if you stick to the created method, you can’t render fetched data to the server because it’s already too late.

For this reason, Nuxt.js exposes another instance method like created called asyncData. This method has access to two contexts: the client and the server. Therefore, when you make request in this method and return a data payload, the payload is automatically attached to the Vue instance.

Let’s see an example. Create a services folder in the root and add a data.js file to it. We are going to simulate data fetching by requesting data from this file:

export default [ { id: 1, price: 4, title: 'Drinks', imgUrl: 'http://res.cloudinary.com/christekh/image/upload/v1515183358/pro3_tqlsyl.png' }, { id: 2, price: 3, title: 'Home', imgUrl: 'http://res.cloudinary.com/christekh/image/upload/v1515183358/pro2_gpa4su.png' }, // Truncated for brevity. See repo for full code. ]

Next, update the index page to consume this file:

<template> <div> <app-banner></app-banner> <div class="cta"> <app-button>Start Shopping</app-button> </div> <app-product-list :products="products"></app-product-list> </div> </template> <style> ... </style> <script> import h1 from '@/components/h1'; import banner from '@/components/banner'; import button from '@/components/button'; import productList from '@/components/product-list'; import data from '@/services/data'; export default { asyncData(ctx, callback) { setTimeout(() => { callback(null, { products: data }); }, 2000); }, components: { 'app-h1': h1, 'app-banner': banner, 'app-button': button, 'app-product-list': productList } }; </script>

Ignore the imported components and focus on the asyncData method for now. I am simulating an async operation with setTimeout and fetching data after two seconds. The callback method is called with the data you want to expose to the component.

Now back to the imported components. You have already seen the <h1> component. I have created few more to serve as UI components for our app. All these components live in the components directory and you can get the code for them from the Github repo. Rest assured that they contain mostly HTML and CSS so you should be fine understanding what they do.

This is what the output should look like:

Guess what? The fetched data is still rendered to the server!

Parameterized (Dynamic) Routes

Sometimes the data you show in your page views are determined by the state of the routes. A common pattern in web apps is to have a dynamic parameter in a URL. This parameter is used to query data or a database for a given resource. The parameters can come in this form:

https://example.com/product/2

The value 2 in the URL can be 3 or 4 or any value. The most important thing is that your app would fetch that value and run a query against a dataset to retrieve relative information.

In Nuxt.js, you have the following structure in the pages folder:

pages/ --| product/ -----| _id.vue

This resolves to:

router: { routes: [ { name: 'product-id', path: '/product/:id?', component: 'pages/product/_id.vue' } ] }

To see how that works out, create a product folder in the
pages directory and add a _id.vue file to it:

<template> <div class="product-page"> <app-h1>{{product.title}}</app-h1> <div class="product-sale"> <div class="image"> <img :src="product.imgUrl" :alt="product.title"> </div> <div class="description"> <app-h2>${{product.price}}</app-h2> <p>Lorem ipsum dolor sit amet consectetur adipisicing elit.</p> </div> </div> </div> </template> <style> </style> <script> import h1 from '@/components/h1'; import h2 from '@/components/h2'; import data from '@/services/data'; export default { asyncData({ params }, callback) { setTimeout(() => { callback(null,{product: data.find(v => v.id === parseInt(params.id))}) }, 2000) }, components: { 'app-h1': h1, 'app-h2': h2 }, }; </script>

What’s important is the asyncData again. We are simulating an async request with setTimout. The request uses the id received via the context object’s params to query our dataset for the first matching id. The rest is just the component rendering the product.

Protecting Routes With Middleware

It won’t take too long before you start realizing that you need to secure some of your website’s contents from unauthorized users. Yes, the data source might be secured (which is important) but user experience demands that you prevent users from accessing unauthorized contents. You can do this by showing a friendly walk-away error or redirecting them to a login page.

In Nuxt.js, you can use a middleware to protect your pages (and in turn your contents). A middleware is a piece of logic that is executed before a route is accessed. This logic can prevent the route from being accessed entirely (probably with redirections).

Create a middleware folder in the root of the project and add an auth.js file:

export default function (ctx) { if(!isAuth()) { return ctx.redirect('/login') } } function isAuth() { // Check if user session exists somehow return false; }

The middleware checks if a method, isAuth, returns false. If that is the case, it implies that the user is not authenticated and would redirect the user to a login page. The isAuth method just returns false by default for test purposes. Usually, you would check a session to see if the user is logged in.

Don’t rely on localStorage because the server does not know that it exists.

You can use this middleware to protect pages by adding it as value to the middleware instance property. You can add it to the _id.vue file we just created:

export default { asyncData({ params }, callback) { setTimeout(() => { callback(null,{product: data.find(v => v.id === parseInt(params.id))}) }, 2000) }, components: { //... }, middleware: 'auth' };

This automatically shuts this page out every single time we access it. This is because the isAuth method is always returning false.

Long Story, Short

I can safely assume that you have learned what SSR is and why you should be interested in using it. You also learned some fundamental concepts like routing, layouts, security, as well as async data fetching. There is more to it, though. You should dig into the Nuxt.js guide for more features and use cases. If you’re working on a React project and need this kind of tool, then I think you should try Next.js.

Routing and Route Protection in Server-Rendered Vue Apps Using Nuxt.js is a post from CSS-Tricks

The Wix Code Database and Data Modeling

Thu, 01/25/2018 - 19:53

(This is a sponsored post.)

I happen to know many of the readers of CSS-Tricks are strong web designers and developers. Most of you probably don’t use website builders very often, as you are a website builder. You love the control. You love the possibilities. You want to be close to the metal because that’s your expertise.

But you also know the costs. Everything you chose to yourself piles on to the responsibility you take on. Technical debt. Using a site builder like Wix can dramatically reduce that technical debt, and you might be surprised at how little control you have to give up. The following post is about some new and very powerful new features of Wix right up that alley.

One of the cool features of Wix Code is the ability to separate your site’s design and layout from its content. This means you can create and maintain your information in a database and then have your pages dynamically retrieve and display this information in whatever way you like.

Let’s take an in-depth look at what you can do with the Wix Code database, including the types of information you can store, ways you can manipulate data with code, and how you can dynamically display the information on your site.

Throughout this article, we’ll use a simplified example of an art school that stores and displays information about its courses and teachers.

The Wix Code Database

Like all databases, the Wix Code database is made up of individual tables, which we call collections. In our example of the art school (see image below), we have two collections, one each for the courses and teachers.

You can create as many collections as you need and populate them with a near unending amount of data. A robust permissions model means you have complete control over who can access your information and what they can do with it.

You can work directly with your Live data, which is the information your visitors see when they view your pages. You can also work with Sandbox data, so you can try stuff out without affecting your live site. You can sync with them at any time.

Populating Collections

You have several options for populating your collections. You can manually enter data directly in the Wix Content Manager, either to your Live data or your Sandbox data.

If you’re an Excel ace, you can do all the work in Excel (or whatever spreadsheet program you prefer), save your sheet as a CSV file, and then import it into the Wix Code database. In fact, you can create your entire collection this way, schema and all. You can import to your Live data or your Sandbox data.

You can also export your Wix data to CSV files. If you make sure to include the built-in ID system field, you will be able to modify your content in your spreadsheet and then re-import it into your Wix Code database so that each record, or what we call item, is updated.

A third option is to build a form to capture user input and store it in your database.

Using External Databases

If you already have a database somewhere, you might be thinking that you don’t want to recreate it in Wix. The good news is that you don’t have to. As long as your database exposes an API, you can access it from your Wix site.

For simple applications, you can use the wix-fetch module—an implementation of the standard JavaScript Fetch API—to access your external database with an HTTP request and use that data in your Wix site’s pages.

You can also pair the wix-fetch module with another Wix module, wix-router, that lets you control the routing of incoming requests. Using the functionality provided by both of these modules, you can create SEO-friendly dynamic pages that show different data depending on the URLs used to reach them.

For example, you can design a single member profile page that can be used by all of your site’s members.

Using wix-router and wix-fetch you can write code that pulls information from incoming requests for the profile page, queries an external database to retrieve the information for the page, and then injects that data into the profile page. You can even add security to your page by using the wix-users module.

So if you create another page for users to update their profile pages, you can check who is trying to access it and only allow users to update their own profiles.

Data Hooks

You can add hooks to actions on your collections using the wix-data API.

For example, in our Teachers collection, we have two separate fields: First name and Last name. To make displaying names on our pages easier, we also want to have one field that has both names together. To do this, we can add a beforeInsert hook to our Teachers collection that hooks into the insert action, reads the contents of the First name and Last name fields, and then concatenates them and populates the Full name field.

Modeling Your Data

Now that we’ve covered the database itself, let’s talk about modeling your data in the Wix Code database.

Collection Schemas
Like all databases, each collection has a schema to define its fields. All standard field types are supported, including text, image, boolean, number, date and time, and rich text.

There is also a field type specifically designed for URLs. It automatically formats the URL into clickable links that you can add to your pages. For example, teachers in your school could supply the URL of their portfolio website, and you could include that link on their dynamic page.

You can also use the document field type to store a wide range of file types. You can allow your users to download files stored in your collections (such as reading lists for each course) or to upload their own files.

ID Fields and Primary Fields

Each collection has an _ID field, which is the primary key for that table. Collections also have a primary field (indicated by a lock icon), which is the display key for each item.

When you create joins using reference fields (see the next section), the values come from the primary field. The reference itself uses the _ID field, of course. If you plan on using reference fields, it’s a good idea to make sure the data you store in the primary field is unique.

Reference Fields

Reference fields create a connection between collections that is defined in the collection schema itself. This is similar to foreign keys in relational databases.

Each reference field points to a specific collection. The value that is displayed in the reference field in each item in the collection is taken from the value of the primary field of the referenced collection.

In our example, we created a reference field in our Courses collection that points to our Teachers collection so that we can indicate who teaches each class.

The advantage of reference fields is three-fold. First, they help maintain data integrity because their value is taken directly from the referenced collection. Second, they help eliminate data duplication, which we all know is the enemy of good database design. And third, when we create our page layouts, reference fields let us access information in the referenced collection as well as in the main collection we are using. This allows us to create master-detail pages, such as a list of all the courses taught by each teacher.

Creating Pages from Your Content

Of course, storing and maintaining data is nice, but the real point of having a website is displaying content to visitors. So let’s talk about how that works with Wix Code.

Back to our art school example. We have two different types of information: courses and teachers. So you could start by designing a page layout to display all the information about each of the courses. Then you might want to create a master-detail page that lists all of your teachers and the courses they teach.

Setting Up the Dynamic Page

When you create dynamic pages in Wix Code, you first define the URL that will control what content your page can display. Some URLs can specify a single item and others can specify an entire category of items (such as all courses of a certain level).

You set up the URL pattern by picking a field (or fields) from your collection. One URL pattern you could use to display each of your courses could be https://.../Courses/<Title>. Each time a different page is generated, the field is replaced by the actual title of the item being retrieved. So one-course page’s URL would be https://.../Courses/Art-History, and another course page’s URL would be https://.../Courses/Intro-to-Painting.

Then you design your page layout in the Editor, putting different elements on the page and connecting the ones you want to use to display dynamic data to fields in your collection. You can use text elements, images, buttons, strips, and a variety of multi-item elements like repeaters, tables, and galleries. If you want some items to remain static, such as titles, just don’t connect them.

The image below is an example of what a dynamic page layout for our Courses page could look like in the Editor. The square brackets indicate that this content is dynamic.

The actual dynamic pages could look something like these.

Note how both pages have the same layout. However, some of the elements’ contents have been replaced with the information about the courses from our database. The page background is also different for each page. The container box even enlarged automatically to include the larger course description for the Art History course.

Note especially how the name and picture of each course’s teacher appear on the page, even though the details about each instructor are stored in a separate collection from the data about the course. This is because we connected the Courses and the Teachers collections using a reference field, which gave us access to information about the specific teacher for each course.

Finally, note how the page URLs are unique to each page. In essence, each of these pages is unique. And Wix Code creates them automatically for us. If we add a new course to our collection, a page for it is automatically created.

Master-Detail Pages

Another cool thing you can do with Wix Code is to create master-detail pages. For example, you could create a page to act as an index that lists all the teachers in your school and the courses each one teaches. This would require pulling information from more than one collection (Courses and Teachers) and then filtering the courses by their teacher so that only the relevant courses are displayed.

Our database collections are set up in a many-to-one structure; each teacher has many courses they teach. Whereas above we displayed each course and their individual teacher, now we are taking the opposite approach and displaying each teacher and all their courses.

Below is a sample of what an index page with master-detail information might look like using a repeater.

Because the repeater is connected to both our Teachers collection and our Courses collection, it can display the information from both collections dynamically. The embedded table element in each repeater item displays the list of courses each teacher teaches.

Summary

We’ve presented some high-level information about the Wix Code database and some of the capabilities it offers for storing your data, manipulating your data, and displaying your data dynamically to your visitors. We’ve also illustrated how the options available to you are controlled in part by the decisions you make when you create your collections and connect them. Before you get started creating your Wix Code database, it’s a good idea to spend some time thinking about what kind of information you have and how you want to display it so that you can most effectively model your data.

Direct Link to ArticlePermalink

The Wix Code Database and Data Modeling is a post from CSS-Tricks

How to Style a Form With Tailwind CSS

Wed, 01/24/2018 - 15:10

If you've been staying in the loop with the latest CSS frameworks, you've probably already heard of the newest kid on the block: Tailwind CSS. According to its documentation, "Tailwind is a utility-first CSS framework for rapidly building custom user interfaces."

In practice, this means using a variety of classes that closely map to underlying CSS properties. For example, applying a class like .text-center to an element means that we're setting its text-align property to center. Simple enough, right?

Using utility classes like this allows us to spend more time iterating through designs and avoiding premature abstraction of our CSS. Then, once we're happy with our designs, Tailwind makes it easy to extract our utilities into component classes.

Now, I'm sure you know that even mentioning a utility framework is an open invitation for a certain amount of brouhaha. Before we start yelling at me on Twitter or the comments for even mentioning a utility framework, let's just take a moment to remember that Tailwind is just one possible tool for us to use.

If you don't want to add it to your toolbox, then no worries—you do you! But, if you're interested in at least understanding this new tool, let's take a look at building a sign-up form together.

Without further ado, let's set up a fresh project with Tailwind, code out some HTML, and style it up.

The Set Up

Let's start by creating a directory for us to work from. Using your terminal, navigate to the directory you'd like to create your project and run mkdir <your-project-name>. Now, let's cd into our new project and follow the Tailwind installation guide.

Since we want to see everything that Tailwind can do, let's install it with npm or Yarn using the following.

# Using npm npm install tailwindcss --save-dev # Using Yarn yarn add tailwindcss --dev

With Tailwind installed, we can now generate the configuration file by running ./node_modules/.bin/tailwind init. This generates a tailwind.js file for us in the root of our project. In this file, we can adjust Tailwind's default settings to our project's needs. For this project, we shouldn't have to change a thing.

Now, let's create a CSS file where we can manage our own CSS and inject the Tailwind styles. To do that we can run touch styles.css from our project directory.

Inside of this new file, we can use Tailwind's @tailwind directive to inject the preflight and utilities styles into our CSS. preflight contains all of the base styles and some browser style normalizations, while utilities adds all of the utility classes we specified in our config file. So, our styles.css file should look something like this:

@tailwind preflight; /* Here we can add any custom overrides */ @tailwind utilities; /* Here we can add our own utilities or custom CSS */

If you're using PHPStorm and you're annoyed by the red squiggles in your CSS file for @tailwind, just add /*noinspection CssInvalidAtRule*/ above where you use it.

With that all set up, we can run ./node_modules/.bin/tailwind build styles.css to generate the CSS file we'd like to use in our project. This may seem a bit tedious, but don't worry! Tailwind works with proper build tools like Webpack, Gulp, or Laravel Mix, so in a larger project you can just set it and forget it.

That'll take care of our Tailwind set up! Now, we can start coding our HTML.

Our HTML

Before we can style our sign-up form, we need to build it! To start, we'll need a simple index.html file. So, from your root directory, you can run touch index.html to create the file. Then, we can add the following snippet to get us started.

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Tailwind Intro</title> <link rel="stylesheet" href="main.css"> </head> <body> </body> </html>

As you can see, it's your typical HTML page. The only wrinkle here is that we're importing our main.css file and we've given our page a descriptive title. Now, let's start building our sign-up form!

To start, let's add two nested <div> elements to the inside of our <body> tag.

<body> <div> <div> </div> </div> </body>

We'll use the outer <div> for our page positioning, while the inner <div> will be the wrapper for our form. Now, inside the inner <div>, we can add a <h1> to label the form, and a <form>.

<div> <h1>Sign Up</h1> <form action="/" method="post"> </form> </div>

We're really cooking with gas now! To finish the form, we just need to add the <label> elements, <input> elements, and <button>. As we add them, let's wrap each of our <label> <input> pairs in a <div> so they stay together.

<form action="/" method="post"> <div> <label for="first_name">First Name</label> <input type="text" name="first_name" id="first_name"> </div> <div> <label for="last_name">Last Name</label> <input type="text" name="last_name" id="last_name"> </div> <div> <label for="email">Email</label> <input type="email" name="email" id="email"> </div> <div> <label for="password">Password</label> <input type="password" name="password" id="password"> </div> <button type="submit">Create Account</button> </form>

Finally, let's add a link to access the login page right below our form.

<div> <!-- Form is here --> <a href="/login">Already have an account?</a> </div>

Putting that all together, our HTML will look like this:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Tailwind Intro</title> <link rel="stylesheet" href="main.css"> </head> <body> <div> <div> <h1>Sign Up</h1> <form action="/" method="post"> <div> <label for="first_name">First Name</label> <input type="text" name="first_name" id="first_name"> </div> <div><label for="last_name">Last Name</label> <input type="text" name="last_name" id="last_name"> </div> <div> <label for="email">Email</label> <input type="email" name="email" id="email"> </div> <div> <label for="password">Password</label> <input type="password" name="password" id="password"> </div> <button type="submit">Create Account</button> </form> <a href="/login">Already have an account?</a> </div> </div> </body> </html>

Pretty straightforward, right? Now, when we see how that renders on the page, we should see something that looks like this:

Don't be alarmed if it looks like the <input>s are missing; that's just the browser resets at work. At last, we're ready to see what this Tailwind CSS is all about.

Using Tailwind CSS

Being the good developers that we are, let's take a mobile-first approach to styling our sign-up form. So, at a smaller viewport width of 400px, our page looks like this:

Styling Our Form Fields

Let's start using Tailwind by styling our <input>s. First, let's add a border so we can see it on the page. To do that, we just need to add the .border class. So, now our first name <input> will look like this:

<input class="border" type="text" name="first_name" id="first_name">

Now we can see it on the screen!

How easy was that? Let's continue by adding some padding and making the text color a touch lighter. To do that, we just need to add the following classes: .py-2, .px-3, and .text-grey-darkest.

<input class="border py-2 px-3 text-grey-darkest" type="text" name="first_name" id="first_name">

With the first two classes, we're taking advantage of the padding scale that comes with Tailwind and applying it vertically and horizontally to the element. If you want to define your own scale, just hop into your config file and change it to what you need. With the last class, we're using Tailwind's default color palette and changing the color of our element to the darkest grey.

Let's take our form a step further. Now, we can position our <label>s above our <input>s and give them a bit of styling.

<div class="flex flex-col mb-4"> <label class="mb-2 uppercase font-bold text-lg text-grey-darkest" for="first_name">First Name</label> <input class="border py-2 px-3 text-grey-darkest" type="text" name="first_name" id="first_name"> </div>

Look at that, our first name field looks great! And the best part is that I really don't have to explain what these classes are doing—they explain themselves! But just so we're all on the same page, let me run through them quickly.

The outer <div> has its display property set to flexvia .flex and its flex-direction is set to column with .flex-col. Then it has a bit of margin on the bottom thanks to .mb-4.

Meanwhile, our <label> has a little less margin on the bottom thanks to .mb-2. The rest of the classes make our text uppercased, bold, large (1.125rem), and the darkest grey in our color palette.

Altogether, a pretty quick and easy way to style our fields! Now, let's add these styles to the rest of our fields, style our button and link, and see what we're working with.

<form class="mb-6" action="/" method="post"> <div class="flex flex-col mb-4"> <label class="mb-2 uppercase font-bold text-lg text-grey-darkest" for="first_name">First Name</label> <input class="border py-2 px-3 text-grey-darkest" type="text" name="first_name" id="first_name"> </div> <div class="flex flex-col mb-4"> <label class="mb-2 uppercase font-bold text-lg text-grey-darkest" for="last_name">Last Name</label> <input class="border py-2 px-3 text-grey-darkest" type="text" name="last_name" id="last_name"> </div> <div class="flex flex-col mb-4"> <label class="mb-2 uppercase font-bold text-lg text-grey-darkest" for="email">Email</label> <input class="border py-2 px-3 text-grey-darkest" type="email" name="email" id="email"> </div> <div class="flex flex-col mb-6"> <label class="mb-2 uppercase font-bold text-lg text-grey-darkest" for="password">Password</label> <input class="border py-2 px-3 text-grey-darkest" type="password" name="password" id="password"> </div> <button class="block bg-teal hover:bg-teal-dark text-white uppercase text-lg mx-auto p-4 rounded" type="submit">Create Account</button> </form> <a class="block w-full text-center no-underline text-sm text-grey-dark hover:text-grey-darker" href="/login">Already have an account?</a> Adding Hover Styles

Now things are starting to look better! In this block of code, everything should be pretty self-explanatory. However, we have added one new thing: a state variant. If we take a look at our <button>, we can see one in action.

<button class="block bg-teal hover:bg-teal-dark text-white uppercase text-lg mx-auto p-4 rounded" type="submit">Create Account</button>

If you look at the class right after .bg-teal, you can see that we've added a hover: prefix to .bg-teal-dark. These prefixes let us style elements on hover and focus, and they let us use breakpoints too! All in all, this is a pretty powerful feature of Tailwind and it lets us create dynamic, responsive UI very quickly.

Now, let's wrap our mobile view by positioning our form in the middle of the screen and adding a colorful page background.

<div class="flex items-center h-screen w-full bg-teal-lighter"> <div class="w-full bg-white rounded shadow-lg p-8 m-4"> <h1 class="block w-full text-center text-grey-darkest mb-6">Sign Up</h1> <form class="mb-4" action="/" method="post"> <div class="flex flex-col mb-4"> <label class="mb-2 uppercase font-bold text-lg text-grey-darkest" for="first_name">First Name</label> <input class="border py-2 px-3 text-grey-darkest" type="text" name="first_name" id="first_name"> </div> <div class="flex flex-col mb-4"> <label class="mb-2 uppercase font-bold text-lg text-grey-darkest" for="last_name">Last Name</label> <input class="border py-2 px-3 text-grey-darkest" type="text" name="last_name" id="last_name"> </div> <div class="flex flex-col mb-4"> <label class="mb-2 uppercase font-bold text-lg text-grey-darkest" for="email">Email</label> <input class="border py-2 px-3 text-grey-darkest" type="email" name="email" id="email"> </div> <div class="flex flex-col mb-6"> <label class="mb-2 uppercase font-bold text-lg text-grey-darkest" for="password">Password</label> <input class="border py-2 px-3 text-grey-darkest" type="password" name="password" id="password"> </div> <button class="block bg-teal hover:bg-teal-dark text-white uppercase text-lg mx-auto p-4 rounded" type="submit">Create Account</button> </form> <a class="block w-full text-center no-underline text-sm text-grey-dark hover:text-grey-darker" href="/login">Already have an account?</a> </div> </div>

Bada bing bada boom, we've got ourselves a good-looking mobile sign-up form! But, what happens when we take a look at this on a bigger screen?

Responsive Design

It's certainly better than our plain HTML, but it needs some work. Let's use some of the responsive state variants and style this for larger screens.

<div class="flex items-center h-screen w-full bg-teal-lighter"> <div class="w-full bg-white rounded shadow-lg p-8 m-4 md:max-w-sm md:mx-auto"> <h1 class="block w-full text-center text-grey-darkest mb-6">Sign Up</h1> <form class="mb-4 md:flex md:flex-wrap md:justify-between" action="/" method="post"> <div class="flex flex-col mb-4 md:w-1/2"> <label class="mb-2 uppercase tracking-wide font-bold text-lg text-grey-darkest" for="first_name">First Name</label> <input class="border py-2 px-3 text-grey-darkest md:mr-2" type="text" name="first_name" id="first_name"> </div> <div class="flex flex-col mb-4 md:w-1/2"> <label class="mb-2 uppercase font-bold text-lg text-grey-darkest md:ml-2" for="last_name">Last Name</label> <input class="border py-2 px-3 text-grey-darkest md:ml-2" type="text" name="last_name" id="last_name"> </div> <div class="flex flex-col mb-4 md:w-full"> <label class="mb-2 uppercase font-bold text-lg text-grey-darkest" for="email">Email</label> <input class="border py-2 px-3 text-grey-darkest" type="email" name="email" id="email"> </div> <div class="flex flex-col mb-6 md:w-full"> <label class="mb-2 uppercase font-bold text-lg text-grey-darkest" for="password">Password</label> <input class="border py-2 px-3 text-grey-darkest" type="password" name="password" id="password"> </div> <button class="block bg-teal hover:bg-teal-dark text-white uppercase text-lg mx-auto p-4 rounded" type="submit">Create Account</button> </form> <a class="block w-full text-center no-underline text-sm text-grey-dark hover:text-grey-darker" href="/login">Already have an account?</a> </div> </div>

Thanks to our responsive prefixes, our sign-up form is looking much better! Let's take a look at our <form> for some examples.

<form class="mb-4 md:flex md:flex-wrap md:justify-between" action="/" method="post"> <!-- ... --> </form>

Just like with our hover: prefix, we're only applying the prefixed classes when that condition is met. In this case, that means we're only applying the flex styles to our <form> when the page's min-width is 768px.

Extracting Utilities Into Components

Now that we've finished prototyping our form, we can extract our utility classes into component classes. Let's start by extracting our <input> classes.

<input class="border py-2 px-3 text-grey-darkest" type="password" name="password" id="password">

As we can see, our <input> has a couple of classes on it. We can extract these to our CSS using Tailwind's @apply directive. @apply allows us to apply the same styles that our utility classes use to a new class. So, at the bottom of our styles.css file, we can add the following:

.field { @apply .border .py-2 .px-3 .text-grey-darkest; }

Then, once we've re-complied our Tailwind files, our <input> can just have the .field class.

<input class="field" type="password" name="password" id="password">

As you can see, with Tailwind we get the best of utility and component classes! We can iterate quickly with utility classes, and still extract component classes when we start to see a pattern.

Even better, we can blend them to handle those one-off cases where dedicated component classes don't make sense.

The Final CSS

Applying this thinking to the rest of our code, our CSS and HTML will look like this.

@tailwind preflight; /* Here we can add any custom overrides */ @tailwind utilities; /* Here we can add our own utilities or custom CSS */ .field { @apply .border .py-2 .px-3 .text-grey-darkest; } .field-label { @apply .uppercase .font-bold .text-lg .text-grey-darkest .mb-2; } .field-group { @apply .flex .flex-col; } .btn { @apply .block .text-white .uppercase .text-lg .p-4 .rounded; } .btn-teal { @apply .bg-teal; } .btn-teal:hover { @apply .bg-teal-dark; } .link { @apply .block .no-underline .text-sm; } .link-grey { @apply .text-grey-dark; } .link-grey:hover { @apply .text-grey-darker; } The Final HTML <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Tailwind Intro</title> <link rel="stylesheet" href="main.css"> </head> <body> <div class="flex items-center h-screen w-full bg-teal-lighter"> <div class="w-full bg-white rounded shadow-lg p-8 m-4 md:max-w-sm md:mx-auto"> <h1 class="block w-full text-center text-grey-darkest mb-6">Sign Up</h1> <form class="mb-4 md:flex md:flex-wrap md:justify-between" action="/" method="post"> <div class="field-group mb-4 md:w-1/2"> <label class="field-label" for="first_name">First Name</label> <input class="field md:mr-2" type="text" name="first_name" id="first_name"> </div> <div class="field-group mb-4 md:w-1/2"> <label class="field-label md:ml-2" for="last_name">Last Name</label> <input class="field md:ml-2" type="text" name="last_name" id="last_name"> </div> <div class="field-group mb-4 md:w-full"> <label class="field-label" for="email">Email</label> <input class="field" type="email" name="email" id="email"> </div> <div class="field-group mb-6 md:w-full"> <label class="field-label" for="password">Password</label> <input class="field" type="password" name="password" id="password"> </div> <button class="btn btn-teal mx-auto" type="submit">Create Account</button> </form> <a class="link link-grey w-full text-center" href="/login">Already have an account?</a> </div> </div> </body> </html>

We've extracted our duplicate classes and left the rest. As we find ourselves building similar components, then we can extract more classes!

Wrap Up

Whew! We certainly covered a lot in this post. We started out stretching our HTML muscles by building a quick form, and then we took a mobile-first approach to our styles with Tailwind. Along the way, we saw how to use Tailwind's utility classes to quickly style an element. Then, we used state variants to add some dynamic styles. And finally, we saw how we could have our cake and eat too when we extracted our duplicate classes to component classes.

I hope that you were able to get a taste of how Tailwind can make an impact in your own projects. If you'd like to mess around with this project, feel free to clone the repo and experiment with Tailwind yourself. As always, feel free to ask me any questions on Twitter. And until next time, happy coding!

How to Style a Form With Tailwind CSS is a post from CSS-Tricks

Creating Vue.js Component Instances Programmatically

Tue, 01/23/2018 - 14:39

This article assumes basic understanding of Vue.js framework and how to create components in it. If you are new to Vue, then this CSS-Tricks series is a good place to start.

I have been on a Vue.js project that required the ability to create components programmatically. By programmatically, I mean you create and insert the components completely from JavaScript, without writing anything in the template. This article aims to illustrate how different aspects of using components in a template, such as instantiation, props passing, slots, mounting, translate to JavaScript code.

Normally if you are working with the recommended Single File Component style, you would have a Button component like so:

<template> <button :class="type"><slot /></button> </template> <script> export default { name: 'Button', props: [ 'type' ], } </script>

To use it in another component, all you have to do is import the Button component and insert its tag in the template:

<template> <Button type="primary">Click me!</Button> </template> <script> import Button from 'Button.vue' export default { name: 'App', components: { Button } } </script>

In my case, I don't know which component to insert in the template and also where to insert it. This information is only available at runtime. So I needed a way to dynamically create component instance for any passed component and insert it in the DOM, during runtime.

Creating the Instance

The very first idea I had to create a dynamic instance of a given component was to pass it to new and it would give me the actual instance. But if you notice carefully the script block in any of the above component code, they are all exporting a simple object, and not a class (constructor function). If I do this:

import Button from 'Button.vue' var instance = new Button()

...it fails. We need a class. Or, in simple terms, a constructor function. The way to do that is to pass the component object to Vue.extend to create a subclass of the Vue constructor. Now we can create an instance out of it with the new keyword:

import Button from 'Button.vue' import Vue from 'vue' var ComponentClass = Vue.extend(Button) var instance = new ComponentClass()

Hooray! Step 1 cleared! Now we need to insert it in the DOM.

Inserting in DOM

Every Vue instance has a method called $mount on it which mounts the component instance on the element you pass to it (i.e. it replaces the passed element with the component instance). This is not a behavior I wanted. I wanted to insert my component instances inside some DOM element. There is a way to do that too. From the official docs:

If elementOrSelector argument is not provided, the template will be rendered as an off-document element, and you will have to use native DOM API to insert it into the document yourself.

That’s what I did:

import Button from 'Button.vue' import Vue from 'vue' var ComponentClass = Vue.extend(Button) var instance = new ComponentClass() instance.$mount() // pass nothing this.$refs.container.appendChild(instance.$el)

There are a couple of things to note in the code above.

First, $refs is the recommended way to get reference to a DOM element in Vue.js. You specify an attribute on the DOM element you want to reference (<div ref="container"></div> in this case) and then that element is available on the set key on component's $refs property.

Second, to get the native DOM element reference from a Vue component instance, you can use the $el property.

Passing Props to the Instance

Next, I had to pass some props to my Button instance. Specifically, the type prop. The Vue constructor function accepts an options object that we can use to pass in and initialize related things. For passing props, there is a key called propsData which we can use, like so:

import Button from 'Button.vue' import Vue from 'vue' var ComponentClass = Vue.extend(Button) var instance = new ComponentClass({ propsData: { type: 'primary' } }) instance.$mount() // pass nothing this.$refs.container.appendChild(instance.$el)

We are almost done, with one final remaining bit. With the normal template method, we used button like: <Button>Click me!</Button>;. We simply wrote the inner text between the tags and it rendered inside the final button tag with the help of slot. But now how do we pass it?

Setting the Slot

If you have used slots in Vue.js, you might be aware that the slots are accessible on any instance on the $slots property. And if named slots are not used, then slots are available on $slots.default as an array. That is the exact key we'll modify on the instance to set our button's inner text. Remember, this needs to be done before mounting the instance. Note that in our case we just put a simple string in the slot because that is all we required. But you can pass more complex DOM to it in form for Virtual nodes or VNode using the createElement function. You can read about creating Virtual nodes in the Vue.js documentation. Thanks to a Vue core team member, Rahul, for suggesting this technique.

import Button from 'Button.vue' import Vue from 'vue' var ComponentClass = Vue.extend(Button) var instance = new ComponentClass({ propsData: { type: 'primary' } }) instance.$slots.default = [ 'Click me!' ] instance.$mount() // pass nothing this.$refs.container.appendChild(instance.$el) Final Demo

View Demo

Hope you liked this article. Follow me on Twitter where I share more articles and side projects of mine.

Creating Vue.js Component Instances Programmatically is a post from CSS-Tricks

Using CSS Clip Path to Create Interactive Effects

Mon, 01/22/2018 - 14:39

Do you remember being a kid, cutting out pictures from magazines? Did you glue them onto paper to create your own collages? This post is about cutting out images on the web using the CSS property clip-path. We will discuss how to do the cutting and how we can use these cut-out parts to create some interesting effects, combining these cut-out parts with the original image.

I’ll use the following photo as an example. The flower stands out from the rest of the photo. It is a natural focal point to cut out and create our effects around.

Image courtesy of Unsplash. Credit: Hermes Rivera Creating the SVG

First off, we are going to create a new SVG file and import our example image into it. You will need image editing software with vector capability to make the cut. I’m using Inkscape, a free open source editor, but you can apply the same method covered in this post using other applications such as Adobe Illustrator or even an online editor, like Vectr.

Let's start out by creating a new 100px square SVG document in the image editor. It’s important to use a 100px square because clipping paths come in length-percent. Choosing a 0-100 scale will allow for seamless conversion from pixel to percent.

One thing that I find very valuable before proceeding is to examine the SVG code output from the editor. Getting that output depends on the application. For example, there are two methods in Illustrator alone. Looking at the markup gives us insight into what the editor is doing behind the scenes because not all applications export SVG the same way. Seeing the code will increase your understanding of the markup. It’s a win-win.

The SVG output should give us something like this:

<svg … width="100px" height="100px" viewBox="0 0 100 100" …> ... </svg>

One of the more important parts of the above is the viewBox attribute because it represents the internal coordinate system of the SVG document. Here's a thorough explanation of how it works. Above, we can see that the document has the correct proportions where width, height and viewBox all span from 0 to 100.

Next up is importing the image. Here we'll want to resize the image to 100px square and place it at the origin (0, 0). Doing so might break the aspect ratio of your image, unless your image is already in a square proportion. Our example image is not. This will not be a problem when applying clip-path later on.

The image is temporarily rescaled to meet the new square proportion.

Looking at the generated code once again, we now should see the <image> tag inside the SVG document. Note the preserveAspectRatio is set to none. This tells us that the image’s original dimensions are being ignored.

<svg … width="100px" height="100px" viewBox=“0 0 100 100”> ... <image … y="0" x="0" xlink:href=".../image-file-name.jpg" preserveAspectRatio="none" height="100" width="100" … /> ... </svg> Masking the Image File

Now for the actual image cutting.

The concept of cutting images is called masking. If you are unfamiliar with masking it’s essentially drawing a closed shape with the pen tool around an area of the image. You don’t need to be savvy with a vector editor to do this. It doesn’t require any particular artistic skills and it can be done in a few basic steps.

Masking digital images is very much like cutting images out of real magazines. The path created in the vector editor is the same you'd follow using a pair of scissors. Select the pen tool and start drawing the outline of the part of the image that you want to cut out. In this case, it's the flower focal point we pointed out earlier. Create as many points you like along the way to shape the mask. Be sure to close the path as the last step.

It is important to only use cusp nodes when doing the cutting because clip-path does not support complex shapes, like Bezier curves at the time of this writing. It supports only simple shapes such as polygon, circle and ellipse.

If we view the SVG code now, the output will include a path with all the coordinates of the shape you drew. Here is an abbreviated example of my path's output:

... <path d="m 52.843605,79.860084 -0.69448,1.767767 -0.883884,0 -1.26269,-1.578364 -0.757615,0.06314 -1.388959,-2.714785 -0.12627,-2.967323 -1.704632,2.525381 -1.136422,-0.126269 -0.505076,-2.841054 -1.515229,1.325825 -1.325825,-0.126269 -0.252538,-1.578363 -0.947018,-0.126269 -0.252538,-0.315673 -0.947018,0.126269 -0.69448,-0.757614 0.126269,-1.641498 -0.441942,-0.252538 -0.189403,-2.588516 -0.505077,-0.06314 -1.010152,0.568211 -0.568211,-1.452094 0.441942,-2.399112 -1.325825,-0.126269 -0.378808,-1.262691 0.378808,-2.08344 0.883883,-1.641498 -1.010152,-1.26269 0.505076,-1.957171 -1.452094,-1.010152 -0.378808,-1.010153 1.136422,-2.209709 -2.209709,-0.378807 -0.441941,-1.704632 0.631345,-2.020305 1.704632,-1.38896 -1.578363,-1.452094 0.568211,-2.462247 0.820749,-0.441942 0.126269,-1.515229 0.757614,-1.073287 0.441942,-1.515228 -0.505076,-1.38896 0,-2.272843 0.505076,-1.010153 1.136422,-0.505076 1.325825,0 0.06313,-0.568211 -0.947018,-2.08344 0.378807,-0.631345 0,-0.441942 1.073288,-0.69448 1.073287,0 0.56821,0.315673 -0.189403,-2.525381 0.189403,-0.883884 0.378808,0.757615 0.06313,-0.883884 0.378807,-0.378807 0.189404,-0.378807 0.126269,-2.08344 0.315673,0.06314 0,-0.568211 0.378807,-0.06313 1.199556,0.568211 0.505076,0.69448 0.252538,-2.08344 0.631346,-0.505076 0.631345,-0.568211 0.441942,-0.505076 0.252538,0.505076 0,-0.883883 1.262691,0.315673 0.820749,-1.894036 1.325825,1.136421 1.073287,-1.452094 0.820749,0.189403 1.010152,1.515229 0.505077,0.757615 0.631345,-1.452095 0.820749,-0.56821 0.820749,0.505076 0.378807,0.631345 0.820749,-0.189403 0.820749,0.947018 0,0.252538 0.69448,-0.126269 0.378807,0.631345 0.820749,0 0.568211,1.515229 0.378807,1.325825 0.505076,-0.189404 0.252538,0.441942 0.378808,0.126269 0.441941,2.08344 0,0.568211 0.505077,-0.126269 0,0.883883 0.694479,-0.252538 0.505077,0.505076 0.252538,0.947018 0,0.883884 0.315673,0 0.378807,0.631345 0.441941,0.631345 0.06314,1.515229 -0.378807,1.957171 -0.441942,1.767767 2.904189,-1.136422 0.252538,0.631345 0.126269,2.209709 -0.883884,1.830902 1.38896,0.378807 1.010153,1.199556 -0.378808,1.641498 -0.947018,1.767767 -0.505076,0.378807 0.69448,1.767767 1.010153,1.26269 0.378807,1.38896 -0.378807,1.515229 -0.568211,0.315673 -0.505077,1.010152 -1.452094,0.883884 0.189404,1.325825 0.315672,0.883883 -0.378807,1.38896 -1.388959,1.073287 -0.505077,0.126269 0,0.505077 -0.189403,1.830901 -1.010153,0.631345 0.820749,2.209709 -0.631345,1.452094 -1.641498,-0.189403 0.126269,1.578363 -0.315673,1.641498 -1.073287,0.505076 -0.378807,0.315673 -0.378807,0.883883 -0.252538,1.010153 0.06313,2.714785 -0.631345,0.631345 -1.578364,-0.883883 -0.757614,-1.262691 -0.189404,2.462247 0.189404,2.083439 -0.252538,2.588516 -0.441942,1.894036 -0.631345,0.631346 -0.631345,-0.189404 -0.820749,-0.883883 z" /> ...

Below is a video of me cutting out the flower and the result. The cutting took me about two minutes and the result is pretty decent.

Here is my image with a slight opacity on the mask to show the final shape that was cut out:

Converting SVG to CSS Clip Path

Now that we have the mask let’s have a look at how we go from SVG to clip-path. This means converting the path descriptor, or the d attribute in the SVG code.

Before we look into how to do the conversion, let’s talk a bit about the reasons for using clipping paths. You might ask why we’re creating a clipping path at all? Why not mask the image in the vector editor and export a pre-cut image? It’s possible and using images is a lot more convenient than working with a huge chunks of CSS code. But there are two principal benefits of going with the clipping path as I see it: interactivity and compression. SVG is essentially code in the DOM that can be manipulated and it is a much smaller file size than a bitmap image of the same shape.

The syntax for CSS clipping paths is somewhat the reverse of what it is in SVG. Pairs are comma-separated and spaces separate coordinates. This is the complete opposite to the SVG descriptor syntax. To further complicate the conversion, some shapes only use absolute coordinates. SVG paths are more flexible as they can use both coordinate systems.

I’ve created a rudimentary Node script that converts SVG paths. It takes paths in relative coordinates and outputs corresponding polygons using CSS clip-path. It uses regex to parse SVG files. Feel free to fork it and enhance it. One obvious addition would be to add normalization of proportions. Adding normalization would eradicate the need to only use square images when creating masks.

Here is the result of applying the clip-path to the photo of the flower:

See the Pen Cutting out images by Mikael Ainalem (@ainalem) on CodePen.

Tricks Using CSS Clip Path

Now that we have the cut-out part let’s have a look what we can with it.

Overlay Effect

One quite neat trick is to stack the cut-out part on top of the original image. Below is a pen illustrating the idea of overlaying the cut-out part on top of the original image. It will give you an idea of the positioning and the two different parts involved. Having these two different elements gives us the possibility to apply separate effects on the foreground and the background respectively.

See the Pen Cutting out images #2 by Mikael Ainalem (@ainalem) on CodePen.

Highlighting Effect

Highlighting parts on an image is not just visually appealing. It can also have a real impact on the user experience of your site. It isn’t hard to come up with useful scenarios where you might like to highlight parts of an image in a web page. Highlighting tagged people in a photo could be one use-case. Another could be to highlight certain features of a product in a product showcase. A third case could be a photo of a map, in which you would like to highlight places to do some storytelling around. Highlighting or emphasizing parts of the UI can when properly applied be powerful UX pattern. Using clipping paths is one way to achieve highlights in your UI.

Going back to the photo of the flower we can now easily make the flower stand out. One way to achieve this is to tone down the background behind the flower by lowering its opacity:

See the Pen Cutting out images #3 by Mikael Ainalem (@ainalem) on CodePen.

An interesting note is that the browser will hit-test the mask. Thus, to make it a bit more playful, we can trigger the highlight effect when the user hovers the flower. One way to do this is to add JavaScript event handlers (addEventListener) and attach them to the masked element. Setting these handlers to trigger on events like mouseenter and mouseout captures the user hovering the flower. We can even toggle classes on the background element to trigger the effect. A CSS opacity transition is essentially what’s needed.

See the Pen Cutting out images #4 by Mikael Ainalem (@ainalem) on CodePen.

There is nothing that prevents us from reusing the above technique several times in the same image. Here’s an example of highlighting many people in a photo. In this case there are several overlaid cut-outs:

See the Pen clip-path highlight by Mikael Ainalem (@ainalem) on CodePen.

Fading and Blurring Effects

An effect that we’ve been seeing more in the last year is blurred backgrounds. It’s kind of a reverse way to enhance foreground elements. Rather than enhancing the foreground element itself one can create the same effect by blurring background elements. This way of enhancing foreground elements has another pleasant side-effect: the element in your current focal point remains untouched. But, at the same time, it becomes more prominent.

The easiest way to achieve a blur effect is to use the CSS filter blur. The following pen uses the same JavaScript callback method as the previous example to trigger the effect on hover. Instead of toning down the background, it is blurred with a CSS filter transition.

See the Pen Cutting out images #9 by Mikael Ainalem (@ainalem) on CodePen.

Having a transition using the CSS filter, however, is very costly in terms of performance. This has to do with the shader running on the GPU used to create the blur effect. Animating the CSS blur filter is generally not a good idea. A more performant option is to reuse pre-filtered version of the image and use a cross-fade. In other words, we animate the opacity of a duplicated background image instead of animating the blur. Here is what that looks like:

See the Pen Cutting out images #10 by Mikael Ainalem (@ainalem) on CodePen.

Outline

Another option to reinforce the cut-out element is to use an outline effect. Reusing the mask is an easy way to make it. If we insert the SVG in between the two main elements and add a slight scale (1.04 in this case), we’ll make it appear as an outline.

See the Pen Cutting out images #5 by Mikael Ainalem (@ainalem) on CodePen.

Of course, we can also trigger the outline on hover like we did in the other examples:

See the Pen Cutting out images #6 by Mikael Ainalem (@ainalem) on CodePen.

The edges of the mask are a bit rough as the mask is binary. One option to soften the edges is to add an SVG filter. Here is an example:

See the Pen Cutting out images #8 by Mikael Ainalem (@ainalem) on CodePen.

Cutting Holes

What if the part you want to cut out has holes in it? What if it shows parts of the background that you would like to exclude?

For instance, imagine you want to cut out a donut. Then you want the mask to exclude the hole in the middle. How do you then cut out the mask? The clip-path specification doesn’t allow more than one polygon unless we use SVGs. This means there is no possible way to create more than one shape at a time.

Well, one way to create these holes is to use very thin connectors and draw it as one shape. In other words, we can make a very thin incision from the edge and cut out the hole. This pen illustrates what it looks like when we make these connectors very thin:

See the Pen Cutting out images #7 by Mikael Ainalem (@ainalem) on CodePen.

Morphing Clip Paths

To make the highlight effect even more playful we can actually morph the clip-path itself. Below is an example of creating a dynamic highlight of a butterfly in three shots. The highlight is morphed between the three different cut-out parts on hover.

See the Pen Cutting out images #11 by Mikael Ainalem (@ainalem) on CodePen.

Double Exposure Effect

Another interesting effect we can create with clip-path is a double exposure. Here are two images blend in the same mask.

See the Pen Double exposure by Mikael Ainalem (@ainalem) on CodePen.

Browser support

So, can clip-path be used in all browsers? Unfortunately, not at the moment! If we look the caniuse table it kinda looks a bit like a traffic light at the time of this writing.

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

DesktopChromeOperaFirefoxIEEdgeSafari665154NoNoTP*Mobile / TabletiOS SafariOpera MobileOpera MiniAndroidAndroid ChromeAndroid Firefox11.0-11.2*37*No626257 Wrapping it Up

Some key points I hope you walk away with from this post:

  • Using clipping paths is one way to make parts of your images stand out
  • Stacking the cut-out part on top of the original image makes it possible to create different kinds of highlight effects in images
  • We can leverage the browser’s hit testing on masks to create interactive effects on cut-out parts
  • The clip-path property makes way for UX patterns that highlight and create effects around parts of your images
Acknowledgments
  • Inkscape for vector image editing
  • Unsplash for the royalty-free images used in the examples
  • Github for the repository used for the conversion script
  • npm for being the package mnager for the conversion script
  • caniuse for browser support reference
  • CodePen for hosting the demos used in this post

Using CSS Clip Path to Create Interactive Effects is a post from CSS-Tricks

2017/2018 JavaScript

Fri, 01/19/2018 - 23:46

There has been a lot of research on the landscape this year! Here are a few snippets from a bunch of articles. There is a ton of information in each, so I'm just picking out a few juicy quotes from each here.

Perhaps the most interesting bit is how different the data looked at is. Each of these is different: a big developer survey, npm data, GitHub data, and StackOverflow data. Yet, they mostly tell the same stories.

The Brutal Lifecycle of JavaScript Frameworks

Ian Allen of StackOverflow writes:

JavaScript UI frameworks and libraries work in cycles. Every six months or so, a new one pops up, claiming that it has revolutionized UI development. Thousands of developers adopt it into their new projects, blog posts are written, Stack Overflow questions are asked and answered, and then a newer (and even more revolutionary) framework pops up to usurp the throne.

Using the Stack Overflow Trends tool and some of our internal traffic data, we decided to take a look at some of the more prominent UI frameworks: Angular, React, Vue.js, Backbone, Knockout, and Ember.

Read More

The Top JavaScript Trends to Watch in 2018

Ryan Chartrand of X-Team for Hackernoon writes:

This time last year, not many had faith that Vue would ever become a big competitor to React when it comes to major companies adopting it, but it was impossible to ignore Vue this year, even sending Angular a bit into the shadows in terms of developer hype.

Read More

The State of JavaScript 2017

Sacha Greif uses a survey rather than usage data:

We asked over a hundred questions to more than 28,000 developers all over the world, covering topics going from front-end libraries all the way to back-end frameworks.

I particularly enjoyed the opinions. Lots of people who love working with JavaScript and find it to be moving in the right direction and find it overly complex.

Read More

The State of JavaScript Frameworks, 2017

This one is from Laurie Voss of npm, which is probably the best source of data for usage but faces interesting challenges with that data:

You can use npm’s download statistics to give you insight into the amount of people actively invested in using and maintaining a package. However, probably more important than absolute popularity is growth.

Packages, once incorporated into software, have very long lives. People very seldom rip packages out of software once they’re installed. Because of this very low “churn,” packages hardly ever decline in usage. Furthermore, nearly all packages in the npm Registry grow in usage as the number of total npm users continues to skyrocket. They vary only in how fast they’re growing.

This makes measuring growth harder, since measuring absolute growth in downloads all the time makes almost everything look popular.

All in all it tells a familiar story: React is incredibly popular and Vue is the one to watch.

Read More

Top JavaScript Libraries & Tech to Learn in 2018

Eric Elliott writes:

Vue.js did do very well in 2017. It got a lot of headlines and a lot of people got interested. As I predicted, it did not come close to unseating React, and I’m confident to predict it won’t unseat React in 2018, either. That said, it could overtake Angular in 2018.

Read More

2017 JavaScript Rising Stars

Michael Rambeau's writes:

Once again, Vue.js is the trendiest project of the year, with more than 40,000 stars added on GitHub during the year.

It's far more than in 2016 (26,000 stars), and the gap with the next contender (React) is even bigger.

Read More

2017/2018 JavaScript is a post from CSS-Tricks

Secure Contexts Everywhere

Fri, 01/19/2018 - 18:55

Anne van Kesteren for Mozilla says:

Effective immediately, all new features that are web-exposed are to be restricted to secure contexts. Web-exposed means that the feature is observable from a web page or server, whether through JavaScript, CSS, HTTP, media formats, etc. A feature can be anything from an extension of an existing IDL-defined object, a new CSS property, a new HTTP response header, to bigger features such as WebVR. In contrast, a new CSS color keyword would likely not be restricted to secure contexts.

In other words, if your site isn't HTTPS, you won't get new web tech features. Holy jeepers. The reasoning is the web should be using HTTPS, so this is our way of beating you with a stick if you try to use fancy features without going HTTPS first.

It'll be fascinating to watch the first major feature drop and if they stick to their word here. The web dev forums of the internet will overflow with WHY DOESN'T grid-gap WORK WITH MY FLEXBOX? (or some likely coming-soon feature) questions and the answer will be: talk to your server team. What if they drop container queries behind this? That would be a hilarious devastating tornado of developer fury.

Direct Link to ArticlePermalink

Secure Contexts Everywhere is a post from CSS-Tricks

Creating a Vue.js Serverless Checkout Form: Configure the Checkout Component

Fri, 01/19/2018 - 15:54

This is the fourth post in a four-part series. In Part one, we set up a serverless Stripe function on Azure. Part two covered how we hosted the function on Github. The third part covered Stripe Elements in Vue. This last post shows how to configure the checkout component and make the shopping cart fully functional.

Article Series:
  1. Setup and Testing
  2. Stripe Function and Hosting
  3. Application and Checkout Component
  4. Configure the Checkout Component (This Post)

As a reminder, here's where we are in our application at this point:

Configuring the Checkout Component

We have to do a few things to adjust the component in order for it to meet our needs:

  • Make sure the form is only displaying if we haven't submitted it—we'll deal with the logic for this in our pay method in a moment
  • Allow the form to take a customer's email address in case something is wrong with the order.
  • Disable the submit button until the required email address is provided
  • Finally and most importantly, change to our testing key

Here's our updated checkout component with the changes to the original code highlighted:

<div v-if="!submitted" class="payment"> <h3>Please enter your payment details:</h3> <label for="email">Email</label> <input id="email" type="email" v-model="stripeEmail" placeholder="name@example.com"/> <label for="card">Credit Card</label> <p>Test using this credit card: <span class="cc-number">4242 4242 4242 4242</span>, and enter any 5 digits for the zip code</p> <card class='stripe-card' id="card" :class='{ complete }' stripe='pk_test_5ThYi0UvX3xwoNdgxxxTxxrG' :options='stripeOptions' @change='complete = $event.complete' /> <button class='pay-with-stripe' @click='pay' :disabled='!complete || !stripeEmail'>Pay with credit card</button> </div>

There are a number of things we need to store and use for this component, so let's add them to data or bring them in as props. The props that we need from our parent component will be total and success. We'll need the total amount of the purchase so we can send it to Stripe, and the success will be something we need to coordinate between this component and the parent, because both components need to know if the payment was successful. I write out the datatypes as well as a default for my props.

props: { total: { type: [Number, String], default: '50.00' }, success: { type: Boolean, default: false } },

Next, the data we need to store will be the stripeEmail we collected from the form, stripeOptions that I left in to show you can configure some options for your form, as well as status and response that we'll get from communicating with the server and Stripe. We also want to hold whether or not the form was submitted, and whether the form was completed for enabling and disabling the submit button, which can both be booleans.

data() { return { submitted: false, complete: false, status: '', response: '', stripeOptions: { // you can configure that cc element. I liked the default, but you can // see https://stripe.com/docs/stripe.js#element-options for details }, stripeEmail: '' }; },

Now for the magic! We have everything we need—we just need to alter our pay() method, which will do all the heavy lifting for us. I'm going to use Axios for this, which will receive and transform the data:

npm i axios --save

...or using Yarn:

yarn add axios

If you're not familiar with Axios and what it does, check out this article for some background information.

pay() { createToken().then(data => { this.submitted = true; // we'll change the flag to let ourselves know it was submitted console.log(data.token); // this is a token we would use for the stripeToken below axios .post( 'https://sdras-stripe.azurewebsites.net/api/charge?code=zWwbn6LLqMxuyvwbWpTFXdRxFd7a27KCRCEseL7zEqbM9ijAgj1c1w==', { stripeEmail: this.stripeEmail, // send the email stripeToken: data.token.id, // testing token stripeAmt: this.total // send the amount }, { headers: { 'Content-Type': 'application/json' } } ) .then(response => { this.status = 'success'; this.$emit('successSubmit'); this.$store.commit('clearCartCount'); // console logs for you :) this.response = JSON.stringify(response, null, 2); console.log(this.response); }) .catch(error => { this.status = 'failure'; // console logs for you :) this.response = 'Error: ' + JSON.stringify(error, null, 2); console.log(this.response); }); }); },

The code above does a number of things:

  • It allows us to track whether we've submitted the form or not, with this.submitted
  • It uses Axios to post to our function. We got this URL from going to where the function lives in the portal, and clicking "Get Function URL" on the right side of the screen.
  • It sends the email, token, and total to the serverless function
  • If it's successful, it changes the status to success, commits to our Vuex store, uses a mutation to clear our cart, and emits to the parent cart component that the payment was successful. It also logs the response to the console, though this is for educational purposes and should be deleted in production.
  • If it errors, it changes the status to failure, and logs the error response for help with debugging

If the payment fails, which we'll know from our status, we need to let the user know something went wrong, clear our cart, and allow them to try again. In our template:

<div v-if="status === 'failure'"> <h3>Oh No!</h3> <p>Something went wrong!</p> <button @click="clearCheckout">Please try again</button> </div>

The button executes the following clearCheckout method that clears a number of the fields and allow the customer to try again:

clearCheckout() { this.submitted = false; this.status = ''; this.complete = false; this.response = ''; }

If the payment succeeds, we will show a loading component, that will play an SVG animation until we hear back from the server. Sometimes this can take a couple of seconds, so it's important that our animation make sense if it is seen for a short or long amount of time, and can loop as necessary.

<div v-else class="loadcontain"> <h4>Please hold, we're filling up your cart with goodies</h4> <app-loader /> </div>

Here's what that looks like:

See the Pen shop loader by Sarah Drasner (@sdras) on CodePen.

Now if we revisit the first cart component we looked at in pages/cart.vue, we can fill that page based on the logic we set up before because it's been completed:

<div v-if="cartTotal > 0"> <h1>Cart</h1> ... <app-checkout :total="total" @successSubmit="success = true"></app-checkout> </div> <div v-else-if="cartTotal === 0 && success === false" class="empty"> <h1>Cart</h1> <h3>Your cart is empty.</h3> <nuxt-link exact to="/"><button>Fill 'er up!</button></nuxt-link> </div> <div v-else> <app-success @restartCart="success = false"/> <h2>Success!</h2> <p>Your order has been processed, it will be delivered shortly.</p> </div>

If we have items in our cart, we show the cart. If the cart is empty and the success is false, we'll let them know that their cart is empty. Otherwise, if the checkout has just been processed, we'll let them know that everything has been executed successfully!

We are now here:

In the AppSuccess.vue component, we have a small SVG animation designed to make them feel good about the purchase:

See the Pen success by Sarah Drasner (@sdras) on CodePen.

(You may have to hit "Rerun" to replay the animation.)

We also put a small timer in the mounted() lifecycle hook:

window.setTimeout(() => this.$emit('restartCart'), 3000);

This will show the success for three seconds while they read it then kick off the restartCart that was shown in the component above. This allows us to reset the cart in case they would like to continue shopping.

Conclusion

You learned how to make a serverless function, host it on Github, add required dependencies, communicate with Stripe, set up a Shopping Cart in a Vue application, establish a connection with the serverless function and Stripe, and handle the logic for all of the cart states. Whew, way to go!

It's worth mentioning that the demo app we looked at is a sample application built for specifically for this purpose of this tutorial. There are a number of steps you'd want to go through for a production site, including testing, building the app's dist folder, and using real Stripe keys. There are also so many ways to set this up, Serverless functions can be so flexible in tandem with something like Vue. Hopefully this gets you on track and saves you time as you try it out yourself.

Creating a Vue.js Serverless Checkout Form: Configure the Checkout Component is a post from CSS-Tricks

The Ultimate Guide to Headless CMS

Thu, 01/18/2018 - 21:26

(This is a sponsored post.)

The World Has Changed—So Must the CMS

Having a responsive website is no longer enough. Your audience expects a seamless and personalized customer experience across all their devices—the age of headless technology is coming.

Headless CMS is the next generation in content management for brands that want to stay ahead of the curve by engaging customers through the growing number of channels.

Download The Ultimate Guide to Headless CMS ebook for a deep look into what headless CMS is, and why it should be at the top of your list when choosing a new CMS.

Download the ebook now!

Direct Link to ArticlePermalink

The Ultimate Guide to Headless CMS is a post from CSS-Tricks

Get Ready for `display: contents;`

Thu, 01/18/2018 - 19:24

Last year I asked, "Will we be flattening our HTML for CSS Grids?"

The issue is that the only way for elements to participate in the same CSS grid together (or flexbox for that matter) is for them to be siblings. So, in some cases we might be incentivized to forego HTML semantics for the benefit of layout (not great).

One answer to this is display: contents;—a magical new display value that essentially makes the container disappear, making the child elements children of the element the next level up in the DOM.

Fast forward to today, Chrome is shipping it, WebKit is shipping it, and Firefox has shipped it. Vote for it in Edge here.

Wanna understand it better? Rachel Andrew wrote "Vanishing boxes with display contents" and clarifies how it all works:

This value becomes useful if you want to add some element because it makes sense in terms of document semantics, but doesn’t in terms of display. Perhaps you have some content that makes sense marked up as an article, that article is then a flex item in your layout BUT the elements you really would like to be flex items are nested inside that article. Rather than flattening your markup and remove the article element to enable these inner elements to be part of the flex layout, you could remove the boxes generated by article using display: contents. You then get the best of both worlds, semantic markup plus the visual display your design requires. That sounds good to me.

Manuel Rego takes a stab at explaining it as well:

display: contents makes that the div doesn’t generate any box, so its background, border and padding are not rendered. However the inherited properties like color and font have effect on the child (span element) as expected.

There is also a very related subject to all this: subgrids. Probably literally display: subgrid;. It's probably less important in terms of maintaining semantics than display: contents; but also different.

Eric Meyer called subgrids essential:

Grid layout is the first serious candidate to fill that hole in the past two decades, and I don’t want to see them hamstrung from the outset. Subgrids are essential to the adoption of grids. I hope they’ll be implemented as soon as possible

And to understand the difference, Rachel Andrew also wrote "Why display: contents is not CSS Grid Layout subgrid":

You won’t get far through a conversation about subgrid in CSS Grid Layout without someone suggesting that display: contents solves most of the problems anyway, so do we really need subgrid? This really isn’t the case, display: contents does indeed solve a class of problems, but these are different problems to those that subgrid would help us with.

Get Ready for `display: contents;` is a post from CSS-Tricks

Creating a Vue.js Serverless Checkout Form: Application and Checkout Component

Thu, 01/18/2018 - 15:07

This is the third post in a four-part series. In part one, we set up a serverless Stripe function on Azure. Part two covered how we hosted the function on Github. This post will focus on wiring everything up as a Vue.js application.

Article Series:
  1. Setup and Testing
  2. Stripe Function and Hosting
  3. Application and Checkout Component (This Post)
  4. Configure the Checkout Component (Coming Soon)

Stripe has a number of ways to build out a checkout form, the most basic being a single button on the page that you trigger to pull up their custom modal. There’s a repo and component for this, but as easy as that is to implement (it's probably the most simple way to do it), I wanted a little more customization and wanted the checkout flow to be part of the page and application. This approach wouldn’t work for my needs.

Stripe Elements

Stripe also offers a thing called Elements. Elements allow you to integrate Stripe's payment system into your own checkout form and style it like your own site for a cohesive experience. It won't feel like you're using a third party plugin. They do have some pre-styled examples if you prefer something you can use right out of the box.

Luckily for us, there's a really nice repo with a Vue version of Stripe Elements called vue-stripe-elements. The repo's documentation is really nice, so you could check that out. Here's how I put it to use:

npm i vue-stripe-elements-plus --save

...or using Yarn:

yarn add vue-stripe-elements-plus

Now let's talk about our cart and integrate it.

The Cart

Here's what everything looks like as a birds eye view of the application. We've already addressed the function and stripe pieces, now let's dig into the application itself.

We're not going to go through setting up the entire application in these posts, rather just the Cart and Checkout. I'd suggest checking out the following links before continuing if you need to catch up on the basics of Vue, Vuex, and Nuxt:

In our general store set up with Vuex, we hold a manifest of all of our product data used to populate the pages with items. We'll also use that information to populate a (currently empty) cart object where items can be added for purchase. We'll use that data on a page called `Cart.vue` in the pages directory. If you're unfamiliar with Nuxt.js, it allows us to use .vue components as pages by creating them in this pages directory. We can still populate these pages with components from the components directory to create a more modular application. Here are the parts we're discussing now:

We'll need two pieces of information from that store in Vuex: the contents of the cart and the cartTotal.

We'll use computed properties in pages/Cart.vue to fetch that information so that we can cache and use them in the cart.

computed: { cart() { return this.$store.state.cart; }, cartTotal() { return this.$store.state.cartTotal; }, ... }

...and we'll create a new computed property that will store the monetary total of the items in the cart as well:

computed: { ... total() { return Object.values(this.cart) .reduce((acc, el) => acc + (el.count * el.price), 0) .toFixed(2); } }

The first thing that we'll do is see if the cart has items in it. If it does, then we need to check that the payment hasn't already been processed. We need to do this because there's no need to display a checkout form if there are no items in the cart or if payment has already been processed for the items that were added.

<div v-if="cartTotal > 0"> <!--we'll add our checkout here--> </div> <!--If the cart is empty, give them the ability to get back to the main page to add items--> <div v-else-if="cartTotal === 0 && success === false" class="empty"> <!--we'll add our empty state here--> </div> <!--If there's a success, let's let people know it's being processed, we'll add a success component later on--> <div v-else> <!--we'll add success here--> </div>

We'll also create a success property in our data that we'll initially set to false and use later to record whether or not a payment was successfully submitted.

data() { return { success: false }; },

We want to show cart items if they exist, their individual totals (as we can have multiple counts of the same item) and the final total.

<div v-if="cartTotal > 0"> <h1>Cart</h1> <div class="cartitems" v-for="item in cart" key="item"> <div class="carttext"> <h4>{{ item.name }}</h4> <p>{{ item.price | usdollar }} x {{ item.count }}</p> <p>Total for this item: <strong>{{ item.price * item.count }}</strong></p> </div> <img class="cartimg" :src="`/${item.img}`" :alt="`Image of ${item.name}`"> </div> <div class="total"> <h3>Total: {{ total | usdollar }}</h3> </div> <!--we're going to add our checkout here--> </div>

We're using a filter to format the prices in US dollars. I format them this way instead of hardcoding them in case I need to support other currencies in the future.

filters: { usdollar: function(value) { return `$${value}`; } } Setting up the Checkout Component

Now we're going to create our checkout component, which will hold all of the Stripe checkout logic and connect to the serverless function we set up in Part Two. We'll register the component in the Cart.vue file:

import AppCheckout from './../components/AppCheckout.vue'; export default { components: { AppCheckout }, ... }

Here's where we're at now:

And, in the checkout component itself, we'll bring over the base for the file that we saw in the vue-stripe-elements repo documentation:

<template> <div id='app'> <h1>Please give us your payment details:</h1> <card class='stripe-card' :class='{ complete }' stripe='pk_test_XXXXXXXXXXXXXXXXXXXXXXXX' :options='stripeOptions' @change='complete = $event.complete' /> <button class='pay-with-stripe' @click='pay' :disabled='!complete'>Pay with credit card</button> </div> </template> <script> import { stripeKey, stripeOptions } from './stripeConfig.json' import { Card, createToken } from 'vue-stripe-elements-plus' export default { data () { return { complete: false, stripeOptions: { // see https://stripe.com/docs/stripe.js#element-options for details } } }, components: { Card }, methods: { pay () { // createToken returns a Promise which resolves in a result object with // either a token or an error key. // See https://stripe.com/docs/api#tokens for the token object. // See https://stripe.com/docs/api#errors for the error object. // More general https://stripe.com/docs/stripe.js#stripe-create-token. createToken().then(data => console.log(data.token)) } } } </script> Next Up...

So far, this is what the component looks like out of the box. We're going to have to update this component a bit to fit our needs, but not too much. Stay tuned tomorrow for the final installment when we connect our component to our serverless function and finish up the checkout!

Article Series:
  1. Setup and Testing
  2. Stripe Function and Hosting
  3. Application and Checkout Component (This Post)
  4. Configure the Checkout Component (Coming Soon)

Creating a Vue.js Serverless Checkout Form: Application and Checkout Component is a post from CSS-Tricks

Creating a Vue.js Serverless Checkout Form: Stripe Function and Hosting

Wed, 01/17/2018 - 14:44

We're now in the second post of a four-part series where we're creating a checkout form application in Vue.js that can accept payments via the Stripe API. In part one, we looked at the concept of serverless functions, set one up in Azure, and connected it to a Stripe account. In this post, we'll focus on setting up Stripe as a serverless function and hosting it all on Github.

Article Series:
  1. Setup and Testing
  2. Stripe Function and Hosting (This Post)
  3. Application and Checkout Component (Coming Soon)
  4. Configure the Checkout Component (Coming Soon)

First, we’re going write our function and test it out in the portal, but eventually we’re going to move it over to Github and have Azure pull in the code. I’ll explain why we do this in a moment.

For now, in order to get it working and testable, we’re going to write it in the portal and fill in the request body to perform the test. But we need to know what Stripe will expect from us first.

Dun dun dun...

Working With Stripe as a Serverless Function

If you check out Stripe's documentation, you can see that we’ll need to grab the Stripe token in the dashboard. This will eventually mirror the POST parameters submitted by our form. Stripe makes it easy, so it's fairly straightforward to use their library for the server-side function with Express:

app.get('/', (req, res) => res.render('index.pug', { keyPublishable })); app.post('/charge', (req, res) => { let amount = 500; stripe.customers .create({ email: req.body.stripeEmail, source: req.body.stripeToken }) .then(customer => stripe.charges.create({ amount, description: 'Sample Charge', currency: 'usd', customer: customer.id }) ) .then(charge => res.render('charge.pug')); }); app.listen(4567);

We won’t need to set up all of Node and Express for this, though, as what we really need is the amount, the currency, the description, and the token, which we can integrate with the testing code we were provided earlier in the portal's view of our function. So, let’s head over to the Azure portal where our function lives and update that default testing code to accept the parameters we need for Stripe, and also populate the request.body in the test panel.

We’ll add our Stripe testing key and kick everything off. To be totally sure, we’re going to log what we’ve gotten started:

var stripe = require('stripe')('sk_test_whateveryourtestingkeyisgoeshere'); // ^ this is a stripe testing key module.exports = function(context, req) { context.log('starting to get down');

If we have a request body, an email, and a token, then let's get started. We’ll create a customer from the email and then use that customer to create the Stripe charges, passing in the amount of the charge as we do so.

if ( req.body && req.body.stripeEmail && req.body.stripeToken && req.body.stripeAmt ){ stripe.customers .create({ email: req.body.stripeEmail, source: req.body.stripeToken }) .then(customer => { context.log('starting the stripe charges'); stripe.charges.create({ amount: req.body.stripeAmt, description: 'Sample Charge', currency: 'usd', customer: customer.id }); }) ...

We also want to test if this all completed successfully, or if it errored out. If it did error, we need to log what that error is. We’ll also see if the whole thing errored entirely, making sure we’re logging everything appropriately along the way.

You'll note that I log a lot. I think it's not enough to know that something has errored. I want to know when the error happened and why so that I can track it down. This makes it much easier to debug if something were to go wrong.

... .then(charge => { context.log('finished the stripe charges'); context.res = { // status: 200 body: 'This has been completed' }; context.done(); }) .catch(err => { context.log(err); context.done(); }); } else { context.log(req.body); context.res = { status: 400, body: "We're missing something" }; context.done(); } };

In the testing area on the right side of the portal, we’ll fill the request.body with the stripeEmail, stripeToken (a testing token in this case), and some random amount for the charge. When we run this, we can see that it works! We get a 200 OK Status, and we’ve logged This has been completed in the output.

Testing the request body parameters with the actual function in Azure. Github-Hosted Serverless Function

Let's put everything in Github now that it's working. One big reason we want to do this is because our function will have a dependency on Stripe’s library. If you head over to the sample-stripe-handler repo I’ve created for this tutorial, you’ll see a package.json file. The most important lines in that file are these:

"dependencies": { "stripe": "^5.3.0" }

This tells the function to pull in the correct version of the Stripe API that we need to use in order for our app to properly function. As a note, you could also use this method to write other kinds of functions using other libraries. This means the possibilities for what to create are endless!

We'll pull everything from our function into this repo. This includes the function itself, the package.json file, as well as the contents of the function.json file that you'll see in the "View Files" tab on the right in the Azure portal.

Once we have that all in ready to go in a Github repo, we'll head back over to the Azure portal, because now we have to let Azure know that we'd like to use this repo to host our function instead of our test. We can still test our function inside the portal—we just won't be able to edit it via the GUI anymore.

Click on the “Platform Features” tab and select the “Deployment Options” item.

From here, click "Settings" then "Choose source" and a number of options will be provided. I’m going to choose Github because that’s where I want to host mine, but you can see that there are a lot of other ways we could have done this.

Deployment settings source options, including Github.

Once Github has been selected, you will be able to configure which repo you would like to use as your deployment source. I chose the sample-stripe-handler repo that we created earlier.

Configuring Github as the deployment source.

After we’ve done this and it’s loaded, you’ll be taken to a "Deployments" screen that shows the last commit that you made to the repo. That means everything’s working correctly!

Let’s test this a little further. My function didn’t work properly the first time because I was using ES6. I could have added in Babel, but I just converted it back to ES5 and pushed to the master branch. You can see the function.json becomes inactive as the last deployment, and my latest commit message—which is mostly me grumbling—is now the latest deploy! Awesome.

We can't be too careful so, to check that these tests did indeed work, I’m going to head over to the Stripe dashboard. Sure enough, there are testing charges showing up in our dashboard &#x1f600;

One last thing!

We would be remiss to exclude our good friend CORS, which we need to properly enable for everything to communicate as it should. Let's go to our function in the dashboard, and select CORS:

In the prompt that appears, we'll whitelist our localhost dev server, as well as our final URL for the site. Voila! We're all set.

Next Up...

We got a lot done in this post! Next, we'll want to learn how to move away from testing only within the function and get this sucker communicating freely with a checkout experience that we’ll build within a Vue.js application. Stay tuned!

Article Series:
  1. Setup and Testing
  2. Stripe Function and Hosting (This Post)
  3. Application and Checkout Component (Coming Soon)
  4. Configure the Checkout Component (Coming Soon)

Creating a Vue.js Serverless Checkout Form: Stripe Function and Hosting is a post from CSS-Tricks

“Stop Using CSS Selectors for Non-CSS”

Tue, 01/16/2018 - 22:14

I saw Nicole Dominguez tweet this the other day:

say it louder for the people in the backhttps://t.co/prDKo5QaZi

— nicole (@sodevious) January 11, 2018

I wasn't at this conference, so I have very little context. Normally, I'd consider it a sin to weigh in on a subject brought up by looking at two out-of-context slides, but I'm only weighing in out of interest and to continue the conversation.

The idea seems to be that if you need to select an element in the DOM with JavaScript, don't use the same selector as you would in CSS.

So if you have...

<article class="article"> </article>

...and you need to apply an event listener to that article for some reason, then don't use...

$(".article")

(or querySelector or whatever, I assume.)

Instead, apply an attribute intended just for the JavaScript to target, like...

<article class="article" data-hoverable> </article>

...and target that like...

$("[data-hoverable]")

The idea is that you can separate jobs. The class has the job of styling, and the data attribute has the job of JavaScripting. Both can change without affecting each other.

Seems reasonable to me.

Also seems like there is plenty to talk about here. Performance, I suppose, but that's probably the least-interesting thing since selectors are generally pretty damn fast these days. We could continue the conversation by talking about:

  • What naming convention?
  • Should you be naming events?
  • What if it needs to be selected for different reasons multiple times?
  • Can you or should you use IDs?
  • Is it worth avoiding DOM selection at all if you can?
  • What other nuances are part of this discussion?

I saw Michael Scharnagl had some thoughts on his own usage of ID's, classes, and data-attributes that could help frame things a bit.

“Stop Using CSS Selectors for Non-CSS” is a post from CSS-Tricks

Creating a Vue.js Serverless Checkout Form: Setup and Testing

Tue, 01/16/2018 - 15:19

There comes a time in any young app’s life when it will have to monetize. There are a number of ways to become profitable, but accepting cash is a surefire way to make this more direct. In this four-part tutorial, we’ll go over how to set up a serverless function, make it talk to the Stripe API, and connect it to a checkout form that is setup as a Vue application. This may sound daunting, but it’s actually pretty straightforward! Let's dig in.

Article Series:
  1. Setup and Testing (This Post)
  2. Stripe Function and Hosting (Coming Soon)
  3. Application and Checkout Component (Coming Soon)
  4. Configure the Checkout Component (Coming Soon)
What is Serverless?

We’ve covered serverless concepts before but, in case you haven’t read that article, let’s talk for a minute about what we mean by "serverless” because it’s a bit of a misnomer.

The promise of serverless is to spend less time setting up and maintaining a server. You're essentially letting the service handle maintenance and scaling for you, and you boil what you need down to functions that run certain code when a request is made. For this reason, people may refer to this as FaaS. This is really useful because you pay for what you use, rather than a large container that you might not need in its entirety. You also primarily hunker down and focus just on the code you need to run instead of babysitting a server, which really appeals to a lot of people who’d like to get up and running quickly.

But FaaS isn't always the right tool for the job. It's really useful for small executions but, if you have processes that might hold up resources or a ton of computation, being able to communicate with a server as you normally do might be more efficient.

What we’re going to make is a perfect use case for going serverless. Stripe checkouts are pretty seamless to integrate on both the client and server side, but we do actually need to execute some logic on the server, so we’ll use Azure to help us with this. The portal and Github integration are pretty quick to manipulate, as long as you know where to go. So by all means, let’s make it happen!

Sign up for Stripe

First, we’ll create a Stripe account. We verify our new account via email and then we’ll head over to the API section, where we can retrieve two keys. You’ll note that we’re in test mode right now, which is good! We’ll keep it like that for testing, and unveil the testing key token to use while we set up the application.

Once you're signed in, go to the API section of your dashboard to retrieve your key.

The Stripe API screen

You may also want to add a phone number to your account for 2 factor auth as well.

Setting up Our Serverless Function in the Azure Portal

First, we’ll head over to the portal, (or if you don't already have an account, you can sign up for a free trial here) and select New > Serverless Function

Setting up a new Servless Function in Azure

When we click on the Serverless Function app, we’ll be taken to a panel that asks for details to help with the setup. As you can see in the screenshot above, it will autofill most of the fields just from the app name, but let's go over some of these options quickly:

  • Add in a unique name
  • A Resource Group (if you don’t already have one, create one)
  • I use the Windows OS because the Linux is still in preview, so Windows will be more stable
  • I use the Consumption Plan because this is the one that will have payments that scale with the use, and it will also scale automatically. The other option, App Service Plan, is good for people who prefer everything to be a bit more manual.
  • Choose a location that is close to your customer base, or a midpoint between two customer bases
  • Choose a storage, or create one as I’ve done
  • I’ll also check Pin to Dashboard because I want to be able to retrieve my function quickly later

This will bring you back to the main portal dashboard and let you know that your function is deploying. Once it’s done, it take you to a main screen that has all of your options. From here, we’ll want to create our function, and it will be an HTTP trigger.

We’ll select Functions under our function name, and you’ll see a little table with a plus that says “New Function”:

Once we click here, we have a few options on what we can create. We’ll pick HTTP Trigger:

We’ll be able to select the language (pick "JavaScript") and then "Create":

The Default Testing Function

From here, we’re given a default testing function which helps us see how this all works. If we open all of these panels and hit the Run button, we’ll see the output in logs.

Running the function in a test environment

Here’s the code we were given:

module.exports = function(context, req) { context.log('JavaScript HTTP trigger function processed a request.'); if (req.query.name || (req.body && req.body.name)) { context.res = { // status: 200, /* Defaults to 200 */ body: 'Hello ' + (req.query.name || req.body.name) }; } else { context.res = { status: 400, body: 'Please pass a name on the query string or in the request body' }; } context.done(); };

You’ll see here that we’re passing in the context. That allows us to log, which will be shown in the lowest panel below. In the Test panel on the right, we can pass in a request body that can be used to test our application. When it runs, we see the output with a 200 status and know that everything is working. We also have a context.log for the case that it gives us a 400 error. If you'd like to play around with a serverless function and see it in action for yourself, you can create one with a free trial account.

Next Up...

Now that we have the base of our serverless function, let's set up what we'll need to communicate with Stripe! More to come in the next post in this series.

Article Series:
  1. Setup and Testing (This Post)
  2. Stripe Function and Hosting (Coming Soon)
  3. Application and Checkout Component (Coming Soon)
  4. Configure the Checkout Component (Coming Soon)

Creating a Vue.js Serverless Checkout Form: Setup and Testing is a post from CSS-Tricks

Pages