Wednesday 31 July 2019

Fetching Data in React using React Async

You’re probably used to fetching data in React using axios or fetch. The usual method of handling data fetching is to:

  • Make the API call.
  • Update state using the response if all goes as planned.
  • Or, in cases where errors are encountered, an error message is displayed to the user.

There will always be delays when handling requests over the network. That’s just part of the deal when it comes to making a request and waiting for a response. That’s why we often make use of a loading spinner to show the user that the expected response is loading.

See the Pen
ojRMaN
by Geoff Graham (@geoffgraham)
on CodePen.

All these can be done using a library called React Async.

React Async is a promised-based library that makes it possible for you to fetch data in your React application. Let’s look at various examples using components, hooks and helpers to see how we can implement loading states when making requests.

For this tutorial, we will be making use of Create React App. You can create a project by running:

npx create-react-app react-async-demo

When that is done, run the command to install React Async in your project, using yarn or npm:

## yarn
yarn add react-async

## npm
npm install react-async --save

Example 1: Loaders in components

The library allows us to make use of <Async> directly in our JSX. As such, the component example will look like this;

// Let's import React, our styles and React Async
import React from 'react';
import './App.css';
import Async from 'react-async';

// We'll request user data from this API
const loadUsers = () =>
  fetch("https://jsonplaceholder.typicode.com/users")
    .then(res => (res.ok ? res : Promise.reject(res)))
    .then(res => res.json())

// Our component
function App() {
  return (
    <div className="container">
      <Async promiseFn={loadUsers}>
        {({ data, err, isLoading }) => {
          if (isLoading) return "Loading..."
          if (err) return `Something went wrong: ${err.message}`

          if (data)
            return (
              <div>
                <div>
                  <h2>React Async - Random Users</h2>
                </div>
                {data.map(user=> (
                  <div key={user.username} className="row">
                    <div className="col-md-12">
                      <p>{user.name}</p>
                      <p>{user.email}</p>
                    </div>
                  </div>
                ))}
              </div>
            )
        }}
      </Async>
    </div>
  );
}

export default App;

First, we created a function called loadUsers. This will make the API call using the fetch API. And, when it does, it returns a promise which gets resolved. After that, the needed props are made available to the component.

The props are:

  • isLoading: This handles cases where the response has not be received from the server yet.
  • err: For cases when an error is encountered. You can also rename this to error.
  • data: This is the expected data obtained from the server.

As you can see from the example, we return something to be displayed to the user dependent on the prop.

Example 2: Loaders in hooks

If you are a fan of hooks (as you should), there is a hook option available when working with React Async. Here’s how that looks:

// Let's import React, our styles and React Async
import React from 'react';
import './App.css';
import { useAsync } from 'react-async';

// Then we'll fetch user data from this API
const loadUsers = async () =>
  await fetch("https://jsonplaceholder.typicode.com/users")
    .then(res => (res.ok ? res : Promise.reject(res)))
    .then(res => res.json())

// Our component
function App() {
  const { data, error, isLoading } = useAsync({ promiseFn: loadUsers })
  if (isLoading) return "Loading..."
  if (error) return `Something went wrong: ${error.message}`
  if (data)
  
  // The rendered component
  return (
    <div className="container">
      <div>
        <h2>React Async - Random Users</h2>
      </div>
      {data.map(user=> (
        <div key={user.username} className="row">
          <div className="col-md-12">
            <p>{user.name}</p>
            <p>{user.email}</p>
          </div>
        </div>
      ))}
    </div>
  );
}

export default App;

This looks similar to the component example, but in this scenario, we’re making use of useAsync and not the Async component. The response returns a promise which gets resolved, and we also have access to similar props like we did in the last example, with which we can then return to the rendered UI.

Example 3: Loaders in helpers

Helper components come in handy in making our code clear and readable. These helpers can be used when working with an useAsync hook or with an Async component, both of which we just looked at. Here is an example of using the helpers with the Async component.

// Let's import React, our styles and React Async
import React from 'react';
import './App.css';
import Async from 'react-async';

// This is the API we'll use to request user data
const loadUsers = () =>
  fetch("https://jsonplaceholder.typicode.com/users")
    .then(res => (res.ok ? res : Promise.reject(res)))
    .then(res => res.json())

// Our App component
function App() {
  return (
    <div className="container">
      <Async promiseFn={loadUsers}>
          <Async.Loading>Loading...</Async.Loading>
          <Async.Fulfilled>
            {data => {
              return (
                <div>
                  <div>
                    <h2>React Async - Random Users</h2>
                  </div>
                  {data.map(user=> (
                    <div key={user.username} className="row">
                      <div className="col-md-12">
                        <p>{user.name}</p>
                        <p>{user.email}</p>
                      </div>
                    </div>
                  ))}
                </div>
              )
            }}
          </Async.Fulfilled>
          <Async.Rejected>
            {error => `Something went wrong: ${error.message}`}
          </Async.Rejected>
      </Async>
    </div>
  );
}

export default App;

This looks similar to when we were making use of props. With that done, you could break the different section of the app into tiny components.

Conclusion

If you have been growing weary of going the route I mentioned in the opening section of this tutorial, you can start making of React Async in that project you are working on. The source code used in this tutorial can be found in their different branches on GitHub.

The post Fetching Data in React using React Async appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/31aLOsa
via IFTTT

Bringing CSS Grid to WordPress Layouts

A More Accessible Portals Demo

Tuesday 30 July 2019

How much specificity do @rules have, like @keyframes and @media?

I got this question the other day. My first thought is: weird question! Specificity is about selectors, and at-rules are not selectors, so... irrelevant?

To prove that, we can use the same selector inside and outside of an at-rule and see if it seems to affect specificity.

body {
  background: red;
}
@media (min-width: 1px) {
  body {
    background: black;
  }
}

The background is black. But... is that because the media query increases the specificity? Let's switch them around.

@media (min-width: 1px) {
  body {
    background: black;
  }
}
body {
  background: red;
}

The background is red, so nope. The red background wins here just because it is later in the stylesheet. The media query does not affect specificity.

If it feels like selectors are increasing specificity and overriding other styles with the same selector, it's likely just because it comes later in the stylesheet.

Still, the @keyframes in the original question got me thinking. Keyframes, of course, can influence styles. Not specificity, but it can feel like specificity if the styles end up overridden.

See this tiny example:

@keyframes winner {
  100% { background: green; }
}
body {
  background: red !important;
  animation: winner forwards;
}

You'd think the background would be red, especially with the !important rule there. (By the way, !important doesn't affect specificity; it's a per-rule thing.) It is red in Firefox, but it's green in Chrome. So that's a funky thing to watch out for. (It's been a bug since at least 2014 according to Estelle Weyl.)

The post How much specificity do @rules have, like @keyframes and @media? appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/2KbrrUG
via IFTTT

Intrinsically Responsive CSS Grid with minmax() and min()

The most famous line of code to have come out of CSS grid so far is:

grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));

Without any media queries, that will set up a grid container that has a flexible number of columns. The columns will stretch a little, until there is enough room for another one, and then a new column is added, and in reverse.

The only weakness here is that first value in minmax() (the 10rem value above). If the container is narrower than whatever that minimum is, elements in that single column will overflow. Evan Minto shows us the solution with min():

grid-template-columns: repeat(auto-fill, minmax(min(10rem, 100%), 1fr));

The browser support isn't widespread yet, but Evan demonstrates some progressive enhancement techniques to take advantage of now.

Direct Link to ArticlePermalink

The post Intrinsically Responsive CSS Grid with minmax() and min() appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/2Ge1UJp
via IFTTT

Creating Dynamic Routes in a Nuxt Application

The Simplest Way to Load CSS Asynchronously

Scott Jehl:

One of the most impactful things we can do to improve page performance and resilience is to load CSS in a way that does not delay page rendering. That’s because by default, browsers will load external CSS synchronously—halting all page rendering while the CSS is downloaded and parsed—both of which incur potential delays.

<link rel="stylesheet" href="/path/to/my.css" media="print" onload="this.media='all'">

Don't just up and do this to all your stylesheets though, otherwise, you'll get a pretty nasty "Flash of Unstyled Content" (FOUC) as the page loads. You need to pair the technique with a way to ship critical CSS. Do that though, and like Scott's opening sentence said, it's quite impactful.

Interesting side story... on our Pen Editor page over at CodePen, we had a FOUC problem:

What makes it weird is that we load our CSS in <link> tags in the <head> completely normally, which should block-rendering and prevent FOUC. But there is some hard-to-reproduce bug at work. Fortunately we found a weird solution, so now we have an empty <script> tag in the <head> that somehow solves it.

Direct Link to ArticlePermalink

The post The Simplest Way to Load CSS Asynchronously appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/2xZ9Jya
via IFTTT

Run useEffect Only Once

React has a built-in hook called useEffect. Hooks are used in function components. The Class component comparison to useEffect are the methods componentDidMount, componentDidUpdate, and componentWillUnmount.

useEffect will run when the component renders, which might be more times than you think. I feel like I've had this come up a dozen times in the past few weeks, so it seems worthy of a quick blog post.

import React, { useEffect } from 'react';

function App() {
  useEffect(() => {
    // Run! Like go get some data from an API.
  });

  return (
    <div>
      {/* Do something with data. */}
    </div>
  );
}

In a totally isolated example like that, it's likely the useEffect will run only once. But in a more complex app with props flying around and such, it's certainly not guaranteed. The problem with that is that if you're doing something like fetching data from an API, you might end up double-fetching which is inefficient and unnecessary.

The trick is that useEffect takes a second parameter.

The second param is an array of variables that the component will check to make sure changed before re-rendering. You could put whatever bits of props and state you want in here to check against.

Or, put nothing:

import React, { useEffect } from 'react';

function App() {
  useEffect(() => {
    // Run! Like go get some data from an API.
  }, []);

  return (
    <div>
      {/* Do something with data. */}
    </div>
  );
}

That will ensure the useEffect only runs once.

Note from the docs:

If you use this optimization, make sure the array includes all values from the component scope (such as props and state) that change over time and that are used by the effect. Otherwise, your code will reference stale values from previous renders.

The post Run useEffect Only Once appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/332aQeq
via IFTTT

Monday 29 July 2019

Lessons Learned from a Year of Testing the Web Platform

Mike Pennisi:

The web-platform-tests project is a massive suite of tests (over one million in total) which verify that software (mostly web browsers) correctly implement web technologies. It’s as important as it is ambitious: the health of the web depends on a plurality of interoperable implementations.

Although Bocoup has been contributing to the web-platform-tests, or “WPT,” for many years, it wasn’t until late in 2017 that we began collecting test results from web browsers and publishing them to wpt.fyi

Talk about doing God's work.

The rest of the article is about the incredible pain of scaling a test suite that big. Ultimately Azure Pipelines was helpful.

Direct Link to ArticlePermalink

The post Lessons Learned from a Year of Testing the Web Platform appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/2JLfPJ9
via IFTTT

Empathetic Consulting: 3 Things to Remember When Working With Other Teams

Getting design system customization just right

I had a little rant in me a few months ago about design systems: "Who Are Design Systems For?" My main point was that there are so many public and open source ones out there that choosing one can feel like choosing new furniture for your house. You just measure up what you need and what you like and pick one. But it just isn't that simple. Some are made for you, some makers want you to use them, and some just ain't.

A more measured take from Koen Vendrik (consistently, the same Koen who just made a cool Jest browser tool):

... it’s important that you first define who a design system is for and what people should be able to do with it. When you have decided this, and start looking at the implementation for the level of flexibility you require, keep in mind that it’s okay to do something that’s different from what’s already out there. It’s easy to create a lot of flexibility or none at all, the trick is to get it just right.

The levels:

  • Zero customizability. Sometimes this is the point: enforcing consistency and making it easy to use (no config).
  • Build your own (BYO) theme. The other end of the spectrum: do whatever you want, fully cusomizable.
  • Guided theme building. This is baby bear. Like changing preprocessor values to change colors, but it can get fancier.

Direct Link to ArticlePermalink

The post Getting design system customization just right appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/2xLvqBK
via IFTTT

The Guardian digital design system

Friday 26 July 2019

Telling the Story of Graphic Design

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.



from CSS-Tricks https://ift.tt/2LIf3ii
via IFTTT

9 Tips to Integrate Organic, Paid, and Content - Whiteboard Friday

Thursday 25 July 2019

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

My Favorite Netlify Features

Responsive Iframes

Say you wanted to put the CSS-Tricks website in an <iframe>. You'd do that like this:

<iframe src="https://css-tricks.com"></iframe>

Without any other styling, you'd get a rectangle that is 300x150 pixels in size. That's not even in the User Agent stylesheet, it's just some magical thing about iframes (and objects). That's almost certainly not what you want, so you'll often see width and height attributes right on the iframe itself (YouTube does this).

<iframe 
  width="560"
  height="315"
  src="https://css-tricks.com"></iframe>

Those attributes are good to have. It's a start toward reserving some space for the iframe that is a lot closer to how it's going to end up. Remember, layout jank is bad. But we've got more work to do since those are fixed numbers, rather than a responsive-friendly setup.

The best trick for responsive iframes, for now, is making an aspect ratio box. First you need a parent element with relative positioning. The iframe is the child element inside it, which you apply absolute positioning to in order to fill the area. The tricky part is that the parent element becomes the perfect height by creating a pseudo-element to push it to that height based on the aspect ratio. The whole point of it is that pushing the element to the correct size is a nicer system than forcing a certain height. In the scenario where the content inside is taller than what the aspect ratio accounts for, it can still grow rather than overflow.

I'll just put a complete demo right here (that works for images too):

See the Pen
Responsive Iframe
by Chris Coyier (@chriscoyier)
on CodePen.

Every time we're dealing with aspect ratios, it makes me think of a future with better handling for it. There is the experimental intrinsicsize attribute that I could imagine being quite nice for iframes in addition to images. Plus there is the hopefully-will-exist-soon aspect-ratio in CSS and the idea that it could default to use the width and height attributes on the element, which I hope would extend to iframes.

The post Responsive Iframes appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/2OkDxQP
via IFTTT

How Google PageSpeed Works: Improve Your Score and Search Engine Ranking

What I Like About Vue

Dave Rupert digs into some of his favorite Vue features and one particular issue that he has with React:

I’ve come to realize one thing I don’t particularly like about React is jumping into a file, reading the top for the state, jumping to the bottom to find the render function, then following the method calls up to a series other sub-rendering functions only to find the component I’m looking for is in another castle. That cognitive load is taxing for me.

I wrote about this very problem recently in our newsletter where I argued that finding my way around a React component is difficult. I feel like I have to spend more energy than necessary figuring out how a component works because React encourages me to write code in a certain way.

On the other hand, Dave, says that Vue matches his mental model when authoring components:

<template>
  // Start with a foundation of good HTML markup 
</template>
<script>
  // Add interaction with JavaScript
</script>
<style>
  // Add styling as necessary. 
</style>

And this certainly matches the way I think about things, too.

Direct Link to ArticlePermalink

The post What I Like About Vue appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/32CcJOZ
via IFTTT

The ABCs of Video Content: How to Build a Video Marketing Strategy

Wednesday 24 July 2019

Zdog

Don’t comma-separate :focus-within if you need deep browser support

I really like :focus-within. It's a super useful selector that allows you to essentially select a parent element when any of its children are in focus.

Say you wanted to reveal some extra stuff when a <div> is hovered...

div:hover {
  .extra-stuff {
     /* reveal it */
  }
}

That's not particularly keyboard-friendly. But if something in .extra-stuff is tab-able anyway (meaning it can be focused), that means you could write it like this to make it a bit more accessible:

div:hover,
div:focus-within {
  .extra-stuff {
     /* reveal it */
  }
}

That's nice, but it causes a tricky problem.

Browsers ignore entire selectors if it doesn't understand any part of them. So, if you're dealing with a browser that doesn't support :focus-within then it would ignore the CSS example above, meaning you've also lost the :hover state.

Instead:

div:hover {
  .extra-stuff {
     /* reveal it */
  }
}
div:focus-within {
  .extra-stuff {
     /* reveal it */
  }
}

That is safer. But it's repetitive. If you have a preprocessor like Sass...

@mixin reveal {
  .extra-stuff {
     transform: translateY(0);
  }
}
div:hover {
  @include reveal;
}
div:focus-within {
  @include reveal;
}

See the Pen
Mixing for :focus-within without comma-separating
by Chris Coyier (@chriscoyier)
on CodePen.

I'd say it's a pretty good use-case for having native CSS mixins.

The post Don’t comma-separate :focus-within if you need deep browser support appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/2Ma87tt
via IFTTT

The Ultimate Guide to SEO Meta Tags

Posted by katemorris

Editor's note: This post first appeared in April of 2017, but because SEO (and Google) changes so quickly, we figured it was time for a refresh!


Meta tags represent the beginning of most SEO training, for better or for worse. I contemplated exactly how to introduce this topic because we always hear about the bad side of meta tags — namely, the keywords meta tag. One of the first things dissected in any site review is the misuse of meta tags, mainly because they're at the top of every page in the header and are therefore the first thing seen. But we don't want to get too negative; meta tags are some of the best tools in a search marketer's repertoire.

There are meta tags beyond just description and keywords, though those two are picked on the most. I've broken down the most-used (in my experience) by the good, the bad, and the indifferent. You'll notice that the list gets longer as we get to the bad ones. I didn't get to cover all of the meta tags possible to add, but there's a comprehensive meta tag resource you should check out if you're interested in everything that's out there.

It's important to note that in 2019, you meta tags still matter, but not all of them can help you. It's my experience, and I think anyone in SEO would agree, that if you want to rank high in search, your meta tags need to accompany high-quality content that focuses on user satisfaction.

My main piece of advice: stick to the core minimum. Don't add meta tags you don't need — they just take up code space. The less code you have, the better. Think of your page code as a set of step-by-step directions to get somewhere, but for a browser. Extraneous meta tags are the annoying "Go straight for 200 feet" line items in driving directions that simply tell you to stay on the same road you're already on!

The good meta tags

These are the meta tags that should be on every page, no matter what. Notice that this is a small list; these are the only ones that are required, so if you can work with just these, please do.

  • Meta content type – This tag is necessary to declare your character set for the page and should be present on every page. Leaving this out could impact how your page renders in the browser. A few options are listed below, but your web designer should know what's best for your site.
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
  • Title – While the title tag doesn’t start with "meta," it is in the header and contains information that's very important to SEO. You should always have a unique title tag on every page that describes the page. Check out this post for more information on title tags.
  • Meta description – The infamous meta description tag is used for one major purpose: to describe the page to searchers as they read through the SERPs. This tag doesn't influence ranking, but it's very important regardless. It's the ad copy that will determine if users click on your result. Keep it within 160 characters, and write it to catch the user's attention. Sell the page — get them to click on the result. Here's a great article on meta descriptions that goes into more detail.
  • Viewport – In this mobile world, you should be specifying the viewport. If you don’t, you run the risk of having a poor mobile experience — the Google PageSpeed Insights Tool will tell you more about it. The standard tag is:
<meta name=viewport content="width=device-width, initial-scale=1">

The indifferent meta tags

Different sites will need to use these in specific circumstances, but if you can go without, please do.

  • Social meta tags I'm leaving these out. OpenGraph and Twitter data are important to sharing but are not required per se.
  • Robots One huge misconception is that you have to have a robots meta tag. Let's make this clear: In terms of indexing and link following, if you don't specify a meta robots tag, they read that as index,follow. It's only if you want to change one of those two commands that you need to add meta robots. Therefore, if you want to noindex but follow the links on the page, you would add the following tag with only the noindex, as the follow is implied. Only change what you want to be different from the norm.
<meta name="robots" content="noindex" />
  • Specific bots (Googlebot) – These tags are used to give a specific bot instructions like noodp (forcing them not to use your DMOZ listing information, RIP) and noydir (same, but instead the Yahoo Directory listing information). Generally, the search engines are really good at this kind of thing on their own, but if you think you need it, feel free. There have been some cases I've seen where it's necessary, but if you must, consider using the overall robots tag listed above.
  • Language – The only reason to use this tag is if you're moving internationally and need to declare the main language used on the page. Check out this meta languages resource for a full list of languages you can declare.
  • Geo – The last I heard, these meta tags are supported by Bing but not Google (you can target to country inside Search Console). There are three kinds: placename, position (latitude and longitude), and region.
<META NAME="geo.position" CONTENT="latitude; longitude">
<META NAME="geo.placename" CONTENT="Place Name">
<META NAME="geo.region" CONTENT="Country Subdivision Code">
  • Keywords – Yes, I put this on the "indifferent" list. While no good SEO is going to recommend spending any time on this tag, there's some very small possibility it could help you somewhere. Please leave it out if you're building a site, but if it's automated, there's no reason to remove it.
  • Refresh – This is the poor man's redirect and should not be used, if at all possible. You should always use a server-side 301 redirect. I know that sometimes things need to happen now, but Google is NOT a fan.
  • Site verification – Your site is verified with Google and Bing, right? Who has the verification meta tags on their homepage? These are sometimes necessary because you can't get the other forms of site verification loaded, but if at all possible try to verify another way. Google allows you to verify by DNS, external file, or by linking your Google Analytics account. Bing still only allows by XML file or meta tag, so go with the file if you can.

The bad meta tags

Nothing bad will happen to your site if you use these — let me just make that clear. They're a waste of space though; even Google says so (and that was 12 years ago now!). If you're ready and willing, it might be time for some spring cleaning of your <head> area.

  • Author/web author – This tag is used to name the author of the page. It's just not necessary on the page.
  • Revisit after – This meta tag is a command to the robots to return to a page after a specific period of time. It's not followed by any major search engine.
  • Rating – This tag is used to denote the maturity rating of content. I wrote a post about how to tag a page with adult images using a very confusing system that has since been updated (see the post's comments). It seems as if the best way to note bad images is to place them on a separate directory from other images on your site and alert Google.
  • Expiration/date – "Expiration" is used to note when the page expires, and "date" is the date the page was made. Are any of your pages going to expire? Just remove them if they are (but please don't keep updating content, even contests — make it an annual contest instead!). And for "date," make an XML sitemap and keep it up to date. It's much more useful.
  • Copyright – That Google article debates this with me a bit, but look at the footer of your site. I would guess it says "Copyright 20xx" in some form. Why say it twice?
  • Abstract – This tag is sometimes used to place an abstract of the content and used mainly by educational pursuits.
  • Distribution – The "distribution" value is supposedly used to control who can access the document, typically set to "global." It's inherently implied that if the page is open (not password-protected, like on an intranet) that it's meant for the world. Go with it, and leave the tag off the page.
  • Generator – This is used to note what program created the page. Like "author," it's useless.
  • Cache-control – This tag is set in hopes of controlling when and how often a page is cached in the browser. It's best to do this in the HTTP header.
  • Resource type – This is used to name the type of resource the page is, like "document." Save yourself time, as the DTD declaration does it for you.

There are so many meta tags out there, I’d love to hear about any you think need to be added or even removed! Shout out in the comments with suggestions or questions.


Sign up for The Moz Top 10, a semimonthly mailer updating you on the top ten hottest pieces of SEO news, tips, and rad links uncovered by the Moz team. Think of it as your exclusive digest of stuff you don't have time to hunt down but want to read!



from The Moz Blog https://ift.tt/2Z6YXln
via IFTTT

Tuesday 23 July 2019

Unsuck It

Julia Carrie Wong and Matthew Cantor's How to speak Silicon Valley: 53 essential tech-bro terms explained was pretty hilarious. A little something in there to offend everyone.

Speaking of kinda douchey words, I'm reminded of one of my favorite sites on the internet: Unsuck It. Not only does it call out a ton of terms for being, uh, sucky, but suggests unsucky alternatives.

Bubble Up

Thank you for pointing out that issue. I’ll be sure to bubble that up.

Unsucked: Tell someone with more authority.

Powwow

Oh, yes! That’s very important to me. Let’s have a powwow about this first thing tomorrow.

Unsucked: Yet more unthinking appropriation of Native American culture. Meeting.

Solutioneering

Unsucked: Thinking.


On a somewhat related note, there's the ol' swoop and poop which is also a thing.

Direct Link to ArticlePermalink

The post Unsuck It appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/1Ix8QPt
via IFTTT

Pseudo Code

Yonatan Doron wrote a post on Medium not long ago called "Art of Code — Why you should write more Pseudo Code." Love that title, as a fan of pseudo code myself. That is, writing "code" that describes something you want to do or communicate, but that isn't of any particular language and doesn't use any correct APIs or anything.

Taking this time to write commented pseudo code helps organize our thoughts and our motivation and plan the desired outcome code ahead. By doing so, one moment later when we venture through to start hacking we would always have this map or skeleton of our thoughts that can help us regain focus and increase our productiveness

Jeremy Keith once likened it to writing a script:

When the user submits a form, then show a modal dialogue with an acknowledgment.” I then encouraged them to write a script …but I don’t mean a script in the JavaScript sense; I mean a script in the screenwriting or theatre sense. Line by line, write out each step that you want to accomplish. Once you’ve done that, translate each line of your English (or Portuguese) script into JavaScript.

I've seen educators use this technique time and time again. But it isn't just for teachers to use and students to learn from — it's for anyone's benefit. I find myself doing pseudo code before I write real code, sure, but I also leave it in place sometimes in code comments. Most commonly, I do it in Notion documents or in Slack conversations to get across a point.

Even simple ideas:

if env.dev
  stop email delivery

Anything with logic and branching or step-by-step bits benefits highly from it. Notice that code isn't valid code. It's not valid in any language I can think of. Sometimes, I'll throw in some random parenthesis or a semicolon out of muscle memory. Who cares? It's just about communicating an idea to myself or someone else.

if (grid is supported)
  use grid
else
  lay out things in a basic row with flexbox

It's natural. Chances are, they won't care about the syntax either, they'll just get the idea.

on form submit
  validate
  if errors
     show errors;
  else
     submit to api;
     if api success
        show ui success;
     else
        show ui fail;

(After writing these out, it made me think of uilang. Check out how the plain language code blocks work there.)

Yonatan's article was missing real-world pseudo code examples, so I asked around. Check out all these great examples!

I'm a little surprised at how much of it is on paper! That's pretty cool, really. Just weird for me as I very rarely use paper for anything. I probably should.

The post Pseudo Code appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/2JKflmh
via IFTTT

Zoom, CORS, and the Web

How to Boost Content Linkability Without Wasting Your Marketing Budget

Monday 22 July 2019

CSS :not() with Multiple Classes

Say you want to select an element when it doesn't have a certain class. That's what the :not() selector is for.

body:not(.home) {
  
}

But what if there are multiple classes you want to avoid?

There are no logical combinators with :not(), like and or or, but you can chain them, which is effectively like and.

body:not(.home):not(.away):not(.page-50) {
  
}

The :not() selector doesn't add any specificy by itself, but what is inside does, so :not(.foo) adds the same weight as .foo does.

The post CSS :not() with Multiple Classes appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/30P0YTs
via IFTTT

A Beginner’s Journey to Launching a Website

CSS Animation Libraries

Spying On Google: 5 Ways to Use Log File Analysis To Reveal Invaluable SEO Insights

Thursday 18 July 2019

Weekly Platform News: CSS ::marker pseudo-element, pre-rendering web components, adding Webmention to your site

MozCon 2019: Everything You Need to Know About Day Three

Posted by KameronJenkins

If the last day of MozCon felt like it went too fast or if you forgot everything that happened today (we wouldn't judge — there were so many insights), don't fret. We captured all of day three's takeaways so you could relive the magic of day three. 

Don't forget to check out all the photos with Roger from the photobooth! They're available here in the MozCon Facebook group. Plus: You asked and we delivered: the 2019 MozCon speaker walk-on playlist is now live and available here for your streaming pleasure. 

Cindy Krum— Fraggles, Mobile-First Indexing, & the SERP of the Future 

If you were hit with an instant wave of nostalgia after hearing Cindy's walk out music, then you are in good company and you probably were not disappointed in the slightest by Cindy’s talk on Fraggles.

  • “Fraggles” are fragments + handles. A fragment is a piece of info on a page. A handle is something like a bookmark, jump link, or named anchor — they help people navigate through long pages to get what they’re looking for faster.
  • Ranking pages is an inefficient way to answer questions. One page can answer innumerable questions, so Google’s now can pull a single answer from multiple parts of your page, skipping sections they don’t think are as useful for a particular answer.
  • The implications for voice are huge! It means you don’t have to listen to your voice device spout off a page’s worth of text before your question is answered.
  • Google wants to index more than just websites. They want to organize the world’s information, not websites. Fraggles are a demonstration of that.

Luke Carthy — Killer Ecommerce CRO and UX Wins Using A SEO Crawler 

Luke Carthy did warn us in his talk description that we should all flex our notetaking muscles for all the takeaways we would furiously jot down — and he wasn’t wrong.

  • Traffic doesn’t always mean sales and sales don’t always mean traffic!
  • Custom extraction is a great tool for finding missed CRO opportunities. For example, Luke found huge opportunity on Best Buy’s website — thousands of people’s site searches were leading them to an unoptimized “no results found” page.
  • You can also use custom extraction to find what product recommendations you or your customers are using at scale! Did you know that 35% of what customers buy on Amazon and 75 percent of what people watch on Netflix are the results of these recommendations?
  • For example, are you showing near-exact products or are you showing complementary products? (hint: try the latter and you’ll likely increase your sales!)
  • Custom extraction from Screaming Frog allows you to scrape any data from the HTML of the web pages while crawling them.

Andy Crestodina — Content, Rankings, and Lead Generation: A Breakdown of the 1% Content Strategy 

Next up, Andy of Orbit Media took the stage with a comprehensive breakdown of the most effective tactics for turning content into a high-powered content strategy. He also brought the fire with this sound advice that we can apply in both our work life and personal life.

  • Blog visitors often don’t have commercial intent. One of the greatest ways to leverage blog posts for leads is by using the equity we generate from links to our helpful posts and passing that onto our product and service pages.
  • If you want links and shares, invest in original research! Not sure what to research? Look for unanswered questions or unproven statements in your industry and provide the data.
  • Original research may take longer than a standard post, but it’s much more effective! When you think about it this way, do you really have time to put out more, mediocre posts?
  • Give what you want to get. Want links? Link to people. Want comments? Comment on others people's work.
  • To optimize content for social engagement, it should feature real people, their faces, and their quotes.
  • Collaborating with other content creators on your content not only gives it built-in amplification, but it also leads to great connections and is just generally more fun.

Rob Ousbey — Running Your Own SEO Tests: Why It Matters & How to Do It Right 

Google’s algorithms have changed a heck of a lot in recent years — what’s an SEO to do? Follow Rob’s advice — both fashion and SEO — who says that the answer lies in testing.

  • “This is the way we’ve always done it” isn’t sufficient justification for SEO tactics in today’s search landscape.
  • In the earlier days of the algorithm, it was much easier to demote spam than it was to promote what’s truly good.
  • Rob and his team had a theory that Google was beginning to rely more heavily on user experience and satisfaction than some of the more traditional ranking factors like links.
  • Through SEO A/B testing, they found that:
    • Google relies less heavily on link signals when it comes to the top half of the results on page 1.
    • Google relies more heavily on user experience for head terms (terms with high search volume), likely because they have more user data to draw from.
  • In the process of A/B testing, they also found that the same test often produces different results on different sites. The best way to succeed in today’s SEO landscape is to cultivate a culture of testing!

Greg Gifford — Dark Helmet's Guide to Local Domination with Google Posts and Q&A 

If you’re a movie buff, you probably really appreciated Greg’s talk — he schooled us all in movie references and brought the fire with his insights on Google Posts and Q&A  

The man behind #shoesofmozcon taught us that Google is the new home page for local businesses, so we should be leveraging the tools Google has given us to make our Google My Business profiles great. For example…

Google Posts

  • Images should be 1200x900 on google posts
  • Images are cropped slightly higher than the center and it’s not consistent every time
  • The image size of the thumbnail is different on desktop than it is on mobile
  • Use Greg’s free tool at bit.ly/posts-image-guide to make sizing your Google Post images easier
  • You can also upload videos. The file size limit is 100mb and/or 30 seconds
  • Add a call-to-action button to make your Posts worth it! Just know that the button often means you get less real estate for text in your Posts
  • Don’t share social fluff. Attract with an offer that makes you stand out
  • Make sure you use UTM tracking so you can understand how your Posts are performing in Google Analytics. Otherwise, it’ll be attributed as direct traffic.

Google Q&A

  • Anyone can ask and answer questions — why not the business owner! Control the conversation and treat this feature like it's your new FAQ page.
  • This feature works on an upvote system. The answer with the most upvotes will show first.
  • Don’t include a URL or phone number in these because it’ll get filtered out.
  • A lot of these questions are potential customers! Out of 640 car dealerships’ Q&As Greg evaluated, 40 percent were leads! Of that 40 percent, only 2 questions were answered by the dealership.

 Emily Triplett Lentz — How to Audit for Inclusive Content 

Emily of Help Scout walked dropped major knowledge on the importance of spotting and eliminating biases that frequently find their way into online copy. She also hung out backstage after her talk to cheer on her fellow speakers. #GOAT. #notallheroeswearcapes.

  • As content creators, we’d all do well to keep ableism in mind: discrimination in favor of able-bodied people. However, we’re often guilty of this without even knowing it.
  • One example of ableism that often makes its way into our copy is comparing dire or subideal situations with the physical state of another human (ex: “crippling”).
  • While we should work on making our casual conversation more inclusive too, this is particularly important for brands.
  • Create a list of ableist words, crawl your site for them, and then replace them. However, you’ll likely find that there is no one-size-fits-all replacement for these words. We often use words like “crazy” as filler words. By removing or replacing with a more appropriate word, we make our content better and more descriptive in the process.
  • At the end of the day, brands should remember that their desire for freedom of word choice isn’t more important than people’s right not to feel excluded and hurt. When there’s really no downside to more inclusive content, why wouldn’t we do it?

Visit http://content.helpscout.net/mozcon-2019 to learn how to audit your site for inclusive content!

Joelle Irvine — Image & Visual Search Optimization Opportunities 

Curious about image optimization and visual search? Joelle has the goods for you — and was blowing people's minds with her tips for visual optimization and how to leverage Google Lens, Pinterest, and AR for visual search.

  • Visual search is not the same thing as searching for images. We’re talking about the process of using an image to search for other content.
  • Visual search like Google Lens makes it easier to search when you don’t know what you’re looking for.
  • Pinterest has made a lot of progress in this area. They have a hybrid search that allows you to find complimentary items to the one you searched. It’s like finding a rug that matches a chair you like rather than finding more of the same type of chair.
  • 62 percent of millennials surveyed said they would like to be able to search by visual, so while this is mostly being used by clothing retailers and home decor right now, visual search is only going to get better, so think about the ways you can leverage it for your brand!

Joy Hawkins — Factors that Affect the Local Algorithm that Don't Impact Organic 

Proximity varies greatly when comparing local and organic results — just ask Joy of Sterling Sky, who gets real about fake listings while walking through the findings of a recent study.

Here are the seven areas in which the local algorithm diverges from the organic algorithm:

  • Proximity (AKA: how close is the biz to the searcher?)
    • Proximity is the #1 local ranking factor, but the #27 ranking factor on organic.
    • Studies show that having a business that’s close in proximity to the searcher is more beneficial for ranking in the local pack than in traditional organic results.
  • Rank tracking
    • Because there is so much variance by latitude/longitude, as well as hourly variances, Joy recommends not sending your local business clients ranking reports.
    • Use rank tracking internally, but send clients the leads/sales. This causes less confusion and gets them focused on the main goal.
    • Visit bit.ly/mozcon3 for insights on how to track leads from GMB
  • GMB landing pages (AKA: the website URL you link to from your GMB account)
    • Joy tested linking to the home page (which had more authority/prominence) vs. linking to the local landing page (which had more relevance) and found that traffic went way up when linking to the home page.
    • Before you go switching all your GMB links though, test this for yourself!
  • Reviews
    • Joy wanted to know how much reviews actually impacted ranking, and what it was exactly about reviews that would help or hurt.
    • She decided to see what would happen to rankings when reviews were removed. This happened to a business who was review gating (a violation of Google’s guidelines) but Joy found that reviews flagged for violations aren’t actually removed, they’re hidden, explaining why “removed” reviews don’t negatively impact local rankings.
  • Possum filter
    • Organic results can get filtered because of duplicate content, whereas local results can get filtered because they’re too close to another business in the same category. This is called the Possum filter.
  • Keywords in a business name
    • This is against Google’s guidelines but it works sadly
    • For example, Joy tested adding the word “salad bar” to a listing that didn’t even have a salad bar and their local rankings for that keyword shot up.
    • Although it works, don’t do it! Google can remove your listing for this type of violation, and they’ve been removing more listings for this reason lately.
  • Fake listings
    • New listings can rank even if they have no website, authority, citations, etc. simply because they keyword stuffed their business name. These types of rankings can happen overnight, whereas it can take a year or more to achieve certain organic rankings.
    • Spend time reporting spam listings in your clients’ niches because it can improve your clients’ local rankings.

Britney Muller — Featured Snippets: Essentials to Know & How to Target 

Closing out day three of MozCon was our very own Britney, Sr. SEO scientist extraordinaire, on everyone’s favorite SEO topic: Featured snippets!

We’re seeing more featured snippets than ever before, and they’re not likely going away. It’s time to start capitalizing on this SERP feature so we can start earning brand awareness and traffic for our clients!

Here’s how:

  • Know what keywords trigger featured snippets that you rank on page 1 for
  • Know the searcher’s intent
  • Provide succinct answers
  • Add summaries to popular posts
  • Identify commonly asked questions
  • Leverage Google’s NLP API
  • Monitor featured snippets
  • If all else fails, leverage ranking third party sites. Maybe your own site has low authority and isn’t ranking well, but try publishing on Linkedin or Medium instead to get the snippet!

There’s lots of debate over whether featured snippets send you more traffic or take it away due to zero-click results, but consider the benefits featured snippets can bring even without the click. Whether featured snippets bring you traffic, increased brand visibility in the SERPs, or both, they’re an opportunity worth chasing.

Aaaand, that's a wrap!

Thanks for joining us at this year's MozCon! And a HUGE thank you to everyone (Mozzers, partners, and crew) who helped make this year's MozCon possible — we couldn't have done it without all of you. 

What was your favorite moment of the entire conference? Tell us below in the comments! And don't forget to grab the speaker slides here


Sign up for The Moz Top 10, a semimonthly mailer updating you on the top ten hottest pieces of SEO news, tips, and rad links uncovered by the Moz team. Think of it as your exclusive digest of stuff you don't have time to hunt down but want to read!



from The Moz Blog https://ift.tt/2GdsthR
via IFTTT

The Real Impact of Mobile-First Indexing & The Importance of Fraggles

MozCon 2019: Day Two Learnings

MozCon 2019: The Top Takeaways From Day One

How to Target Featured Snippet Opportunities — Best of Whiteboard Friday

Using GraphQL Playground with Gatsby

Get Peak WordPress Performance with Jetpack

The irony of web performance is that the average page weight of a site continues to go up year after year, despite us being more aware of the problem and having more tools at our disposal to fight it than ever.

To paraphrase Seinfeld, "we know how to fight page weight issues; we just don't use the tools we have to fight page weight issues."

That's why Jetpack provides powerful features for all users at any plan level. They made it so that performance is integrated right into managing content on a WordPress site.

One of those things is lazy loading images. Lazy loading is an excellent technique to defer loading images until they are actually needed. So, an image never loads until the user actually scrolls to where it comes into display. That could potentially save a ton of server requests and precious bytes when waiting for a page to load. Jetpack includes lazy loading, even on free plans, so everyone has access to this performance boost.


And what's the point of lazy loading anything if you don't have somewhere to host the files? Well, Jetpack also offers unlimited static file and image hosting for every plan level. No more wondering how much storage is left on your server! You get an unlimited amount of space to store anything you need. That's pretty awesome!

It gets even more awesome. That's because the unlimited storage is part of a CDN that is designed to serve images from high-speed dedicated data centers that make downloads as fast and smooth as possible. Again, that's free to everyone!

That makes Jetpack a super resource for combatting performance issues on a WordPress site. Hey, we use Jetpack here at CSS-Tricks and it's a linchpin for so much of how this site works and operates. The performance benefits are a nice perk but it's worth checking out everything it has to offer because there's likely so much more you can leverage.

Get Jetpack

The post Get Peak WordPress Performance with Jetpack appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/2O0uF2x
via IFTTT

Wednesday 17 July 2019

Multi-Line Truncation with Pure CSS

Improving Video Accessibility with WebVTT

Micro Frontends

One random day not long ago, I started hearing joke after joke about "micro frontends" — sort of how I first learned about Toast. I didn't understand the source until asking around, which uncovered this article from Cam Jackson.

In this article we'll describe a recent trend of breaking up frontend monoliths into many smaller, more manageable pieces, and how this architecture can increase the effectiveness and efficiency of teams working on frontend code.

I'd argue it should read "front-end monoliths" and "front-end code," but I digress already.

The idea is similar to microservices, but for the front end. So, instead of one big front-end architecture (e.g. a React app), different parts of the front end are developed entirely independent of one another, have no dependencies on each other, and can be worked on and deployed independently.

It's one of those things where you can't quite tell if it's really an interesting foretelling of the future, just a niche architectural choice that happened to work for a handful of large organizations, or even just a theoretical option.

The first place my mind goes is consistency and DRY-ness. Anywhere I've worked, these things are a big deal and it seems like the industry at large has had endless front-end problems with shipping designs that start and stay consistent and cohesive without repeating itself with shovelfuls of technical debt. Independent front-ends sound like they might be a problem if Team B is being blocked by Team A for something not directly related, but then it introduces the problem of Team B's output drifting towards inconsistency with Team A's output.

The article itself talks about a browse/search landing page, a details/ordering page, and a profile page, with all three of those tackled by different independent products/teams. It sounds kinda cool and interesting to me, and it also sounds like those teams better sit right next to each other at work; otherwise this app is going the way of Frankenstein's monster in two weeks. Styling is only lightly addressed with a, "I dunno, do a good job" sort of vibe. Teams struggle with this when they are all on the same product, so I'd have huge concerns here. The first thing I'd try to solve if this is being discussed seriously would be a design system that transcends all of it and that everyone uses without fail.

And what if those micro front ends co-exist on the same page? Use <iframe>, the article says. I can't see a world where that leads to a good user experience. (iFrames are slow, especially many of them all booting up their own worlds — and what about elements that might overflow bounds like tooltips and menus?)

The other integration options... isolating them to their own bundles or even native web components sounds a bit better. But still, the idea of siloed development where a React component might be slapped on the same page as a Vuew component seems like a huge user penalty for a pretty specific organizational problem. Not to mention you're losing the benefits of a shared understanding of a codebase and the benefits of a deeper technical understanding of a smaller set of tools.

I'm probably not characterizing all of this fairly, especially because the idea is rather new to me and I've never worked like this before.

Nader Dabit has a follow up article: Building Micro Frontends with React, Vue, and Single-spa. Just so I'm not mischaracterizing that: The idea really is that you might build a React app and I build a Vue app and we'll slap 'em together on the same page. I definitely come from an era where we laughed-then-winced when we found sites that used multiple versions of jQuery on the same page, plus one thing that loaded all of MooTools and Prototype thrown on there seemingly by accident. We winced because that was a bucket full of JavaScript, mostly duplicated for no reason, causing bugs and slowing down the page. This doesn't seem all that much different.

Joel Denning points out in an AMA on the subject:

I’m pointing out that we’re in the “hate without closely examining” stage of the idea. It’s entirely possible that after legitimate, close examination that the idea still fails. But too early to tell.

Fair enough.

Sorry about piling on. 😣



from CSS-Tricks https://ift.tt/2Y9umpR
via IFTTT

Monday 15 July 2019

Managing Multiple Backgrounds with Custom Properties

One cool thing about CSS custom properties is that they can be a part of a value. Let's say you're using multiple backgrounds to pull off a a design. Each background will have its own color, image, repeat, position, etc. It can be verbose!

You have four images:

body {
  
  background-position:
    top 10px left 10px,
    top 10px right 10px,
    bottom 10px right 10px,
    bottom 10px left 10px;
  
  background-repeat: no-repeat;
  
  background-image:
    url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-top-left.svg),
    url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-top-right.svg),
    url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-bottom-right.svg),
    url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-bottom-left.svg);
  
}

You want to add a fifth in a media query:

@media (min-width: 1500px) {
  body {
    /* REPEAT all existing backgrounds, then add a fifth. */
  }
}

That's going to be super verbose! You'll have to repeat each of those four images again, then add the fifth. Lots of duplication there.

One possibility is to create a variable for the base set, then add the fifth much more cleanly:

body {
  --baseBackgrounds: 
    url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-top-left.svg),
    url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-top-right.svg),
    url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-bottom-right.svg),
    url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-bottom-left.svg);

  background-position:
    top 10px left 10px,
    top 10px right 10px,
    bottom 10px right 10px,
    bottom 10px left 10px;
  
  background-repeat: no-repeat;
  
  background-image: var(--baseBackgrounds);
}
@media (min-width: 1500px) {
  body {
    background-image: 
      var(--baseBackgrounds),
      url(added-fifth-background.svg);
  }
}

But, it's really up to you. It might make more sense and be easier manage if you made each background image into a variable, and then pieced them together as needed.

body {
  --bg1: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-top-left.svg);
  --bg2: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-top-right.svg);
  --bg3: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-bottom-right.svg);
  --bg4: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-bottom-left.svg);
  --bg5: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-bottom-left.svg);
  
  background-image: var(--bg1), var(--bg2), var(--bg3), var(--bg4);
}
@media (min-width: 1500px) {
  body {
    background-image: var(--bg1), var(--bg2), var(--bg3), var(--bg4), var(--bg5);
  }
}

Here's a basic version of that, including a supports query:

See the Pen
Multiple BGs with Custom Properties
by Chris Coyier (@chriscoyier)
on CodePen.

Dynamically changing just the part of a value is a huge strength of CSS custom properties!

Note, too, that with backgrounds, it might be best to include the entire shorthand as the variable. That way, it's much easier to piece everything together at once, rather than needing something like...

--bg_1_url: url();
--bg_1_size: 100px;
--bg_1_repeat: no-repeat;
/* etc. */

It's easier to put all of the properties into shorthand and use as needed:

body {  
  --bg_1: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-top-left.svg) top 10px left 10px / 86px no-repeat;
  --bg_2: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-top-right.svg) top 10px right 10px / 86px no-repeat;
  --bg_3: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-bottom-right.svg) bottom 10px right 10px / 86px no-repeat;
  --bg_4: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-bottom-left.svg) bottom 10px left 10px  / 86px no-repeat;
    
  background:
    var(--bg_1), var(--bg_2),var(--bg_3),var(--bg_4);
}

Like this.

The post Managing Multiple Backgrounds with Custom Properties appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/2YX7yae
via IFTTT

Build a Chat App Using React Hooks in 100 Lines of Code

Friday 12 July 2019

Position Sticky and Table Headers

You can't position: sticky; a <thead>. Nor a <tr>. But you can sticky a <th>, which means you can make sticky headers inside a regular ol' <table>. This is tricky stuff, because if you didn't know this weird quirk, it would be hard to blame you. It makes way more sense to sticky a parent element like the table header rather than each individiaul element in a row.

The issue boils down to the fact that stickiness requires position: relative to work and that doesn't apply to <thead> and <tr> in the CSS 2.1 spec.

There are two very extreme reactions to this, should you need to implement sticky table headers and not be aware of the <th> workaround.

  • Don't use table markup at all. Instead, use different elements (<div>s and whatnot) and other CSS layout methods to replicate the style of a table, but not locked out of using position: relative and creating position: sticky parent elements.
  • Use table elements, but totally remove all their styling defaults with new display values.

The first is dangerous because you aren't using semantic and accessible elements for the content to be read and navigated. The second is almost the same. You can go that route, but need to be really careful to re-apply semantic roles.

Anyway, none of that matters if you just stick (get it?!) to using a sticky value on those <th> elements.

See the Pen
Sticky Table Headers with CSS
by Chris Coyier (@chriscoyier)
on CodePen.

It's probably a bit weird to have table headers as a row in the middle of a table, but it's just illustrating the idea. I was imagining colored header bars separating players on different sports teams or something.

Anytime I think about data tables, I also think about how tricky it can be to make them responsive. Fortunately, there are a variety of ways, all depending on the best way to group and explore the data in them.

The post Position Sticky and Table Headers appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/30zCHku
via IFTTT

Color Inputs: A Deep Dive into Cross-Browser Differences

Thursday 11 July 2019

Weekly Platform News: HTML Inspection in Search Console, Global Scope of Scripts, Babel env Adds defaults Query

Protecting Vue Routes with Navigation Guards

Authentication is a necessary part of every web application. It is a handy means by which we can personalize experiences and load content specific to a user — like a logged in state. It can also be used to evaluate permissions, and prevent otherwise private information from being accessed by unauthorized users.

A common practice that applications use to protect content is to house them under specific routes and build redirect rules that navigate users toward or away from a resource depending on their permissions. To gate content reliably behind protected routes, they need to build to separate static pages. This way, redirect rules can properly handle redirects.

In the case of Single Page Applications (SPAs) built with modern front-end frameworks, like Vue, redirect rules cannot be utilized to protect routes. Because all pages are served from a single entry file, from a browser’s perspective, there is only one page: index.html. In a SPA, route logic generally stems from a routes file. This is where we will do most of our auth configuration for this post. We will specifically lean on Vue’s navigation guards to handle authentication specific routing since this helps us access selected routes before it fully resolves. Let’s dig in to see how this works.

Roots and Routes

Navigation guards are a specific feature within Vue Router that provide additional functionality pertaining to how routes get resolved. They are primarily used to handle error states and navigate a user seamlessly without abruptly interrupting their workflow.

There are three main categories of guards in Vue Router: Global Guards, Per Route Guards and In Component Guards. As the names suggest, Global Guards are called when any navigation is triggered (i.e. when URLs change), Per Route Guards are called when the associated route is called (i.e. when a URL matches a specific route), and Component Guards are called when a component in a route is created, updated or destroyed. Within each category, there are additional methods that gives you more fine grained control of application routes. Here’s a quick break down of all available methods within each type of navigation guard in Vue Router.

Global Guards

  • beforeEach: action before entering any route (no access to this scope)
  • beforeResolve: action before the navigation is confirmed, but after in-component guards (same as beforeEach with this scope access)
  • afterEach: action after the route resolves (cannot affect navigation)

Per Route Guards

  • beforeEnter: action before entering a specific route (unlike global guards, this has access to this)

Component Guards

  • beforeRouteEnter: action before navigation is confirmed, and before component creation (no access to this)
  • beforeRouteUpdate: action after a new route has been called that uses the same component
  • beforeRouteLeave: action before leaving a route

Protecting Routes

To implement them effectively, it helps to know when to use them in any given scenario. If you wanted to track page views for analytics for instance, you may want to use the global afterEach guard, since it gets fired when the route and associated components are fully resolved. And if you wanted to prefetch data to load onto a Vuex store before a route resolves, you could do so using the beforeEnter per route guard.

Since our example deals with protecting specific routes based on a user’s access permissions, we will use in component navigation guards, namely the beforeEnter hook. This navigation guard gives us access to the proper route before the resolve completes; meaning that we can fetch data or check that data has loaded before letting a user pass through. Before diving into the implementation details of how this works, let’s briefly look at how our beforeEnter hook fits into our existing routes file. Below, we have our sample routes file, which has our protected route, aptly named protected. To this, we will add our beforeEnter hook to it like so:

const router = new VueRouter({
  routes: [
    ...
    {
      path: "/protected",
      name: "protected",
      component: import(/* webpackChunkName: "protected" */ './Protected.vue'),
      beforeEnter(to, from, next) {
        // logic here
      }
  ]
})

Anatomy of a route

The anatomy of a beforeEnter is not much different from other available navigation guards in Vue Router. It accepts three parameters: to, the “future” route the app is navigating to; from, the “current/soon past” route the app is navigating away from and next, a function that must be called for the route to resolve successfully.

Generally, when using Vue Router, next is called without any arguments. However, this assumes a perpetual success state. In our case, we want to ensure that unauthorized users who fail to enter a protected resource have an alternate path to take that redirects them appropriately. To do this, we will pass in an argument to next. For this, we will use the name of the route to navigate users to if they are unauthorized like so:

next({
  name: "dashboard"
})

Let’s assume in our case, that we have a Vuex store where we store a user’s authorization token. In order to check that a user has permission, we will check this store and either fail or pass the route appropriately.

beforeEnter(to, from, next) {
  // check vuex store //
  if (store.getters["auth/hasPermission"]) {
    next()
  } else {
    next({
      name: "dashboard" // back to safety route //
    });
  }
}

In order to ensure that events happen in sync and that the route doesn’t prematurely load before the Vuex action is completed, let’s convert our navigation guards to use async/await.

async beforeEnter(to, from, next) {
  try {
    var hasPermission = await store.dispatch("auth/hasPermission");
    if (hasPermission) {
      next()
    }
  } catch (e) {
    next({
      name: "dashboard" // back to safety route //
    })
  }
} 

Never forget where you came from

So far our navigation guard fulfills its purpose of preventing unauthorized users access to protected resources by redirecting them to where they may have come from (i.e. the dashboard page). Even so, such a workflow is disruptive. Since the redirect is unexpected, a user may assume user error and attempt to access the route repeatedly with the eventual assumption that the application is broken. To account for this, let’s create a way to let users know when and why they are being redirected.

We can do this by passing in a query parameter to the next function. This allows us to append the protected resource path to the redirect URL. So, if you want to prompt a user to log into an application or obtain the proper permissions without having to remember where they left off, you can do so. We can get access to the path of the protected resource via the to route object that is passed into the beforeEnter function like so: to.fullPath.

async beforeEnter(to, from, next) {
  try {
    var hasPermission = await store.dispatch("auth/hasPermission");
    if (hasPermission) {
      next()
    }
  } catch (e) {
    next({
      name: "login", // back to safety route //
      query: { redirectFrom: to.fullPath }
    })
  }
}

Notifying

The next step in enhancing the workflow of a user failing to access a protected route is to send them a message letting them know of the error and how they can solve the issue (either by logging in or obtaining the proper permissions). For this, we can make use of in component guards, specifically, beforeRouteEnter, to check whether or not a redirect has happened. Because we passed in the redirect path as a query parameter in our routes file, we now can check the route object to see if a redirect happened.

beforeRouteEnter(to, from, next) {
  if (to.query.redirectFrom) {
    // do something //
  }
}

As I mentioned earlier, all navigation guards must call next in order for a route to resolve. The upside to the next function as we saw earlier is that we can pass an object to it. What you may not have known is that you can also access the Vue instance within the next function. Wuuuuuuut? Here’s what that looks like:

next(() => {
  console.log(this) // this is the Vue instance
})

You may have noticed that you don’t technically have access to the this scope when using beforeEnter. Though this might be the case, you can still access the Vue instance by passing in the vm to the function like so:

next(vm => {
  console.log(vm) // this is the Vue instance
})

This is especially handy because you can now create and appropriately update a data property with the relevant error message when a route redirect happens. Say you have a data property called errorMsg. You can now update this property from the next function within your navigation guards easily and without any added configuration. Using this, you would end up with a component like this:

<template>
  <div>
    <span></span>
    <!-- some other fun content -->
    ...
    <!-- some other fun content -->
  </div>
</template>
<script>
export default {
  name: "Error",
  data() {
    return {
      errorMsg: null
    }
  },
  beforeRouteEnter(to, from, next) {
    if (to.query.redirectFrom) {
      next(vm => {
        vm.errorMsg =
          "Sorry, you don't have the right access to reach the route requested"
      })
    } else {
      next()
    }
  }
}
</script>

Conclusion

The process of integrating authentication into an application can be a tricky one. We covered how to gate a route from unauthorized access as well as how to put workflows in place that redirect users toward and away from a protected resource based on their permissions. The assumption thus far has been that you already have authentication configured in your application. If you don’t yet have this configured and you’d like to get up and running fast, I highly recommend working with authentication as a service. There are providers like Netlify’s Identity Widget or Auth0’s lock.

The post Protecting Vue Routes with Navigation Guards appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/2NMIz8n
via IFTTT

Passkeys: What the Heck and Why?

These things called  passkeys  sure are making the rounds these days. They were a main attraction at  W3C TPAC 2022 , gained support in  Saf...