Archiwum kategorii: CSS

Using Netlify Forms and Netlify Functions to Build an Email Sign-Up Widget

Post pobrano z: Using Netlify Forms and Netlify Functions to Build an Email Sign-Up Widget

Building and maintaining your own website is a great idea. Not only do you own your platform, but you get to experiment with web technologies along the way. Recently, I dug into a concept called serverless functions, starting with my own website. I’d like to share the results and what I learned along the way, so you can get your hands dirty, too!

But first, a 1-minute intro to serverless functions

A serverless function (sometimes called a lambda function or cloud function) is a piece of code that you can write, host, and run independently of your website, app, or any other code. Despite the name, serverless functions do, indeed, run on a server; but it’s a server you don’t have to build or maintain. Serverless functions are exciting because they take a lot of the legwork out of making powerful, scalable, apps.

There’s lots of great information on serverless functions out there, and a great place to start is CSS Trick’s own guide: The Power of Serverless Front-End Developers.

The Challenge: Build a Mailing List Sign Up Form

I started my journey with a challenge: I wanted to have an email list sign-up form on my site. The rules are as follows:

  • It should work without JavaScript. I’d like to see how much I can get by with just CSS and HTML. Progressive enhancements are OK.
  • It shouldn’t require external dependencies. This is a learning project, so I want to write 100% of the code if possible.
  • It should use serverless functions. Instead of sending data to my email list service client-side, let’s do it server(less)-side!

Meet the team: 11ty, Netlify, and Buttondown

My website is built using a static site framework called 11ty. 11ty allows me to write templates and components in HTML, so that’s how we’ll build our email form. (Chris recently wrote a great article about his experience with 11ty if you’re interested in learning more.)

The website is then deployed using a service called Netlify) and it is the key player on our team here: the point guard, the quarterback, the captain. That’s because Netlify has three features that work together to produce serverless excellence:

  • Netlify can deploy automatically from a GitHub repo. This means I can write my code, create a pull request, and instantly see if my code works. While there are tools to test serverless functions locally, Netlify makes it super easy to test live.
  • Netlify Forms handles any form submissions my site gets. This is one part of the serverless equation: instead of writing code to collect submissions, I’ll configure the HTML with a few simple attributes and let Netlify handle the rest.
  • Netlify Functions allows me to take action with the data from my forms. I’ll write some code to send emails off to my email list provider, and tell Netlify when to run that code.

Finally, I’ll manage my email list with a service called Buttondown. It’s a no-frills email newsletter provider, with an easy-to-use API.

Bonus: for personal sites like mine, 11ty, Netlify, and Buttondown are free. You can’t beat that.

The form

The HTML for my email subscription form is very minimal, with a few extras for Netlify Forms to work.

<form class="email-form" name="newsletter" method="POST" data-netlify="true" netlify-honeypot="bot-field">
  <div hidden aria-hidden="true">
    <label>
      Don’t fill this out if you're human: 
      <input name="bot-field" />
    </label>
  </div>
  <label for="email">Your email address</label>
  <div>
    <input type="email" name="email" placeholder="Email"  id="email" required />
    <button type="submit">Subscribe</button>
  </div>
</form>

First, I set the data-netlify attribute to true to tell Netlify to handle this form.

The first input in the form is named bot-field. This tricks robots into revealing themselves: I tell Netlify to watch for any suspicious submissions by setting the netlify-honeypot attribute to bot-field. I then hide the field from humans using the html hidden and aria-hidden values — users with and without assistive technology won’t be able to fill out the fake input.

If the form gets submitted with anything in the bot-field input, Netlify knows it’s coming from a robot, and ignores the input. In addition to this layer of protection, Netlify automatically filters suspicious submissions with Askimethttps://www.netlify.com/blog/2019/02/12/improved-netlify-forms-spam-filtering-using-akismet/). I don’t have to worry about spam!

The next input in the form is named email. This is where the email address goes! I’ve specified the input-type as email, and indicated that is required; this means that the browser will do all my validation for me, and won’t let users submit anything other than a valid email address.

Progressive enhancement with JavaScript

One neat feature of Netlify Forms is the ability to automatically redirect users to a “thank you” page when they submit a form. But ideally, I’d like to keep my users on the page. I wrote a short function to submit the form without a redirect.

const processForm = form => {
  const data = new FormData(form)
  data.append('form-name', 'newsletter');
  fetch('/', {
    method: 'POST',
    body: data,
  })
  .then(() => {
    form.innerHTML = `<div class="form--success">Almost there! Check your inbox for a confirmation e-mail.</div>`;
  })
  .catch(error => {
    form.innerHTML = `<div class="form--error">Error: ${error}</div>`;
  })
}

When I provide the content of my email form to this function via the form value, it submits the form using JavaScript’s built-in Fetch API. If the function was successful, it shows a pleasant message to the user. If the function hits a snag, it’ll tell my users that something went wrong.

This function is called whenever a user clicks the “submit” button on the form:

const emailForm = document.querySelector('.email-form')
if (emailForm) {
  emailForm.addEventListener('submit', e => {
    e.preventDefault();
    processForm(emailForm);
  })
}

This listener progressively enhances the default behavior of the form. This means that if the user has JavaScript disabled, the form still works!

The serverless function

Now that we have a working email submission form, it’s time to do some automation with a serverless function.

The way Netlify functions work is as follows:

  1. Write the function in a JavaScript file in your project.
  2. Tell Netlify where to look for your function via the netlify.toml file in your project.
  3. Add any environment variables you’ll need via Netlify’s admin interface. An environment variable is something like an API key that you need to keep secret.

That’s it! The next time you deploy your site, the function will be ready to go.

The function for my site is going to be in the functions folder, so I have the following in my netlify.toml file:

[build]
  base = "."
  functions = "./functions"

Then, I’ll add a file in the functions folder called submission-created.js. It’s important to name the file submission-created so that Netlify knows to run it every time a new form submission occurs. A full list of events you can script against can be found in Netlify’s documentation. If you’ve correctly named and configured your function, you should see it on Netlify’s Functions dashboard:

Netlify’s Functions dashboard shows I’ve correctly configured my submission-created function

The content in submission-created.js looks like this:

require('dotenv').config()
const fetch = require('node-fetch')
const { EMAIL_TOKEN } = process.env
exports.handler = async event => {
  const email = JSON.parse(event.body).payload.email
  console.log(`Recieved a submission: ${email}`)
  return fetch('https://api.buttondown.email/v1/subscribers', {
    method: 'POST',
    headers: {
      Authorization: `Token ${EMAIL_TOKEN}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ email }),
  })
    .then(response => response.json())
    .then(data => {
      console.log(`Submitted to Buttondown:\n ${data}`)
    })
    .catch(error => ({ statusCode: 422, body: String(error) }))
}

Let’s look at this line-by-line.

Line 1 includes a library called dotenv. This will help me use environment variables. Environment variables are useful to hold information that I don’t want to make public, like an API key. If I’m running my project locally, I set my environment variables with a .env file in the repo, and make sure it’s listed my .gitignore file. In order to deploy on Netlify, I also set up environment variables in Netlify’s web interface.

On line 2, I add a small library called node-fetch. This allows me to use Javascript’s Fetch API in node, which is how we’ll send data to Buttondown. Netlify automatically includes this dependency, as long as it’s listed in my project’s package.json file.

On line 3, I import my API key from the environment variables object, process.env.

Line 4 is where the function is defined. The exports.handler value is where Netlify expects to find our function, so we define it there. The only input we’ll need is the event value, which will contain all of the data from the form submission.

After retrieving the email address from the event value using JSON.parse, I’m ready to send it off to Buttondown. Here’s where I use the node-fetch library I imported earlier: I send a POST request to https://api.buttondown.email/v1/subscribers, including my API key in the header. Buttondown’s API doesn’t have many features, so it doesn’t take long to read through the documentation if you’d like to learn more.

The body of my POST request consists of the email address we retrieved.

Then (using the neat .then() syntax), I collect the response from Buttondown’s server. I do this so I can diagnose any issues that are happening with the process — Netlify makes it easy to check your function’s logs, so use console.log often!

Deploying the function

Now that I’ve written my function, configured my netlify.toml file, and added my environment variables, everything is ready to go. Deploying is painless: just set up Netlify’s GitHub integration, and your function will be deployed when your project is pushed.

Netlify projects can also be tested locally using Netlify Dev. Depending on the complexity of your code, it can be faster to develop locally: just run npm i netlify -g, then netlify dev. Netlify Dev will use the netlify.toml file to configure and run the project locally, including any serverless functions. Neat, right? One caveat: Netlify Dev currently can’t trigger serverless functions on form submissions, so you’ll have to test that using preview builds.

An idea for the future

Buttondown’s API has a few possible responses when I submit a new email. For instance, if a user submits an email that’s already subscribed to the list, I’d love to be able to tell them as soon as they submit the form.

Conclusion

All in all, I only had to write about 50 lines of code to have a functional email newsletter sign-up form available on my website. I wrote it all in HTML, CSS, and JavaScript, without having to fret with the server side of the equation. The form handles spam, and my readers get a nice experience whether they have JavaScript enabled or not.

The post Using Netlify Forms and Netlify Functions to Build an Email Sign-Up Widget appeared first on CSS-Tricks.

Weekly Platform News: Preventing Image Loads with the Picture Element, the Web We Want, Svg Styles Are Not Scoped

Post pobrano z: Weekly Platform News: Preventing Image Loads with the Picture Element, the Web We Want, Svg Styles Are Not Scoped

In this week’s week roundup of browser news, a trick for loading images conditionally using the picture element, your chance to tell bowser vendors about the web you want, and the styles applied to inline SVG elements are, well, not scoped only to that SVG.

Let’s turn to the headlines…

Preventing image loads with the picture element

You can use the <picture> element to prevent an image from loading if a specific media query matches the user’s environment (e.g., if the viewport width is larger or smaller than a certain length value). [Try out the demo:

See the Pen
voZENR
by Šime Vidas (@simevidas)
on CodePen.

<picture>
  <!-- show 1⨯1 transparent image if viewport width ≤ 40em -->
  <source
    media="(max-width: 40em)"
    srcset="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
  />

  <!-- load only image if viewport width > 40em -->
  <img src="product-large-screen.png" />
</picture>

(via Scott Jehl)

The Web We Want

The Web We Want (webwewant.fyi) is a new collaboration between browser vendors that aims to collect feedback from web developers about the current state of the web. You can submit a feature request on the website („What do you want?””) and get a chance to present it at an event (An Event Apart, Smashing Conference, etc.).

(via Aaron Gustafson)

In other news

  • Firefox supports a non-standard Boolean parameter for the location.reload method that can be used to hard-reload the page (bypassing the browser’s HTTP cache) [via Wilson Page]
  • If you use inline <svg> elements that itself have inline CSS code (in <style> elements), be aware that those styles are not scoped to the SVG element but global, so they affect other SVG elements as well [via Sara Soueidan]
  • XSS Auditor, a Chrome feature that detects cross-site scripting vulnerabilities, has been deemed ineffective and will be removed from Chrome in a future version. You may still want to set the HTTP X-Xss-Protection: 1; mode=block header for legacy browsers [via Scott Helme]

Read more news in my new, weekly Sunday issue. Visit webplatform.news for more information.

The post Weekly Platform News: Preventing Image Loads with the Picture Element, the Web We Want, Svg Styles Are Not Scoped appeared first on CSS-Tricks.

Telling the Story of Graphic Design

Post pobrano z: Telling the Story of Graphic Design

Let me just frame this for you: we’re going to take a piece of production UI from a Sketch file, break it down into pieces of information and then build it up into a story we tell our friends. Our friends might be hearing, or seeing, or touching the story so we are going to interpret and translate the same information for different people. We’re going to interpret the colors and the typography and even the sizes, and express them in different ways. And we really want everyone to pay attention. This story mustn’t be boring or frustrating; it’s got to be easy to follow, understand and remember. And it’s got to, got to, make sense, from beginning to end.

I’ve asked my colleague Katie to choose a component she has designed in Sketch. I’ll go through and mark it up (we mainly use SCSS, Twig and Craft but the templating language is not very important), then she will respond briefly. Hopefully I’ll get most of it right, and then one or two things wrong, so we can look at how things get lost during handoff.

In white label or framework type front-end, the focus is on building pieces that are as flexible and adaptable as possible, as content and style-agnostic as possible (within the scope of the product), because you simply will never know where the code is going and for what, ultimately it is being used. But recently I moved to a web design agency, which has a complete inversion of this focus. It is particular. It is bespoke. It’s all about really deeply engaging with the particular client you have and the particular clients they have, and designing something that suits them, as a tailor would.

Working so closely with a graphic designer like Katie, with highly finished pixel-spaced UI, instead of directly from wireframes or stories is an adjustment and an education, but there are still lots of things I can bring to the table. Chiefly: document design.

Document design, which admittedly is just the old semantic web with an accessibility hat on, is really looking at graphic design, engaging with it as a system of communication, and translating the underlying purpose of the colors/type/layout into an accessible, linearizable, and traversable DOM. It’s HTML, kids. It’s just HTML. You’d think we all knew it by now… but look around you. You’d be wrong!

Katie has slung me a Sketch file chock full of artboards, and she’s pretty great at writing out what she wants so I don’t have to think too hard:

Event card

First I look through the whole UI file and figure out what is actually a card on this site — it turns out there are six or seven components that use this paradigm. Let’s make some observations:

Zoom out on section of artboards
Another card, classes this time.
  • A card is a block of meta data about a page on the site.
  • It has an image/media and metadata — it’s a media object.
  • It’s shown in a group of objects.
  • That group is always typed (there’s no view where there are search results and news articles and classes are all mixed up).
  • Each object has a single link to a page and no other actions.
  • Each object has a call to action (Book, etc.).
  • Each object may have times, categories, badges, and calls to action.
  • Each object must have media, title, and link.

So a card is the major way my user is going to find their way around this site. They are going to be clicking through guided pathways where they get a set of cards they can choose from, based on top pages like „what’s on” or „classes.” They’re not getting options on this card. It’s not really an interactive element — it’s a guide, an index card, that sets her onto her path: in this case a purchase path where she books a ticket for a show at this arts centre.

Before going on, let me just frame this for you:

Imagine you were looking at a flyer for a show and discussing it on the phone. If you actually wanted to go to this show in real life. What would you do? You wouldn’t just read the flyer out, would you? That’s the text. And it might have all kinds of random stuff on it if you started literally at the top. You wouldn’t start with „Twentieth Century Fox” or „Buy Hot Dog Get Cola Free” or „Comedy Drama Musical Family Friendly.” (I would actually hang up on you if you did!) And you wouldn’t simply describe the color or fonts. That’s the CSS. You’d talk through the information on the flyer. You’d say, „It’s The Greatest Showman and it’s on Tuesday, starts at 7:30. It’s at the Odeon on Oxford Street by the tram.” Right?

This is the document. Keep that person on the phone in your mind.

Count, group, and name

So let’s say we’ll deliver a card as the inside of a list item. We want a group and that group should be countable. We’ve already named the page with an <h1> so we’ll introduce and describe the group with a heading, an <h2>. First we’ll name it, then we’ll deliver it, so someone using a screen reader can:

  1. Get the list signaled in the headings overview.
  2. Get a count up front of the number of items on a page.
  3. Know they can skip to the next list item to get the next card.
  4. Know they can skip the group at any point and go to the next page — the pagination is the very next element and it will be labelled as a landmark.

See the Pen
Cards delivered as a countable list with descriptive heading
by limograf (@Sally_McGrath)
on CodePen.

Anchor

In this particular case, I’m gonna wrap this whole card in an anchor element (<a>). There’s only one link on the card and I want to front load that information so someone can click as soon as they know it’s the right card, instead of having to search forward for the action. A big clickable area is nice too, though of course that can be taken too far and make an interface a sort of booby trap! But these cards are not too enormous and I can see they have a nice gutter around them, so there’s a rest space that will reduce accidental clicking for people with more limited dexterity.

Title

Event card „title” element

Then we’ll jump down a heading level and mark up the name of each show as a heading, an <h3>. The designer has made this type the focus and we will too. Some people browse super fast by jumping to the next heading, then next heading, so I’m not going to put any important information before the heading — they’ll jump right over it. I will put the image there, though, as I know in this case, I can’t get meaningful image descriptions from the API so those images are hidden and have empty alt attributes. Now the user can guess (correctly in my case) that the developer is actually describing the content in some meaningful way and might flip back to headings overview (list headings level 3) and just get a list of the shows.

Now let’s deliver our metadata. Let’s list it:

  • Badge
  • Date/Time
  • Categories

Badge

Event card „badge” element

This seems to be something the venue adds to a card to highlight it. As a developer, I can’t immediately see why a user would look for this, but it’s emphasized strongly by the designer, so I’ll make sure it stays in. Katie has moved the badge up out of the flow, but I know that with a headings jump our user could miss it. So I’ll just put the wording directly after the title, I think. I’ll either put it first or last, so make it easier to account for in a non-visual browse and not be too crazy paving in a tabbing, visual browse.

<p class="c-card__badge"><abbr title="Harrow Arts Centre">HAC</abbr> Highlight.</p>

…But on second thought, I won’t put an <abbr> after all. It’s the brand color, so it’s really a statement of ownership by this venue, and we’ve already said HAC a million times by now, so the user knows where they are.

<p class="c-card__badge">HAC Highlight </p>

See the Pen
Badge
by limograf (@Sally_McGrath)
on CodePen.

A quick aside: the 'badging’ is very specific to this organisation. They want to show people clearly and quickly which events they’ve programmed themselves, and which are run by other organizations who’ve hired their venue.

Date/Time

Event card „date/time” element

Now date and time. Katie is keying me in to this decision point by styling the dates in bold. Dates are important. I’m going to pop it in an <h4>, because I’m thinking it looks like someone might be quickly scanning a page of events looking for the matinee, for example, or looking for a news article published on a particular day. I don’t always put dates into headings, especially if there are millions on a page, but I do always make sure they’re in a <time> element with a complete value so the <time>Thu</time> or <time>Mon</time> Katie has specified is read out as comprehensible English words „Thursday” instead of garblage. I could also have used hidden completion or <abbr> with a title.

Categories/ Tags

Event card „categories/tags” element

Next come the categories, and I’m putting them after badge and date. This section is next in the visual order reading top-to-bottom, left-to-right, of course, but it also seems to be deprioritized: it’s been pushed down on the left and the type is smaller. This works for our linear storytelling. As a rule, we don’t want people to sit through repeated or more general content (cinema, cinema, cinema) to get to unique or more specific content (Monday, Tuesday, Wednesday). Remember, we are inside our card: we know it has already been sorted in a few general ways (news, show, class, etc), so it’s likely to have a lot of repeated pieces. We want to ensure that the user will go from specific to general if we can.

There is a primary category that is sorted first and then some other categories sometimes. I won’t deliver this as a countable list as there’s mostly just one category, and loads of lists of one item is not much use. But I will put a little tag beforehand because otherwise, it’s a slightly impenetrable announcement. MOVEMENT! SPOKEN WORD! (I mean, you can work it out retrospectively, but we always try to name things first and then show them, in linear order. This isn’t Memento.) I used to use title="" fairly heavily but I’ve gotten complaints about the tooltip so I route around. Note the use of colon or full stop to give us a „breath.” That’s a nice bit of polish.

<p class="c-card__tags h-text--label>
  <span class="h-accessibility">Categories: </span>
{% for category in categories.all() %}
  <span class="c-card__tag c-tag">{{category}}{% if not loop.last %} / {% endif %}</span>
{% endfor %}</p>

Also I’m hard-coding in my spaces to make sure the categories never run together into complete garblage even with text compression or spaceless rendering turned on somewhere down the pipeline. (This can happen with screen readers and spans and it’s rather alarming!)

There’s a piece of this design I will do in the CSS but haven’t really pulled into the document design: the color-coding on primary category. I am not describing the color to the reader as it seems arbitrary, not evocative. If there were some subtextual element to the color coding beyond tagging categories (if horticultural classes were green, say), then I might bring it through, but in this case it’s a non-verbal key to a category, so we don’t want it in our verbal key.

I’m sorting the primary category to the front of the category paragraph, but I’m not labeling it as primary. This is because there’s a sorting filter before this list that sorts on primary category, and it’s my surmise that it would be easier and less annoying to select a category from that dropdown than to read through each card saying Categories Primary Category Music Secondary Categories Dance. I could be wrong about that! Striking a balance between useful and too much labeling is sometimes a bit tricky. You have to consider the page context. We may be building components but our user is on a page.

See the Pen
Dummies in page context
by limograf (@Sally_McGrath)
on CodePen.

Action

Event card „action” element

Last, the action. The direction to the user, to Book, or Learn More, or whatever it is, has been styled as a button. It’s not actually a button, it’s just a direction, so I’ll mark it up as a span in this case. I definitely want this to come last in the linear document. It’s a call to action and also a signal that we’ve reached the end of this card. The action is the exit point in both cases: if the user acts, we go to the target entry; if they do not, we go to the next card. We definitely never want any data to come after the action, as they might have left by then.

See the Pen
Card
by limograf (@Sally_McGrath)
on CodePen.

My conclusion

This markup, which counts, groups, and names data, delivers linear and non-linear interactions. The page makes sense if you read it top to bottom, makes sense if you read parts of it out of context, and helps you jump around.

Katie, over to you…

Katie Parry, designer

What an ace article! Really interesting. (I particularly like that „Mon,” „Tue,” etc. on cards are read as „Monday,” „Tuesday”… smart!)

One thing that struck me is that using assistive tech means users get information served to them in a „set” order that we’ve decided. So, unless there’s a filter, someone browsing for dance events, for example, has to sit/tab through a title, badge, dates, and maybe several other categories to find out whether an event’s for them or not. Bit tiresome. But that’s not something you’ve got wrong — it’s just how the internet works. Something for me to think about in the future.

Most of our clients are arts and cultural venues that need to sell tickets for events so I design a lot of event cards. They’re one of the very first things I’ll work on when designing a site. (Before even settling on a type hierarchy for the rest of the site.)

Thinking visually, here’s how I’d describe the general conventions of an event card:

  • It must look like a list – so people understand how to use it.
  • It needs to provide enough information for folks to decide if they’re interested or not. (The minimum information is likely an image, title, date, and link.)
  • It needs to include a clear call to action — usually a link to find out more information.
  • It needs to be easily scannable, visually.

Making information visually scannable is a pretty straightforward case of ensuring every information type (e.g. image, title, date, category, link) is sitting in the same place on every card and follows a clear hierarchy.

I focus a lot on typography in my work anyway but clearly: titles are styled to be highly prominent; dates are styled the same as each other but are different from titles; categories look different again – so that folks can easily pick-out the information they’re interested in from simply scanning the page. I’m composing the card for the user, saying, „Hey, look here’s the event’s name, this is when it’s on — and here’s where you go to get your tickets!”

The type styles – and particularly the spacing between them – are doing a lot of work, so I will point out here that the spacings are not quite right in the code sample:

Spacing between the title and dates, dates and button, and button and piping don’t match the design.

This is important. Users need to be able to scan information quickly as they aren’t all looking for the same thing in order to make the decision to go to an event. Too much or too little space between elements can be distracting.

Here, let me tighten that up for you:

See the Pen
Card with accurate spacings
by limograf (@Sally_McGrath)
on CodePen.

Perfect!

Some people just want a general mooch at what’s coming up at their local venue. Others may have seen an advert for a specific show that tickles their fancy, and want to buy tickets. There are people who love music but don’t care for theatre who just want a list of gigs; nothing else. And some folks who feel like going out at the weekend but aren’t that fussed about what it is they go to. So, I design cards to be easy to scan — because most users aren’t at all reading from top to bottom.

Despite the conventions I just laid out, cards certainly don’t all look the same — or work in the same way — across projects.

There is always a tension in web design between making an interface familiar to the user and original to the client. Custom typefaces and color palettes do a lot here, but the other piece of it is through discovery.

I spend time reading-up about a client, including who their audience is by reading what they say on review sites and social media, as well as working directly with the client. Listening to people talk through how they work, what feedback they get from their audience/users often uncovers some interesting little nuggets which influence a design. Developers aren’t typically involved much in discovery, which is something I’d like to change, but for now, I need to make it super-clear to Sally what’s special about this event card for each new project. I write many, many (many) notes on Sketch files, but find they can tend to get lost, so sometimes we have a spreadsheet defining particular functionality.

And soon a data populator instead! 😛

See the Pen
Cards in page context, scraped from production
by limograf (@Sally_McGrath)
on CodePen.

The post Telling the Story of Graphic Design appeared first on CSS-Tricks.

Telling the Story of Graphic Design

Post pobrano z: Telling the Story of Graphic Design

Let me just frame this for you: we’re going to take a piece of production UI from a Sketch file, break it down into pieces of information and then build it up into a story we tell our friends. Our friends might be hearing, or seeing, or touching the story so we are going to interpret and translate the same information for different people. We’re going to interpret the colors and the typography and even the sizes, and express them in different ways. And we really want everyone to pay attention. This story mustn’t be boring or frustrating; it’s got to be easy to follow, understand and remember. And it’s got to, got to, make sense, from beginning to end.

I’ve asked my colleague Katie to choose a component she has designed in Sketch. I’ll go through and mark it up (we mainly use SCSS, Twig and Craft but the templating language is not very important), then she will respond briefly. Hopefully I’ll get most of it right, and then one or two things wrong, so we can look at how things get lost during handoff.

In white label or framework type front-end, the focus is on building pieces that are as flexible and adaptable as possible, as content and style-agnostic as possible (within the scope of the product), because you simply will never know where the code is going and for what, ultimately it is being used. But recently I moved to a web design agency, which has a complete inversion of this focus. It is particular. It is bespoke. It’s all about really deeply engaging with the particular client you have and the particular clients they have, and designing something that suits them, as a tailor would.

Working so closely with a graphic designer like Katie, with highly finished pixel-spaced UI, instead of directly from wireframes or stories is an adjustment and an education, but there are still lots of things I can bring to the table. Chiefly: document design.

Document design, which admittedly is just the old semantic web with an accessibility hat on, is really looking at graphic design, engaging with it as a system of communication, and translating the underlying purpose of the colors/type/layout into an accessible, linearizable, and traversable DOM. It’s HTML, kids. It’s just HTML. You’d think we all knew it by now… but look around you. You’d be wrong!

Katie has slung me a Sketch file chock full of artboards, and she’s pretty great at writing out what she wants so I don’t have to think too hard:

Event card

First I look through the whole UI file and figure out what is actually a card on this site — it turns out there are six or seven components that use this paradigm. Let’s make some observations:

Zoom out on section of artboards
Another card, classes this time.
  • A card is a block of meta data about a page on the site.
  • It has an image/media and metadata — it’s a media object.
  • It’s shown in a group of objects.
  • That group is always typed (there’s no view where there are search results and news articles and classes are all mixed up).
  • Each object has a single link to a page and no other actions.
  • Each object has a call to action (Book, etc.).
  • Each object may have times, categories, badges, and calls to action.
  • Each object must have media, title, and link.

So a card is the major way my user is going to find their way around this site. They are going to be clicking through guided pathways where they get a set of cards they can choose from, based on top pages like „what’s on” or „classes.” They’re not getting options on this card. It’s not really an interactive element — it’s a guide, an index card, that sets her onto her path: in this case a purchase path where she books a ticket for a show at this arts centre.

Before going on, let me just frame this for you:

Imagine you were looking at a flyer for a show and discussing it on the phone. If you actually wanted to go to this show in real life. What would you do? You wouldn’t just read the flyer out, would you? That’s the text. And it might have all kinds of random stuff on it if you started literally at the top. You wouldn’t start with „Twentieth Century Fox” or „Buy Hot Dog Get Cola Free” or „Comedy Drama Musical Family Friendly.” (I would actually hang up on you if you did!) And you wouldn’t simply describe the color or fonts. That’s the CSS. You’d talk through the information on the flyer. You’d say, „It’s The Greatest Showman and it’s on Tuesday, starts at 7:30. It’s at the Odeon on Oxford Street by the tram.” Right?

This is the document. Keep that person on the phone in your mind.

Count, group, and name

So let’s say we’ll deliver a card as the inside of a list item. We want a group and that group should be countable. We’ve already named the page with an <h1> so we’ll introduce and describe the group with a heading, an <h2>. First we’ll name it, then we’ll deliver it, so someone using a screen reader can:

  1. Get the list signaled in the headings overview.
  2. Get a count up front of the number of items on a page.
  3. Know they can skip to the next list item to get the next card.
  4. Know they can skip the group at any point and go to the next page — the pagination is the very next element and it will be labelled as a landmark.

See the Pen
Cards delivered as a countable list with descriptive heading
by limograf (@Sally_McGrath)
on CodePen.

Anchor

In this particular case, I’m gonna wrap this whole card in an anchor element (<a>). There’s only one link on the card and I want to front load that information so someone can click as soon as they know it’s the right card, instead of having to search forward for the action. A big clickable area is nice too, though of course that can be taken too far and make an interface a sort of booby trap! But these cards are not too enormous and I can see they have a nice gutter around them, so there’s a rest space that will reduce accidental clicking for people with more limited dexterity.

Title

Event card „title” element

Then we’ll jump down a heading level and mark up the name of each show as a heading, an <h3>. The designer has made this type the focus and we will too. Some people browse super fast by jumping to the next heading, then next heading, so I’m not going to put any important information before the heading — they’ll jump right over it. I will put the image there, though, as I know in this case, I can’t get meaningful image descriptions from the API so those images are hidden and have empty alt attributes. Now the user can guess (correctly in my case) that the developer is actually describing the content in some meaningful way and might flip back to headings overview (list headings level 3) and just get a list of the shows.

Now let’s deliver our metadata. Let’s list it:

  • Badge
  • Date/Time
  • Categories

Badge

Event card „badge” element

This seems to be something the venue adds to a card to highlight it. As a developer, I can’t immediately see why a user would look for this, but it’s emphasized strongly by the designer, so I’ll make sure it stays in. Katie has moved the badge up out of the flow, but I know that with a headings jump our user could miss it. So I’ll just put the wording directly after the title, I think. I’ll either put it first or last, so make it easier to account for in a non-visual browse and not be too crazy paving in a tabbing, visual browse.

<p class="c-card__badge"><abbr title="Harrow Arts Centre">HAC</abbr> Highlight.</p>

…But on second thought, I won’t put an <abbr> after all. It’s the brand color, so it’s really a statement of ownership by this venue, and we’ve already said HAC a million times by now, so the user knows where they are.

<p class="c-card__badge">HAC Highlight </p>

See the Pen
Badge
by limograf (@Sally_McGrath)
on CodePen.

A quick aside: the 'badging’ is very specific to this organisation. They want to show people clearly and quickly which events they’ve programmed themselves, and which are run by other organizations who’ve hired their venue.

Date/Time

Event card „date/time” element

Now date and time. Katie is keying me in to this decision point by styling the dates in bold. Dates are important. I’m going to pop it in an <h4>, because I’m thinking it looks like someone might be quickly scanning a page of events looking for the matinee, for example, or looking for a news article published on a particular day. I don’t always put dates into headings, especially if there are millions on a page, but I do always make sure they’re in a <time> element with a complete value so the <time>Thu</time> or <time>Mon</time> Katie has specified is read out as comprehensible English words „Thursday” instead of garblage. I could also have used hidden completion or <abbr> with a title.

Categories/ Tags

Event card „categories/tags” element

Next come the categories, and I’m putting them after badge and date. This section is next in the visual order reading top-to-bottom, left-to-right, of course, but it also seems to be deprioritized: it’s been pushed down on the left and the type is smaller. This works for our linear storytelling. As a rule, we don’t want people to sit through repeated or more general content (cinema, cinema, cinema) to get to unique or more specific content (Monday, Tuesday, Wednesday). Remember, we are inside our card: we know it has already been sorted in a few general ways (news, show, class, etc), so it’s likely to have a lot of repeated pieces. We want to ensure that the user will go from specific to general if we can.

There is a primary category that is sorted first and then some other categories sometimes. I won’t deliver this as a countable list as there’s mostly just one category, and loads of lists of one item is not much use. But I will put a little tag beforehand because otherwise, it’s a slightly impenetrable announcement. MOVEMENT! SPOKEN WORD! (I mean, you can work it out retrospectively, but we always try to name things first and then show them, in linear order. This isn’t Memento.) I used to use title="" fairly heavily but I’ve gotten complaints about the tooltip so I route around. Note the use of colon or full stop to give us a „breath.” That’s a nice bit of polish.

<p class="c-card__tags h-text--label>
  <span class="h-accessibility">Categories: </span>
{% for category in categories.all() %}
  <span class="c-card__tag c-tag">{{category}}{% if not loop.last %} / {% endif %}</span>
{% endfor %}</p>

Also I’m hard-coding in my spaces to make sure the categories never run together into complete garblage even with text compression or spaceless rendering turned on somewhere down the pipeline. (This can happen with screen readers and spans and it’s rather alarming!)

There’s a piece of this design I will do in the CSS but haven’t really pulled into the document design: the color-coding on primary category. I am not describing the color to the reader as it seems arbitrary, not evocative. If there were some subtextual element to the color coding beyond tagging categories (if horticultural classes were green, say), then I might bring it through, but in this case it’s a non-verbal key to a category, so we don’t want it in our verbal key.

I’m sorting the primary category to the front of the category paragraph, but I’m not labeling it as primary. This is because there’s a sorting filter before this list that sorts on primary category, and it’s my surmise that it would be easier and less annoying to select a category from that dropdown than to read through each card saying Categories Primary Category Music Secondary Categories Dance. I could be wrong about that! Striking a balance between useful and too much labeling is sometimes a bit tricky. You have to consider the page context. We may be building components but our user is on a page.

See the Pen
Dummies in page context
by limograf (@Sally_McGrath)
on CodePen.

Action

Event card „action” element

Last, the action. The direction to the user, to Book, or Learn More, or whatever it is, has been styled as a button. It’s not actually a button, it’s just a direction, so I’ll mark it up as a span in this case. I definitely want this to come last in the linear document. It’s a call to action and also a signal that we’ve reached the end of this card. The action is the exit point in both cases: if the user acts, we go to the target entry; if they do not, we go to the next card. We definitely never want any data to come after the action, as they might have left by then.

See the Pen
Card
by limograf (@Sally_McGrath)
on CodePen.

My conclusion

This markup, which counts, groups, and names data, delivers linear and non-linear interactions. The page makes sense if you read it top to bottom, makes sense if you read parts of it out of context, and helps you jump around.

Katie, over to you…

Katie Parry, designer

What an ace article! Really interesting. (I particularly like that „Mon,” „Tue,” etc. on cards are read as „Monday,” „Tuesday”… smart!)

One thing that struck me is that using assistive tech means users get information served to them in a „set” order that we’ve decided. So, unless there’s a filter, someone browsing for dance events, for example, has to sit/tab through a title, badge, dates, and maybe several other categories to find out whether an event’s for them or not. Bit tiresome. But that’s not something you’ve got wrong — it’s just how the internet works. Something for me to think about in the future.

Most of our clients are arts and cultural venues that need to sell tickets for events so I design a lot of event cards. They’re one of the very first things I’ll work on when designing a site. (Before even settling on a type hierarchy for the rest of the site.)

Thinking visually, here’s how I’d describe the general conventions of an event card:

  • It must look like a list – so people understand how to use it.
  • It needs to provide enough information for folks to decide if they’re interested or not. (The minimum information is likely an image, title, date, and link.)
  • It needs to include a clear call to action — usually a link to find out more information.
  • It needs to be easily scannable, visually.

Making information visually scannable is a pretty straightforward case of ensuring every information type (e.g. image, title, date, category, link) is sitting in the same place on every card and follows a clear hierarchy.

I focus a lot on typography in my work anyway but clearly: titles are styled to be highly prominent; dates are styled the same as each other but are different from titles; categories look different again – so that folks can easily pick-out the information they’re interested in from simply scanning the page. I’m composing the card for the user, saying, „Hey, look here’s the event’s name, this is when it’s on — and here’s where you go to get your tickets!”

The type styles – and particularly the spacing between them – are doing a lot of work, so I will point out here that the spacings are not quite right in the code sample:

Spacing between the title and dates, dates and button, and button and piping don’t match the design.

This is important. Users need to be able to scan information quickly as they aren’t all looking for the same thing in order to make the decision to go to an event. Too much or too little space between elements can be distracting.

Here, let me tighten that up for you:

See the Pen
Card with accurate spacings
by limograf (@Sally_McGrath)
on CodePen.

Perfect!

Some people just want a general mooch at what’s coming up at their local venue. Others may have seen an advert for a specific show that tickles their fancy, and want to buy tickets. There are people who love music but don’t care for theatre who just want a list of gigs; nothing else. And some folks who feel like going out at the weekend but aren’t that fussed about what it is they go to. So, I design cards to be easy to scan — because most users aren’t at all reading from top to bottom.

Despite the conventions I just laid out, cards certainly don’t all look the same — or work in the same way — across projects.

There is always a tension in web design between making an interface familiar to the user and original to the client. Custom typefaces and color palettes do a lot here, but the other piece of it is through discovery.

I spend time reading-up about a client, including who their audience is by reading what they say on review sites and social media, as well as working directly with the client. Listening to people talk through how they work, what feedback they get from their audience/users often uncovers some interesting little nuggets which influence a design. Developers aren’t typically involved much in discovery, which is something I’d like to change, but for now, I need to make it super-clear to Sally what’s special about this event card for each new project. I write many, many (many) notes on Sketch files, but find they can tend to get lost, so sometimes we have a spreadsheet defining particular functionality.

And soon a data populator instead! 😛

See the Pen
Cards in page context, scraped from production
by limograf (@Sally_McGrath)
on CodePen.

The post Telling the Story of Graphic Design appeared first on CSS-Tricks.

Datalist is for suggesting values without enforcing values

Post pobrano z: Datalist is for suggesting values without enforcing values

Have you ever had a form that needed to accept a short, arbitrary bit of text? Like a name or whatever. That’s exactly what <input type="text"> is for. There are lots of different input types (and modes!), and picking the right one is a great idea.

But this little story is about something else and applies to any of them.

What if the text needs to be arbitrary (like „What’s your favorite color?”) so people can type in whatever, but you also want to be helpful. Perhaps there are a handful of really popular answers. Wouldn’t it be nice if people could just select one? Not a <select>, but a hybrid between an input and a dropdown. Hold on though. Don’t make your own custom React element just yet.

That’s what <datalist> is for. I just used it successfully the other day so I figured I’d blog it because blogging is cool.

Here are the basics:

See the Pen
Basic datalist usage
by Chris Coyier (@chriscoyier)
on CodePen.

The use case I was dealing with needed:

  1. One <input type="text"> for a username
  2. One <input type="text"> for a „flag” (an aribtrary string representing a permission)

I probably wouldn’t do a <datalist> for every username in a database. I don’t think there is a limit, but this is sitting in your HTML, so I’d say it works best at maybe 100 options or less.

But for that second one, we only had maybe 3-4 unique flags we were dealing with at the time, so a datalist for those made perfect sense. You can type in whatever you want, but this UI helps you select the most common choices. So dang useful. Maybe this could be useful for something like a gender input, where there is a list of options you can choose, but it doesn’t enforce you actually choose one of them.

Even lesser known than the fact that <datalist> exists? The fact that it works for all sorts of inputs besides just text, like date, range, and even color.

The post Datalist is for suggesting values without enforcing values appeared first on CSS-Tricks.

Weekly news: Truncating muti-line text, calc() in custom property values, Contextual Alternates

Post pobrano z: Weekly news: Truncating muti-line text, calc() in custom property values, Contextual Alternates

In this week’s roundup, WebKit’s method for truncating multi-line text gets some love, a note on calculations using custom properties, and a new OpenType feature that prevents typographic logjams.

Truncating mutli-line text

The CSS -webkit-line-clamp property for truncating multi-line text is now widely supported (see my usage guide). If you use Autoprefixer, update it to the latest version (9.6.1). Previous versions would remove -webkit-box-orient: vertical, which caused this CSS feature to stop working.

Note that Autoprefixer doesn’t generate any prefixes for you in this case. You need to use the following four declarations exactly (all are required):

.line-clamp {
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3; /* or any other integer */
}

(via Autoprefixer)

Calculations in CSS custom property values

In CSS, it is currently not possible to pre-calculate custom property values (spec). The computed value of a custom property is its specified value (with variables substituted); therefore, relative values in calc() expressions are not „absolutized” (e.g., em values are not computed to pixel values).

:root {
  --large: calc(1em + 10px);
}

blockquote {
  font-size: var(--large);
}

It may appear that the calculation in the above example is performed on the root element, specifically that the relative value 1em is computed and added to the absolute value 10px. Under default conditions (where 1em equals 16px on the root element), the computed value of --large would be 26px.

But that’s not what’s happening here. The computed value of --large is its specified value, calc(1em + 10px). This value is inherited and substituted into the value of the font-size property on the <blockquote> element.

blockquote {
  /* the declaration after variable substitution */
  font-size: calc(1em + 10px);
}

Finally, the calculation is performed and the relative 1em value absolute-ized in the scope of the <blockquote> element — not the root element where the calc() expression is declared.

(via Tab Atkins Jr.)

Contextual Alternates

The „Contextual Alternates” OpenType feature ensures that characters don’t overlap or collide when ligatures are turned off. You can check if your font supports this feature on wakamaifondue.com and enable it (if necessary) via the CSS font-variant-ligatures: contextual declaration.

(via Jason Pamental)

Announcing daily news on webplatform.news

I have started posting daily news for web developers on webplatform.news. Visit every day!

The post Weekly news: Truncating muti-line text, calc() in custom property values, Contextual Alternates appeared first on CSS-Tricks.

My Favorite Netlify Features

Post pobrano z: My Favorite Netlify Features

👋 Hey folks! Silvestar pitched this post to us because he is genuinely enthusiastic about JAMstack and all of the opportunities it opens up for front-end development. We wanted to call that out because, although some of the points in here might come across as sponsored content and Netlify is indeed a CSS-Tricks sponsor, it’s completely independent of Netlify.

Being a JAMstack developer in 2019 makes me feel like I am living in a wonderland. All these modern frameworks, tools, and services make our lives as JAMstack developers quite enjoyable. In fact, Chris would say they give us superpowers.

Yet, there is one particular platform that stands out with its formidable products and features — Netlify. You’re probably pretty well familiar with Netlify if you read CSS-Tricks regularly. There’s a slew of articles on it. There are even two CSS-Tricks microsites that use it.

This article is more of a love letter to Netlify and all of the great things it does. I decided to sit down and list my most favorite things about it. So that’s what I’d like to share with you here. Hopefully, this gives you a good idea not only what Netlify is capable of doing, but helps you get the most out of it as well.

You can customize your site’s Netlify subdomain.

When creating a new project on Netlify, you start by either:

  • choosing a repository from a Git provider, or
  • uploading a folder.

The project should be ready in a matter of minutes, and you could start configuring it for your needs right away. Start by choosing the site name.

The site name determines the default URL for your site. Only alphanumeric characters and hyphens are allowed.

Netlify randomly creates a default name for a new project. If you don’t like the name, choose your own and make it one that would be much easier for you to remember.

The „Site information” section of the Netlify dashboard.

For example, my site name is silvestarcodes, and I could access my site by visiting silvestarcodes.netlify.com.

You can manage all your DNS on Netlify.

If you are setting up an actual site, you would want to add a custom domain. From the domain management panel, go to the custom domains section, click on the „Add custom domain” button, enter your domain, and click the „Verify” button.

Now you have two options:

  1. Point your DNS records to Netlify load balancer IP address
  2. Let Netlify handle your DNS records

For the first option, you could read the full instructions in the official documentation for custom domains.

For the second option, you should add or update the nameservers on your domain registrar. If you didn’t buy the domain already, you could register it right from the dashboard.

Netlify has a service for provisioning DNS records called Netlify DNS.

Once you have configured the custom domain, you could handle your DNS records from the Netlify dashboard.

The „DNS” section of the Netlify dashboard.

If you want to set up a dev subdomain for your dev branch to preview development changes for your site, you could do it automatically. From the Domain Management section in the Settings section of your site, select the dev branch and Netlify would add a new subdomain dev for you automagically. Now you could see the previews by visiting dev subdomain.

The „Subdomains” section of the Netlify dashboard.

You could configure a subdomain for a different website. To achieve this, create a new Netlify site, enter a new subdomain as a custom domain, and Netlify would automatically add the records for you.

As an icing on the DNS management cake, Netlify lets you create Let’s Encrypt certificates for your domain automatically… for free.

You can inject snippets into pages, which is sort of like a Tag Manager.

Snippet injection is another excellent feature. I am using it mostly for inserting analytics, but you could use it for adding meta tags for responsive behavior, favicon tags, or Webmention.io tags.

The „Snippet injection” section of the Netlify dashboard.

When inserting snippets, you could choose to append the code fragment at the end of the <head> block, or at the end of the <body> block.

Every deploy has its own URL forever.

Netlify creates a unique preview link for every successful build. That means you could easily compare revisions made to your site. For example, here is the link to my website from January this year, and here is the link from January last year. Notice the style and content changes.

In his talk, Phil Hawksworth calls this feature immutable, atomic deploys.

They are immutable deployments that live on forever.
— Phil Hawksworth

I found this feature useful when completing tasks and sending the preview links to the clients. If there is a person in charge of handling Git-related tasks, like publishing to production, these preview links could be convenient to understand what to expect during the merge. You could even set up the preview builds for every pull request.

Netlify allows for the cleanest and most responsible A/B testing you can do.

If you ever wanted to run A/B tests on your site, you would find that Netlify makes running A/B tests quite straightforward. Split testing on Netlify allows you to display different versions of your website from different Git branches without any hackery.

The „Split testing” section of the Netlify dashboard.

Start by adding and publishing a separate branch with desired changes. From “Split testing” panel, select which branches to test, set a split percentage, and start the test. You could even set a variable in analytics code to track which branch is currently displayed. You might need to active branch deploys if you didn’t do this already.

Netlify’s Split Testing lets you divide traffic to your site between different deploys, straight from our CDN network, without losing any download performance, and without installing any third party JavaScript library.
Netlify documentation

I have been using A/B testing on my site for a few different features so far:

  • Testing different versions of contact forms
  • Displaying different versions of banners
  • Tracking user behavior, like heatmaps

If you want to track split testing information, you could set up the process environment variable for this purpose. You could learn more about it in the official documentation. The best part? Most A/B testing services use client-side JavaScript to do it, which is unreliable and not great for performance. Doing it at the load balancer level like this is so much better.

There are lots of options for notifications, like email and Slack.

If you want to receive a notification when something happens with your Netlify project, you could choose from a wide variety of notification options. I prefer getting an email for every successful or failed build.

The „Notifications” section of the Netlify dashboard.

If you are using Gmail, you could notice „See the changes live” link for every successful build when hovering your message in Gmail inbox. That means you could open a preview link without opening the email. There are other links like „See full deploy logs” when your build have any issues or „Check usage details” when your plan is near its limits. How awesome is that?

Netlify email notifications include a preview link.

If you want to set up a hook for third-party services, all you need is a URL (JWS secret token is optional). Slack hooks are built-in with Netlify and could be set up within seconds if you know your Slack incoming webhook URL.

Conclusion

All of the features mentioned above are part of the free Netlify plan. I cannot even imagine the effort invested in providing a seamless experience as it is now. But Netlify doesn’t stop there. They are introducing more and more new and shiny features, like Netlify Dev CLI for local development and deploy cancelations. Netlify has established as an undoubtedly game-changing platform in modern web development of static websites, and it is a big part of the growth and popularity of static sites.

The post My Favorite Netlify Features appeared first on CSS-Tricks.

Using GraphQL Playground with Gatsby

Post pobrano z: Using GraphQL Playground with Gatsby

I’m assuming most of you have already heard about Gatsby, and at least loosely know that it’s basically a static site generator for React sites. It generally runs like this:

  1. Data Sources → Pull data from anywhere.
  2. Build → Generate your website with React and GraphQL.
  3. Deploy → Send the site to any static site host.

What this typically means is that you can get your data from any recognizable data source — CMS, markdown, file systems and databases, to name a few — manage the data through GraphQL to build your website, and finally deploy your website to any static web host (such as Netlify or Zeit).

Screenshot of the Gatsby homepage. It shows the three different steps of the Gatsby build process showing how data sources get built and then deployed.
The Gatsby homepage illustration of the Gatsby workflow.

In this article, we are concerned with the build process, which is powered by GraphQL. This is the part where your data is managed. Unlike traditional REST APIs where you often need to send anonymous data to test your endpoints, GraphQL consolidates your APIs into a self-documenting IDE. Using this IDE, you can perform GraphQL operations such as queries, mutations, and subscriptions, as well as view your GraphQL schema, and documentation.

GraphQL has an IDE built right into it, but what if we want something a little more powerful? That’s where GraphQL Playground comes in and we’re going to walk through the steps to switch from the default over to GraphQL Playground so that it works with Gatsby.

GraphiQL and GraphQL Playground

GraphiQL is GraphQL’s default IDE for exploring GraphQL operations, but you could switch to something else, like GraphQL Playground. Both have their advantages. For example, GraphQL Playground is essentially a wrapper over GraphiQL but includes additional features such as:

  • Interactive, multi-column schema documentation
  • Automatic schema reloading
  • Support for GraphQL Subscriptions
  • Query history
  • Configuration of HTTP headers
  • Tabs
  • Extensibility (themes, etc.)

Choosing either GraphQL Playground or GraphiQL most likely depends on whether you need to use those additional features. There’s no strict rule that will make you write better GraphQL operations, or build a better website or app.

This post isn’t meant to sway you toward one versus the other. We’re looking at GraphQL Playground in this post specifically because it’s not the default IDE and there may be use cases where you need the additional features it provides and needs to set things up to work with Gatsby. So, let’s dig in and set up a new Gatsby project from scratch. We’ll integrate GraphQL Playground and configure it for the project.

Setting up a Gatsby Project

To set up a new Gatsby project, we first need to install the gatsby-cli. This will give us Gatsby-specific commands we can use in the Terminal.

npm install -g gatsby-cli

Now, let’s set up a new site. I’ve decided to call this example „gatsby-playground” but you can name it whatever you’d like.

gatsby new gatsby-playground

Let’s navigate to the directory where it was installed.

cd gatsby-playground

And, finally, flip on our development server.

gatsby develop

Head over to http://localhost:8000 in the browser for the opening page of the project. Your Gatsby GraphQL operations are going to be located at http://localhost:8000/___graphql.

Screenshot of the starter page for a new Gatsby project. It says Welcome to your new Gatsby website. Now go build something great.
The GraphiQL interface. There are four panels from left to right showing the explorer, query variables and documentation.
The GraphiQL interface.

At this point, I think it’s worth calling out that there is a desktop app for GraphQL Playground. You could just access your Gatsby GraphQL operations with the URL Endpoint localhost:8000/___graphql without going any further with this article. But, we want to get our hands dirty and have some fun under the hood!

Screenshot of the GraphQL Playground interface. It has two panels showing the Gatsby GraphQL operations.
GraphQL Playground running Gatsby GraphQL Operations.

Gatsby’s Environmental Variables

Still around? Cool. Moving on.

Since we’re not going to be relying on the desktop app, we’ll need to do a little bit of Environmental Variable setup.

Environmental Variables are variables used specifically to customize the behavior of a website in different environments. These environments could be when the website is in active development, or perhaps when it is live in production and available for the world to see. We can have as many environments as we want, and define different Environmental Variables for each of the environments.

Learn more about Environmental Variables in Gatsby.

Gatsby supports two environments: development and production. To set a development environmental variable, we need to have a .env.development file at the root of the project. Same sort of deal for production, but it’s .env.production.

To swap out both environments, we’ll need to set an environment variable in a cross-platform compatible way. Let’s create a .env.development file at the root of the project. Here, we set a key/value pair for our variables. The key will be GATSBY_GRAPHQL_IDE, and the value will be playground, like so:

GATSBY_GRAPHQL_IDE=playground

Accessing Environment Variables in JavaScript

In Gatsby, our Environmental Variables are only available at build time, or when Node.JS is running (what we’ll call run time). Since the variables are loaded client-side at build time, we need to use them dynamically at run time. It is important that we restart our server or rebuild our website every time we modify any of these variables.

To load our environmental variables into our project, we need to install a package:

yarn add env-cmd --dev // npm install --save-dev env-cmd

With that, we will change the develop script in package.json as the final step, to this instead:

"develop": "env-cmd --file .env.development --fallback gatsby develop"

The develop script instructs the env-cmd package to load environmental variables from a custom environmental variable file (.env.development in this case), and if it can’t find it, fallback to .env (if you have one, so if you see the need to, create a .env file at the root of your project with the same content as .env.development).

And that’s it! But, hey, remember to restart the server since we change the variable.

yarn start // npm run develop

If you refresh the http://localhost:8000/___graphql in the browser, you should now see GraphQL playground. Cool? Cool!

GraphQL Playground with Gatsby.

And that’s how we get GraphQL Playground to work with Gatsby!

So that’s how we get from GraphQL’s default GraphiQL IDE to GraphQL Playground. Like we covered earlier, the decision of whether or not to make the switch at all comes down to whether the additional features offered in GraphQL Playground are required for your project. Again, we’re basically working with a GraphiQL wrapper that piles on more features.

Resources

Here are some additional articles around the web to get you started with Gatsby and more familiar with GraphiQL, GraphQL Playground, and Environment Variables.

The post Using GraphQL Playground with Gatsby appeared first on CSS-Tricks.

How I Created a Code Beautifier in Two Days

Post pobrano z: How I Created a Code Beautifier in Two Days

I recently drew up a wireframe for a code beautifier. The next day, I decided to turn it into a real tool. The whole project took less than two days to complete.

I’d been thinking about building a new code beautifier for a while. The idea isn’t unique, but every time I use someone else’s tool, I find myself reapplying the same settings and dodging advertisements every single time. 🤦🏻‍

I wanted a simple tool that worked well without the hassle, so last week I grabbed some paper and started sketching one out. I’m a huge fan of wireframing by hand. There’s just something about pencil and paper that makes the design part of my brain work better than staring at a screen.

I kicked off the design process by hand-drawing wireframes for the app.

I was immediately inspired after drawing the wireframe. The next day, I took a break from my usual routine to turn it into a something real. 👨🏻‍💻

Check it Out

The design

I knew I wanted the code editor to be the main focus of the tool, so I created a thin menu bar at the top that controls the mode (i.e. HTML, CSS, JavaScript) and settings. I eventually added an About button too.

The editor itself takes up most of the screen, but it blends in so you don’t really notice it. Instead of wasting space with instructions, I used a placeholder that disappears when you start typing.

The Dark Mode UI is based on a toggle that updates the styles.

At the bottom, I created a status bar that shows live stats about the code including the current mode, indentation settings, number of lines, number of characters, and document size in bytes. The right side of the status bar has a „Clear” and „Clean + Copy” button. The center has a logo shamelessly plugging my own service.

I don’t think many developers really code on phones, but I wanted this to work on mobile devices anyway. Aside from the usual responsive techniques, I had to watch the window size and adjust the tab position when the screen becomes too narrow.

I’m using flexbox and viewport units for vertical sizing. This was actually pretty easy to do with the exception of a little iOS quirk. Here’s a pen showing the basic wireframe. Notice how the textarea stretches to fill the unused space between the header and footer.

See the Pen
Full-page text editor with header + footer
by Cory LaViska (@claviska)
on CodePen.

If you look at the JavaScript tab, you’ll see the iOS quirk and the workaround. I’m not sure how to feature detect something like this, so for now it’s just a simple device check.

Handling settings

I wanted to keep the most commonly used settings easy to access, but also expose advanced settings for each mode. To do this, I made the settings button a popover with a link to more advanced settings inside. When a setting is changed, the UI updates immediately and the settings are persisted to localStorage.

The most common settings are contained in a small panel that provides quick access to them, while advanced settings are still accessible via a link in the panel.

I took advantage of Vue.js here. Each setting gets mapped to a data property, and when one of them changes, the UI updates (if required) and I call saveSettings(). It works something like this.

function saveSettings() {
  const settings = {};

  // settingsToStore is an array of property names that will be persisted
  // and "this" is referencing the current Vue model
  settingsToStore.map(key => settings[key] = this[key]);
  localStorage.setItem('settings', JSON.stringify(settings);
}

Every setting is a data property that gets synced to localStorage. This is a rather primitive way to store state, so I might update the app to use a state management library such as Vuex later on.

To restore settings, I have a restoreSettings() function that runs when the app starts up.

function restoreSettings() {
  const json = localStorage.getItem('settings');

  if (json) {
    try {
      const settings = JSON.parse(json);

      Object.keys(settings).forEach(key => {
        if (settingsToStore.includes(key)) {
          this[key] = settings[key];
        }
      });
    } catch (err) {
      window.alert('There was an error loading your previous settings');
    }
  }
}

The function fetches settings from localStorage, then applies them one by one ensuring only valid settings in settingsToStore get imported.

The Advanced Settings link opens a dialog with tabs for each mode. Despite having over 30 settings total, everything is organized and easy to access so users won’t feel overwhelmed.

Clicking the „Advanced Settings” link opens up language-specific preferences and shortcuts.

Applying themes

Dark mode is all the rage these days, so it’s enabled by default. There’s also a light theme for those who prefer it. The entire UI changes, except for popovers and dialogs.

I considered using prefers-color-scheme, which coincidentally landed in Firefox 67 recently, but I decided a toggle would probably be better. Browser support for the color theme preference query isn’t that great yet, plus developers are weird. (For example, I use macOS with the light theme, but my text editor is dark.)

The app with Light Mode UI enabled.

Defining features

Coming up with feature ideas is fairly easy. It’s limiting features for an initial release that’s hard. Here are the most relevant features I shipped right away:

  • Beautifies HTML, CSS, and JavaScript code
  • Syntax highlighting with tag/bracket matching
  • Paste or drop files to load code
  • Auto-detects indentation preference based on pasted code or dropped file
  • Light and dark themes
  • Clean and copy in one click
  • Keyboard shortcuts
  • Most JS Beautify options are configurable
  • Settings get stored indefinitely in localStorage
  • Minimal UI without ads (just an unobtrusive plug to my own service) 🙈

I also threw in a few easter eggs for fun. Try refreshing the page, exploring shortcuts, and sharing it on Facebook or Twitter to find them. 😉

The tools and libraries I used

I’m a big fan of Vue.js. It’s probably overkill for this project, but the Vue CLI let me start building with all the latest tooling via one simple command.

vue create beautify-code

I didn’t have to waste any time scaffolding, which helped me build this out quickly. Plus, Vue came in handy for things like live stats, changing themes, toggling settings, etc. I used various Element UI components for things like buttons, form elements, popovers, and dialogs.

The editor is powered by CodeMirror using custom styles. It’s a well-supported and fantastic project that I can’t recommend enough for in-browser code editing.

The library that does all the beautifying is called JS Beautify, which handles JavaScript, HTML, and CSS. JS Beautify runs on the client-side, so there’s really no backend to this app — your browser does all the work!

JS Beautify is incredibly easy to use. Install it with npm install js-beautify and run your code through the appropriate function.

import beautify from 'js-beautify';

const code = 'Your code here';
const settings = {
  // Your settings here
};

// HTML
const html = beautify.html(code, settings)

// CSS
const css = beautify.css(code, settings)

// JavaScript
const js = beautify.js(code, settings)

Each function returns a string containing the beautified code. You can change how each language is output by passing in your own settings.

I’ve been asked a few times about Prettier, which is a comparable tool, so it’s worth mentioning that I chose JS Beautify because it’s less opinionated and more configurable. If there’s enough demand, I’ll consider adding an option to toggle between JS Beautify and Prettier.

I’ve used all of these libraries before, so integration was actually pretty easy. 😅


This project was made possible by my app, Surreal CMS. If you’re looking for a great CMS for static websites, check it out — it’s free for personal, educational, and non-profit websites!

Oh, and if you’re wondering what editor I used… it’s Visual Studio Code. 👨🏻‍💻

The post How I Created a Code Beautifier in Two Days appeared first on CSS-Tricks.

What the Web Needs Now (and how ARTIFACT is here for it)

Post pobrano z: What the Web Needs Now (and how ARTIFACT is here for it)

I recently had the pleasure of joining Dave Rupert, Chris Coyier, and Chris Ferdinandi on the Shop Talk Show to talk about the upcoming ARTIFACT Conference (Austin, TX on Sept. 30 – Oct. 1, 2019). ARTIFACT is an intimate gathering of web designers and developers where we discuss ways to build web sites that work for everyone.

This isn’t our first rodeo! I started ARTIFACT back in 2013 with Christopher Schmitt and Ari Stiles (the team behind the legendary In Control and CSS Dev conferences). At that time, the sudden avalanche of web-enabled mobile devices was throwing the web design community for a loop. How do we best leverage the recently-introduced Responsive Design techniques to adapt our designs to a spectrum of screen sizes?! What does that do to our workflows?! What happens to our beloved Photoshop comps?! How do we educate our clients and structure our billing cycles?! It was an exciting time when we needed to adjust our processes quickly to take on a radically new web viewing environment.

After four events in 2013 and 2014, ARTIFACT took a little hiatus, but we are back for a five-year reunion in 2019. We are returning to a landscape where a lot of the challenges we faced in 2013 have been figured out or, at the very least, have settled down (although there is always room for innovation and improvement).

Is our work making the web better done? Not by a long shot! Now that we’ve got a handle on the low-bar requirement of getting something readable on all those screens, we can focus our energy on higher-order challenges. How do we make our sites work easier for people of all abilities? How do we make our content, products, and services welcoming to everyone? Does our code need to be so bloated and complicated? How can we make our sites simpler and faster? How can I put new tools like CSS Grid, Progressive Web Apps, static sites, and animation to good use?

To that end, this time around ARTIFACT is expanding its focus from “designing for all the devices” to “designing for all the people.” Simply put, we want a web that doesn’t leave anyone out, and we’ve curated our program to address inclusivity, performance, and the ways that new possibilities on the web affect our workflow.

A web for everyone

Inclusive design—including accessibility, diversity, and internationalization—has been bubbling to the top of the collective consciousness of the web-crafting community. I’m incredibly encouraged to see articles, conference talks, and podcasts devoted to improving the reach of the web. At ARTIFACT, inclusivity is a major theme that winds its way throughout our program.

Photo by Jopwell from Pexels
Benjamin Evans will talk about his efforts as the Inclusive Design Lead at AirBnB to create a user experience that does not alienate minority communities.
Accessibility expert Elle Waters will share best practices for integrating accessibility measures into our workflows..
We’ll also hear from David Dylan Thomas on how to recognize and address cognitive bias that can affect content and the overall user experience.

Even better performance

Visitors may also be turned away from our sites if pages take too long to load or use too much data. We know performance matters, yet sites on the whole grow more bloated with every passing year. Tim Kadlec (who knows more about performance than just about anybody) will examine the intersection of performance and inclusion in his talk “Outside Looking In” with lots of practical code examples for how to do better. We’ll also look at performance through the lens of Progressive Web Apps (presented by Jason Grigsby of Cloud Four). In fact, improving performance is a subtext to many of our developer-oriented talks.

Leveraging the modern browser

In the Good News Department, another big change since the first ARTIFACT is that browsers offer a lot more features out of the box, allowing us to leverage native browser behavior and simplify our code (Viva Performance!). Chris Ferdinandi will be demonstrating exactly that in his talk “Lean Web Development,” where he’ll point out ways that taking advantage of built-in browser functionality and writing JavaScript for just the interactivity you need may make a big framework unnecessary. Better native browser features also means un-learning some of our old coping mechanisms. We’ll get to delight at all the polyfills and workarounds that have been kicked to the curb since 2012 in Dave Rupert’s tale of “The Greatest Redesign Ever Told,” and we’ll see what best practices make sense going forward.

Workflow and process

One thing that hasn’t changed—and likely never will—is that never-ending hamster wheel of trying to keep up with an ever-changing web development landscape. I’m guessing that if you are reading CSS-Tricks right now, you know that feeling. The methods we use to build the web are always evolving with new tools, approaches, and possibilities, which is why best practices for adapting our workflows and processes have always been a central focus at ARTIFACT. This year is no different. Jen Simmons will share her thinking process for designing a CSS grid-based layout by live-coding a site before our very eyes. Design systems, which have become a cornerstone of large-scale site production, get the treatment in talks by Kim Williams, Dan Mall, and Brad Frost. (Dan and Brad are also running their acclaimed “Designer + Developer Collaboration Workflow” workshop on October 3.) Divya Sasidharan will show off the possibilities and performance advantages of static sites in her “JAMstackin” presentation, and we’ll get a glimpse of the future of web animation from Sarah Drasner. (She’s bringing her popular “Design for Developers” workshop on October 3 as well).

The web can always do better to serve the people who use it. We’re proud to provide an occasion for designers and developers who care about putting their users front and center to mingle and share ideas. And yes, there will be milkshakes! The very best milkshakes.


ARTIFACT takes place in Austin, TX from September 30 to October 2, 2019 with workshops on October 3. Group discounts are available.

The post What the Web Needs Now (and how ARTIFACT is here for it) appeared first on CSS-Tricks.