Newer posts are loading.
You are at the newest post.
Click here to check if anything new just came in.

May 25 2018

20:54

Service Worker Cookbook

I stumbled upon this site the other day from Mozilla that’s a collection of recipes to get started with a Service Worker — from caching strategies and notifications to providing an offline fallback to your users, this little cookbook has it all.

You can also check out our guide to making a simple site work offline and the offline site that resulted from it.

Direct Link to ArticlePermalink

The post Service Worker Cookbook appeared first on CSS-Tricks.

14:42

Learning Gutenberg: Building Our Custom Card Block

We’ve got some base knowledge, we’ve played with some React and now we’ve got our project tools set up. Let’s dive into building our custom block.

Article Series:

  1. Series Introduction
  2. What is Gutenberg, Anyway?
  3. A Primer with create-guten-block
  4. Modern JavaScript Syntax
  5. React 101
  6. Setting up a Custom webpack
  7. A Custom "Card" Block (This Post)

What we’re building

We’re going to build a custom card block that features an image, a title and a summary. It’s a really common design pattern in the web and it also let’s us look at some core Gutenberg components, along with core WordPress elements, such as the Media Library. We’ll also play with some display logic with JSX for the front-end markup.

Our glorious custom card block!

Our glorious custom card block!

We’re going to focus solely on the CMS aspect of this block in this tutorial. What it renders is some nice, clean markup on the front-end though. You could extend this block to feature front-end styles too, if you wanted.

Getting started

The first thing we’re going to do is open up the block.js file that we created in the previous section. In your active plugin folder, this is located at blocks/src/block/block.js.

If you are working from the file structure created with create-guten-block, you might want to start by deleting everything in block.js and writing your code from scratch along with the tutorial.

Right at the top of this file, add the following:

const { registerBlockType, RichText, MediaUpload, PlainText } = wp.blocks;
const { Button } = wp.components;

We covered destructuring assignments in Part 3. This is a great example of those, which you’ll see a lot in Gutenberg code. Here, wp.components features more than Button, but that’s all we want, so that’s all we’ll get. It’s a neat because it prevents us from having to write stuff like wp.components.Button, which will be great for keeping our code nice and light.

We’ve got that cleared up, so let’s import our Sass files. This is so that webpack detects them.

import './style.scss';
import './editor.scss';

Now let’s start writing the component that powers our block. Right under those lines, add the following:

registerBlockType('card-block/main', {   
  title: 'Card',
  icon: 'heart',
  category: 'common'
});

This code tells Gutenberg, "Hey, I’ve got a block for you to add to your collection. It’s called 'Card,’ it has a 'heart' icon and it should live in the 'common' category." This is our component’s basic definition, so let’s add some more code.

This should look familiar—remember our challenge in Part 2, create-guten-block? In case you need reminding, check it out here. The first six of those were relatively straightforward and involved replacing strings or bit of HTML. The seventh item, “Make the paragraph text editable," is much more complicated to implement and was intended to get you thinking a bit. The time has come though, and we will indeed make some text editable in Gutenberg!

You may also recognize this registerBlockType function from the PHP register_block_type function we used in the last article. While that function registers a block from the server-side of WordPress, this one registers our block into the React ecosystem on the client side. Both are necessary to have a block that uses React, and their registered names, card-block/main must match.

Add the following code, but make sure you put a comma after 'common', so it looks like this: 'common',.

Here’s the code:

attributes: {
  title: {
    source: 'text',
    selector: '.card__title'
  },
  body: {
    type: 'array',
    source: 'children',
    selector: '.card__body'
  },
  imageAlt: {
    attribute: 'alt',
    selector: '.card__image'
  },
  imageUrl: {
    attribute: 'src',
    selector: '.card__image'
  }
}

Here, we are defining the editable attributes of our block and the DOM selector that they are assigned to. This attribute object works in a very similar way to the React state object. It even has a very similar updating method called setAttributes. We’ll get to that later though.

At this point, it’s worth a brief overview of state and attributes because they represent a whole new way of thinking for WordPress developers. I’ll take over for a moment to go over them.

About Attributes and State

It may look like a simple JavaScript object, but that chunk of attributes introduces a whole swath of new concepts to a WordPress theme developer’s brain, not least of which is state. The concept of state has a long history in computer science, and life in general, really. Almost everything has a state. What state is your coffee cup in now? Empty, almost empty? How about your clothing? Are your shoes dirty or new? How about your body? Are you tired or wide awake?

At a high level, state simply refers to the present condition of a thing. In computer science, that thing is a computer program, and that program can be much, much simpler than what we create here on the web. Take a vending machine, for instance. The vending machine has a state that updates each time you put in a coin. When the state of the machine reaches a predefined amount, say $1.25, the machine knows to allow you to make your snack choice.

In Gutenberg, attributes track the present condition of data in a block. Attributes are the closest parallel we can draw to custom fields in Gutenberg, but they exist only in the context of Gutenberg and JavaScript. Let’s take the attribute above for title, for example:

title: {
  source: 'text',
  selector: 'card__title'
},

When Gutenberg fires up, it says, “I need to find some text inside a selector called .card__title, and populate the value for title with whatever I find."

Attributes in Gutenberg are not directly connected to the database like custom fields are connected to post_meta. The entries source and selector are instructions for Gutenberg to populate the state of each block. When we load up the editor, it follows these instructions and assigns a value to title based on the markup saved in the database between the HTML comments that indicate a block of this type. We don’t see the value of title in the attributes we register, but if I were to access props.attributes.title, I would get whatever text exists in .card__title.

We’ve set up some basics, so let’s dive in to our edit function. This is what’s called when the block is accessed from the Gutenberg editor in visual mode. The user will see the rich interface, rather than the HTML code that it generates. That’s what I’ll cover next.

Add our edit function

Let’s add some code in. Add the following after the closing } of the attributes object. Like before, make sure you add a trailing comma, so it looks like this },.

Add the following code after that:

edit({ attributes, className, setAttributes }) {
  return (
  );
}

So, we’re using another destructuring assignment to selectively pick our passed parameters to the edit function. The two most important are attributes and setAttributes. The attributes parameter is the same as the attributes block, but it’s the current, reactive state. This means if the setAttributes function updates one of the attributes values, it will automatically update anywhere that references it, which is similar to our React component from Part 3.

There’s a big ol’ return in this function. Can you guess what’s going in it? Yup! We’re going to stick some JSX in there. Add the following within the return parentheses:

<div className="container">
  <MediaUpload
    onSelect={ media => { setAttributes({ imageAlt: media.alt, imageUrl: media.url }); } }
    type="image"
    value={ attributes.imageID }
    render={ ({ open }) => getImageButton(open) }
  />
  <PlainText
    onChange={ content => setAttributes({ title: content }) }
    value={ attributes.title }
    placeholder="Your card title"
    className="heading"
  />
  <RichText
    onChange={ content => setAttributes({ body: content }) }
    value={ attributes.body }
    multiline="p"
    placeholder="Your card text"
  />
</div>

OK, there’s a lot going on in here, but it’s all stuff we’ve covered in previous parts of this series. What we’ve got here is a container with three existing Gutenberg components. For each, we are setting the relevant attribute as its value, a relevant placeholder and an onChange/onSelect handler. We’re also passing a custom renderer to the <MediaUpload />, which we’ll cover shortly.

Each onChange handler is a handy little expression that passes the new content that triggered the onChange into the setAttributes function, where we set which attributes object to update. This update then cascades into any reference of that attribute, where the content will update like magic. The <MediaUpload /> element features an onSelect event which is fired when the user selects or uploads an item to the media library.

Speaking of the <MediaUpload /> element, you’ll notice there’s a custom render attribute, which references a getImageButton function. Let’s write that next. Above the return in the edit function add the following:

const getImageButton = (openEvent) => {
  if(attributes.imageUrl) {
    return (
      <img 
        src={ attributes.imageUrl }
        onClick={ openEvent }
        className="image"
      />
    );
  }
  else {
    return (
      <div className="button-container">
        <Button 
          onClick={ openEvent }
          className="button button-large"
        >
          Pick an image
        </Button>
      </div>
    );
  }
};

What this function does is detect if there’s an imageUrl in the attributes object. If there is, it’ll render that <img /> tag and let a user click it to select another. If there’s no image, it’ll render a WordPress <Button /> which prompts the user to pick an image. This calls the same openEvent that was passed into the function.

To keep things simple in this tutorial, we’ve bound a click to the <img /> element. You should consider building something fancy that leverages a <button /> for your production-ready blocks, for better accessibility support.

Right, that’s our edit function done. Not much code there, considering what it actually does, which is great!

Add our save function

We’ve got our Gutenberg editor-end of the block written now, which is the hard part. Now all we’ve got to do is tell Gutenberg what we want the block to do with the content. With the same reactive data from attributes, we can render out our front-end markup in real-time, too. That means when someone switches into HTML editing mode on the block, it’ll be up to date. If you edit it in HTML editing mode, the visual mode will also be kept up to date. Super useful.

Let’s dig in then. After our edit function, add a comma, so it looks like }, and then add the following on a new line:

save({ attributes }) {

  const cardImage = (src, alt) => {
    if(!src) return null;

    if(alt) {
      return (
        <img 
          className="card__image" 
          src={ src }
          alt={ alt }
        /> 
      );
    }
    
    // No alt set, so let's hide it from screen readers
    return (
      <img 
        className="card__image" 
        src={ src }
        alt=""
        aria-hidden="true"
      /> 
    );
  };
  
  return (
    <div className="card">
      { cardImage(attributes.imageUrl, attributes.imageAlt) }
      <div className="card__content">
        <h3 className="card__title">{ attributes.title }</h3>
        <div className="card__body">
          { attributes.body }
        </div>
      </div>
    </div>
  );
}

Looks pretty similar to the edit function, right? Let’s step through it.

We start of by using a destructuring assignment to pull out the attributes from the passed paramaters, just like the previous edit function.

Then we have another image helper function that firstly detects if there’s an image and returns null if there’s not one. Remember: we return null in JSX if we want it to render nothing. The next thing this helper does is render a slightly varied <img /> tag if there’s alt text or not. For the latter, it hides it from a screen-reader by adding aria-hidden="true" and setting a blank alt attribute.

Lastly, our return spits out a nice .card block with clean, BEM-driven markup that will load on the front-end of our theme.

And that is that for our save function. We’re so close to having a completed block. Just one more step to go!

Add some style

OK, we’ve got this little bit to do and we’re done. The observant amongst you may have noticed some references to className dotted about. These are referencing our editor.scss rules, so let’s add them.

Open up editor.scss, which lives in the same directory as block.js. Add the following:

@import '../common';

.gutenberg {
    
  .container {
    border: 1px solid $gray;
    padding: 1rem;
  }

  .button-container {
    text-align: center;
    padding: 22% 0;
    background: $off-white;
    border: 1px solid $gray;
    border-radius: 2px;
    margin: 0 0 1.2rem 0;
  }

  .heading {
    font-size: 1.5rem;
    font-weight: 600;
  }

  .image {
    height: 15.7rem;
    width: 100%;
    object-fit: cover;
  }
}

This is some loose CSS to give our block some card-like style. Notice it’s all nested within a .gutenberg class? This is to battle the specificity of some core styles. Within the editor, there is a <div class="gutenberg" wrapped around the block area of the post editor screen, so we can make sure to only affect those elements with this nesting. You’ll probably also notice that we’re importing another Sass file, so let’s fill that one.

Open common.scss which lives in the src directory, which is the parent of the current block directory that we’re in.

/*
 * Common SCSS can contain your common variables, helpers and mixins
 * that are shared between all of your blocks. 
 */

// Colors
$gray: #cccccc;
$off-white: #f1f1f1;

Anyway, guess what? We’ve only gone and built out a custom card block!! Let’s give it a test-drive.

First, check your block is all-good. This is what the complete block.js file should look like:

const { registerBlockType, RichText, MediaUpload, PlainText } = wp.blocks;
const { Button } = wp.components;

// Import our CSS files
import './style.scss';
import './editor.scss';

registerBlockType('card-block/main', {   
  title: 'Card',
  icon: 'heart',
  category: 'common',
  attributes: {
    title: {
      source: 'text',
      selector: '.card__title'
    },
    body: {
      type: 'array',
      source: 'children',
      selector: '.card__body'
    },
    imageAlt: {
      attribute: 'alt',
      selector: '.card__image'
    },
    imageUrl: {
      attribute: 'src',
      selector: '.card__image'
    }
  },
  edit({ attributes, className, setAttributes }) {

    const getImageButton = (openEvent) => {
      if(attributes.imageUrl) {
        return (
          <img 
            src={ attributes.imageUrl }
            onClick={ openEvent }
            className="image"
          />
        );
      }
      else {
        return (
          <div style={ styles.buttonContainer }>
            <Button 
              onClick={ openEvent }
              className="button button-large"
            >
              Pick an image
            </Button>
          </div>
        );
      }
    };

    return (
      <div className="container">
        <MediaUpload
          onSelect={ media => { setAttributes({ imageAlt: media.alt, imageUrl: media.url }); } }
          type="image"
          value={ attributes.imageID }
          render={ ({ open }) => getImageButton(open) }
        />
        <PlainText
          onChange={ content => setAttributes({ title: content }) }
          value={ attributes.title }
          placeholder="Your card title"
          className="heading"
        />
        <RichText
          onChange={ content => setAttributes({ body: content }) }
          value={ attributes.body }
          multiline="p"
          placeholder="Your card text"
          formattingControls={ ['bold', 'italic', 'underline'] }
          isSelected={ attributes.isSelected }
        />
      </div>
    );

  },

  save({ attributes }) {

    const cardImage = (src, alt) => {
      if(!src) return null;

      if(alt) {
        return (
          <img 
            className="card__image" 
            src={ src }
            alt={ alt }
          /> 
        );
      }
      
      // No alt set, so let's hide it from screen readers
      return (
        <img 
          className="card__image" 
          src={ src }
          alt=""
          aria-hidden="true"
        /> 
      );
    };
    
    return (
      <div className="card">
        { cardImage(attributes.imageUrl, attributes.imageAlt) }
        <div className="card__content">
          <h3 className="card__title">{ attributes.title }</h3>
          <div className="card__body">
            { attributes.body }
          </div>
        </div>
      </div>
    );
  }
});

If you’re happy, let’s fire up webpack. While in your current plugin directory in terminal, run this:

npx webpack --watch

This is slightly different to the previous part in the series because we’ve added the --watch argument. This basically keeps an eye on your js files and re-runs webpack if they change.

Fire up the editor!

Let’s fire up the Gutenberg editor by loading up a post in the WordPress back end. In the Gutenberg editor, click the little plus icon and look in the “blocks" tab and there it is: our awesome new card block!

Go ahead and give it a test drive and add some content in there. Feels good right?

Here’s a quick video of what you should be seeing right now, with your fancy new card block:

And with that, you’re done 🎉

Here’s a thing you might be thinking: Aren’t blocks kind of a replacement for custom fields? Can’t I now create my own content structure directly within WordPress instead of using a plugin like Advanced Custom Fields? Not quite...

Blocks vs. Custom Fields

While Gutenberg does afford us the ability to customize the structure of data entry from the user’s experience, on the back-end it’s no different than the current WYSIWYG editor. Data saved from a block is part of the post_content column in the wp_posts database table—it’s not stored separately in wp_postmeta like custom fields. This means that, at present, we cannot access the data from our card block from another post in the same way we could if we had created custom fields for title, image and content with a standard Advanced Custom Fields setup.

That said, I could see some really interesting plugins surfacing that provide a way to port data from a block to other parts of a website. With the WordPress REST API, the possibilities are just about limitless! In our screencast, Andy and I took a stab at incorporating an API request into our card block and, although things didn’t turn out exactly as planned, the tools are already in place and you can get a taste of what could be possible with Gutenberg in the future. Time will tell!

Wrapping up and next steps

What a journey we’ve been on together! Let’s list out what you’ve learned in this series:

So, where can you go from here? Now that you’ve got some solid base knowledge from this series, you could do some further learning. There’s already fantastic resources for that:

Some interesting case studies:

Keep an eye on these resources to stay up to date with the project:

Experimental things happening with Gutenberg:

Once Gutenberg becomes part of WordPress core in version 5.0 (release date TBD), you could also publish a useful custom block in the WordPress plugins directory. There’s definitely room for some handy components such as the card block that you’ve just built.

We hope you’ve enjoyed this series, because we’ve certainly enjoyed making it. We really hope this helps you get into Gutenberg and that you build some cool stuff. You should totally send us links of stuff you have built too!


Article Series:

  1. Series Introduction
  2. What is Gutenberg, Anyway?
  3. A Primer with create-guten-block
  4. Modern JavaScript Syntax
  5. React 101
  6. Setting up a Custom webpack
  7. A Custom "Card" Block (This Post)

The post Learning Gutenberg: Building Our Custom Card Block appeared first on CSS-Tricks.

13:00

A Beginner's Guide to Regular Expressions in JavaScript

Everyone working with JavaScript will have to deal with strings at one point or other. Sometimes, you will just have to store a string inside another variable and then pass it over. Other times, you will have to inspect it and see if it contains a particular substring.

However, things are not always this easy. There will be times when you will not be looking for a particular substring but a set of substrings which follow a certain pattern.

Let's say you have to replace all occurrences of "Apples" in a string with "apples". You could simply use theMainString.replace("Apples", "apples"). Nice and easy.

Now let's say you have to replace "appLes" with "apples" as well. Similarly, "appLES" should become "apples" too. Basically, all case variations of "Apple" need to be changed to "apple". Passing simple strings as an argument will no longer be practical or efficient in such cases.

This is where regular expressions come in—you could simply use the case-insensitive flag i and be done with it. With the flag in place, it doesn't matter if the original string contained "Apples", "APPles", "ApPlEs", or "Apples". Every instance of the word will be replaced with "apples".

Just like the case-insensitive flag, regular expressions offer a lot of other features which will be covered in this tutorial.

Using Regular Expressions in JavaScript

You have to use a slightly different syntax to indicate a regular expression inside different String methods. Unlike a simple string, which is enclosed in quotes, a regular expression consists of a pattern enclosed between slashes. Any flags that you use in a regular expression will be appended after the second slash.

Going back to the previous example, here is what the replace() method would look like with a regular expression and a simple string.

As you can see, the regular expression worked in both cases. We will now learn more about flags and special characters that make up the pattern inside a regular expression.

Backslash in Regular Expressions

You can turn normal characters into special characters by adding a backslash before them. Similarly, you can turn special characters into normal characters by adding a backslash before them.

For example, d is not a special character. However, \d is used to match a digit character in a string. Similarly, D is not a special character either, but \D is used to match non-digit characters in a string.

Digit characters include 0, 1, 2, 3, 4, 5, 6, 7, 8, and 9. When you use \d inside a regular expression, it will match any of these nine characters. When you use \D inside a regular expression, it will match all the non-digit characters.

The following example should make things clear.

You should note that only the first matched character is replaced in the third case. You can also use flags to replace all the matches. We will learn about such flags later.

Just like \d and \D, there are other special character sequences as well.

  1. You can use \w to match any "word" character in a string. Here, word character refers to A-Z, a-z, 0-9, and _. So, basically, it will match all digits, all lowercase and uppercase alphabets, and the underscore.
  2. You can use \W to match any non-word character in a string. It will match characters like %, $, #, ₹, etc.
  3. You can use \s to match a single white space character, which includes space, tab, form feed, and line feed. Similarly, you can use \S to match all other characters besides white space.
  4. You can also look for a specific white space character using \f, \n, \r, \t, and \v, which stand for form feed, line feed, carriage return, horizontal tab, and vertical tab.

Sometimes, you will face situations where you need to replace a word with its substitute, but only if it is not part of a larger word. For example, consider the following sentence:

"A lot of pineapple images were posted on the app".

In this case, we want to replace the word "app" with "board". However, using a simple regular expression pattern will turn "apple" into "boardle", and the final sentence would become:

"A lot of pineboardle images were posted on the app".

In such cases, you can use another special character sequence: \b. This checks for word boundaries. A word boundary is formed by use of any non-word characters like space, "$", "%", "#", etc. Watch out, though—it also includes accented characters like "ü".

Similarly, you can use \B to match a non-word boundary. For example, you could use \B to only match "app" when it is within another word, like "pineapple".

Matching a Pattern "n" Number of Times

You can use ^ to tell JavaScript to only look at the beginning of the string for a match. Similarly, you can use $ to only look at the end of the string for a match.

You can use * to match the preceding expression 0 or more times. For example, /Ap*/ will match A, Ap, App, Appp, and so on.

In a similar manner, you can use + to match the preceding expression 1 or more times. For example, /Ap+/ will match Ap, App, Appp, and so on. The expression will not match the single A this time.

Sometimes, you only want to match a specific number of occurrences of a given pattern. In such cases, you should use the {n} character sequence, where n is a number. For instance, /Ap{2}/ will match App but not Ap. It will also match the first two 'p's in Appp and leave the third one untouched.

You can use {n,} to match at least 'n' occurrences of a given expression. This means that /Ap{2,}/ will match App but not Ap. It will also match all the 'p's in Apppp and replace them with your replacement string.

You can also use {n,m} to specify a minimum and maximum number and limit the number of times the given expression should be matched. For example, /Ap{2,4}/ will match App, Appp, and Apppp. It will also match the first four 'p's in Apppppp and leave the rest of them untouched.

Using Parentheses to Remember Matches

So far, we have only replaced patterns with a constant string. For example, in the previous section, the replacement we used was always "Add". Sometimes, you will have to look for a pattern match inside the given string and then replace it with a part of the pattern.

Let's say you have to find a word with five or more letters in a string and then add an "s" at the end of the word. In such cases, you will not be able to use a constant string value as a replacement as the final value depends on the matching pattern itself.

This was a simple example, but you can use the same technique to keep more than one matching pattern in memory. The number of sub-patterns in the full match will be determined by the number of parentheses used.

Inside the replacement string, the first sub-match will be identified using $1, the second sub-match will be identified using $2, and so on. Here is another example to further clarify the usage of parentheses.

Using Flags With Regular Expressions

As I mentioned in the introduction, one more important feature of regular expressions is the use of special flags to modify how a search is performed. The flags are optional, but you can use them to do things like making a search global or case-insensitive.

These are the four commonly used flags to change how JavaScript searches or replaces a string.

  • g: This flag will perform a global search instead of stopping after the first match.
  • i: This flag will perform a search without checking for an exact case match. For instance, Apple, aPPLe, and apPLE are all treated the same during case-insensitive searches.
  • m: This flag will perform a multi-line search.
  • y: This flag will look for a match in the index indicated by the lastIndex property.

Here are some examples of regular expressions used with flags:

Final Thoughts

The purpose of this tutorial was to introduce you to regular expressions in JavaScript and their importance. We began with the basics and then covered backslash and other special characters. We also learned how to check for a repeating pattern in a string and how to remember partial matches in a pattern in order to use them later.

Finally, we learned about commonly used flags which make regular expressions even more powerful. You can learn more about regular expressions in this article on MDN.

If there is anything that you would like me to clarify in this tutorial, feel free to let me know in the comments.

12:32

Introduction to Popmotion: Custom Animation Scrubber

In the first part of the Popmotion introductory series, we learned how to use time-based animations like tween and keyframes. We also learned how to use those animations on the DOM, using the performant styler.

In part two, we learned how to use pointer tracking and record velocity. We then used that to power the velocity-based animations springdecay, and physics.

In this final part, we're going to be creating a scrubber widget, and we're going to use it to scrub a keyframes animation. We'll make the widget itself from a combination of pointer tracking as well as spring and decay to give it a more visceral feel than run-of-the-mill scrubbers.

Try it for yourself:

Getting Started

Markup

First, fork this CodePen for the HTML template. As before, because this is an intermediate tutorial, I won't go through everything.

The main twist of note is that the handle on the scrubber is made up of two div elements: .handle and .handle-hit-area.

.handle is the round blue visual indicator of where the scrubber handle is. We've wrapped it in an invisible hit area element to make grabbing the element easier for touchscreen users.

Import Functions

At the top of your JS panel, import everything we're going to use in this tutorial:

Select Elements

We're going to need three elements in this tutorial. We'll animate the .box, drag and animate the .handle-hit-area, and measure the .range.

Let's also create stylers for the elements we're going to animate:

Keyframes Animation

For our scrubbable animation, we're going to make the .box move from left to right with keyframes. However, we could just as easily scrub a tween or timeline animation using the same method outlined later in this tutorial.

Your animation will now be playing. But we don't want that! Let's pause it for now:

Dragging the x-axis

It's time to use pointer to drag our scrubber handle. In the previous tutorial, we used both x and y properties, but with a scrubber we only need x.

We prefer to keep our code reusable, and tracking a single pointer axis is quite a common use case. So let's create a new function called, imaginatively, pointerX.

It will work exactly like pointer except it'll take just a single number as its argument and output just a single number (x):

Here, you can see we're using a method of pointer called pipepipe is available on all the Popmotion actions we've seen so far, including keyframes.

pipe accepts multiple functions. When the action is started, all output will be passed through each of these functions in turn, before the update function provided to start fires.

In this case, our function is simply:

All it is doing is taking the { x, y } object usually output by pointer and returning just the x axis.

Event Listeners

We need to know if the user has started pressing the handle before we start tracking with our new pointerX function.

In the last tutorial we used the traditional addEventListener function. This time, we're going to use another Popmotion function called listenlisten also provides a pipe method, as well as access to all action methods, but we're not going to use that here.

listen allows us to add event listeners to multiple events with a single function, similar to jQuery. So we can condense the previous four event listeners to two:

Move the Handle

We'll be needing the handle's x velocity later on, so let's make it a value, which as we learned in the last tutorial allows us to query velocity. On the line after we define handleStyler, add:

Now we can add our startDrag and stopDrag functions:

Right now, the handle can be scrubbed beyond the boundaries of the slider, but we'll come back to this later.

Scrubbing

Now we have a visually functional scrubber, but we're not scrubbing the actual animation.

Every value has a subscribe method. This allows us to attach multiple subscribers to fire when the value changes. We want to seek the keyframes animation whenever handleX updates.

First, measure the slider. On the line after we define range, add:

keyframes.seek accepts a progress value as expressed from 0 to 1, whereas our handleX is set with pixel values from 0 to rangeWidth.

We can convert from the pixel measurement to a 0 to 1 range by dividing the current pixel measurement by rangeWidth. On the line after boxAnimation.pause(), add this subscribe method:

Now, if you play with the scrubber, the animation will scrub successfully!

The Extra Mile

Spring Boundaries

The scrubber can still be pulled outside the boundaries of the full range. To solve this, we could simply use a clamp function to ensure we don't output values outside of 0, rangeWidth.

Instead, we're going to go the extra step and attach springs to the end of our slider. When a user pulls the handle beyond the permitted range, it will tug back towards it. If the user releases the handle while it's outside the range, we can use a spring animation to snap it back.

We'll make this process a single function that we can provide to the pointerX pipe method. By creating a single, reusable function, we can reuse this piece of code with any Popmotion animation, with configurable ranges and spring strengths.

First, let's apply a spring to the left-most limit. We'll use two transformersconditional and linearSpring.

conditional takes two functions, an assertion and a transformer. The assertion receives the provided value and returns either true or false. If it returns true, the second function will be provided the value to transform and return.

In this case, the assertion is saying, "If the provided value is smaller than min, pass this value through the linearSpring transformer." The linearSpring is a simple spring function that, unlike the physics or spring animations, has no concept of time. Provide it a strength and a target, and it will create a function that "attracts" any given value towards the target with the defined strength.

Replace our startDrag function with this:

We're now passing the pointer's x offset through our springRange function, so if you drag the handle past the left-most side, you'll notice it tugs back.

Applying the same to the right-most side is a matter of composing a second conditional with the first using the stand-alone pipe function:

Another benefit of composing a function like springRange is that it becomes very testable. The function it returns is, like all transformers, a pure function that takes a single value. You can test this function to see if it passes through values that lie within min and max unaltered, and if it applies springs to values that lie without.

If you let go of the handle while it lies outside the range, it should now spring back to within range. For that, we'll need to adjust the stopDrag function to fire a spring animation:

Our snapHandleToEnd function looks like this:

You can see that to is set either as 0 or rangeWidth depending on which side of the slider the handle currently sits. By playing with damping and stiffness, you can play with a range of different spring-feels.

Momentum Scrolling

A nice touch on iOS scrubber that I always appreciated was that if you threw the handle, it would gradually slow down rather than come to a dead stop. We can replicate that easily using the decay animation.

In stopDrag, replace handleX.stop() with momentumScroll(x).

Then, on the line after the snapHandleToEnd function, add a new function called momentumScroll:

Now, if you throw the handle, it will come to a gradual stop. It will also animate outside the range of the slider. We can stop this by passing the clamp transformer to the decay.pipe method:

Conclusion

Using a combination of different Popmotion functions, we can create a scrubber that has a bit more life and playfulness than the usual.

By using pipe, we compose simple pure functions into more complex behaviours while leaving the composite pieces testable and reusable.

Next Steps

How about trying these challenges:

  • Make the momentum scroll end with a bounce if the handle hits either end of the scrubber.
  • Make the handle animate to any point on the scrubber when a user clicks on another part of the range bar.
  • Add full play controls, like a play/pause button. Update the scrubber handle position as the animation progresses.
10:00

Getting Started With CSS Layout

Getting Started With CSS Layout

Getting Started With CSS Layout

Rachel Andrew
2018-05-25T12:00:19+02:002018-05-25T13:49:32+00:00

Over the past couple of years, CSS Layout has dramatically changed as well as the way we develop the front end of our sites. We now have a real choice in terms of the layout methods we use in CSS to develop our sites, which means we often need to make a choice as to which approach to take. In this article, I will run through the various layout methods that you have available to you by explaining the basics of how they are used and what they are used for.

This guide is for you if you are fairly new to CSS and wondering what the best way to approach layout is, but also if you are an experienced developer from elsewhere in the stack who wants to make sure your understanding of layout today is up to date. I have not tried to fully document each layout method here, as that would have created a book and not an article. Instead, I am giving an overview of what is available to you, with plenty of links to find out more.

Normal Flow

If you take an HTML webpage which has no CSS applied to change the layout, the elements will display in normal flow. In normal flow, boxes are displayed one after another based on the Writing Mode of the document. This means that if you have a horizontal writing mode, one in which sentences run left to right or right to left, normal flow will display the boxes of block level elements one after the other vertically down the page.

What if there was a web conference without... slides? Meet SmashingConf Toronto 2018 🇨🇦 with live sessions exploring how experts work behind the scenes. Dan Mall, Lea Verou, Sara Soueidan, Seb Lee-Delisle and many others. June 26–27. With everything from live designing to live performance audits.

Check the speakers →

If you are in a vertical writing mode, then sentences run vertically so normal flow would lay the blocks out horizontally.

Shows how the Block Axis is horizontal in a vertical writing mode and vertical in a horizontal writing mode Block and Inline Directions change with Writing Mode

Normal flow is where you begin with any layout: when you create a CSS Layout, you are taking the blocks and causing them to do something other than normal flow.

Structure Your Document To Take Advantage Of Normal Flow

You can take advantage of normal flow by ensuring your document starts out in a well-structured manner. Imagine if — instead of this concept of normal flow — the browser piled all your boxes up in the corner on top of each other until you created a layout. That would mean you would have to place every single thing on the page. Instead, the browser displays our content in an immediately readable way.

If your CSS fails to load, the user can still read the content, and users who don’t get CSS at all (e.g. someone using a screen reader) will have the content delivered to them in the order it is in the document. This makes it important from an accessibility point of view that your HTML document starts life in a good order; however, it will also make your life easier as a web developer. If your content is in the order a user would expect to read it, you won’t need to make massive changes to layout to get it into the right place. With newer layout methods you may be surprised how little you have to do.

Therefore, before thinking about layout, think about document structure and the order you would want your content to be read in from the top of the document to the bottom.

Moving Away From Normal Flow

Once we have a well-structured document, we need to decide how to take that and turn it into our desired layout. This will involve moving away from normal flow, for parts of our document. We have a whole set of layout methods to use. The first method we will take a look at is float, as floats are an excellent demonstration of what it is to take an element out of normal flow.

Floats

Floats are used to shift a box to the left or right, allowing content to display wrapped around it.

In order to float an item, use the CSS property float and a value of left or right. The default value of float is none.

.item {
    float: left;
}

It is worth noting that when you float an item and text wraps around it, that what happens is the line boxes of that content are shortened. If you float an item and the following box containing your text has a background color applied, you can see that this background color will then run underneath the floated item.

A block floated left, background color on the text to the right on it runs under the block The background color on the content runs under the float

As you are shortening the line boxes in order to make space between the float and the wrapping text, you must set a margin on the floated item. A margin on the text would just move the text in from the edge of the container. For an image floated left, you would add a margin to the right and bottom assuming that you want the image flush with the top and left of the container.

See the Pen Smashing Guide to Layout: float by Rachel Andrew (@rachelandrew) on CodePen.

Clearing Floats

Once you have floated an element, all of the following elements will wrap around that floated element until they wrap underneath and normal flow continues. If you want to prevent that, you need to clear the float.

On the element that you want to begin displaying after the float, add the property clear with a value of left to indicate clearing an item floated left, right to clear an item floated right, or both to clear any floats.

.clear {
    clear: both;
}

The above method works if you want an element to start after a float. It won’t help if you find yourself in a situation where you have a floated item inside a box, with some text alongside. If the text is shorter than the floated item, the box will be drawn underneath the content and ignore the float. As we have already learned, floats shorten the line boxes, the rest of the layout continues in normal flow.

The floated box is poking out of the bottom of the container The box around the text does not clear the float

To prevent this situation we need to clear something inside the box. We could add an empty element and set that to clear all. This involves sticking empty divs into our document which isn’t ideal and may not be possible if your page is generated by a CMS. So instead, the typical clearing floats method is what is known as a clear fix hack. This method works by adding CSS Generated Content, and setting that to clear both.

See the Pen Smashing Guide to Layout: clearfix by Rachel Andrew (@rachelandrew) on CodePen.

The Block Formatting Context

Another way to clear floats inside a box is to invoke a Block Formatting Context (BFC) on the container. A Block Formatting Context contains everything inside it, which would include floated items which can no longer poke out the bottom of the box. There are a few ways to force a BFC, the most common when clearing floats is to set the overflow property to have a value other than the default visible.

.container {
    overflow: auto;
}

Using overflow in this way will generally work, however, in certain situations you could end up with clipped shadows or unwanted scrollbars on the item. It also can look a little confusing in your stylesheet: Did you set overflow because you wanted scrollbars or just to gain this clearing ability?

To make intent clearer and prevent the creation of a BFC causing unwanted side effects, you can use flow-root as a value of the display property. The only thing that display: flow-root does is to create a BFC, thus clearing your floats with no other problems caused.

.container {
    display: flow-root;
}

Legacy Usage Of Floats

Until the arrival of newer layout methods floats were used to create column layouts, this technique worked by giving a set of items a width and setting them to float up next to one another. Careful management of the percentage size of these floated boxes could create a grid effect.

I would not suggest starting a new design now and using this method. However, it will remain in existing sites for many years to come. Therefore, if you come across a design where almost everything seems to be floated, this is the technique in use.

Resources And Further Reading On Floats And Clearing Floats

Positioning

To remove an element from normal flow or shift it around from its place in normal flow, you can use the position property in CSS. When in normal flow, elements have a position of static. The items display one after the other in the Block dimension and if you scroll the page they scroll with it.

When changing the value of position you will typically be also using offset values to move the box around from a particular reference point. The reference point used depends on the value of position you are using.

Relative Positioning

If an item has position: relative then the reference point is the place it would normally be in normal flow. You can then use offset values for the properties top, left, bottom and right to move the box from where it would normally be displayed.

.item {
    position: relative;
    bottom: 50px;
}

Note that other items on the page do not respond to the new position of your element. The place it was positioned in normal flow is reserved, therefore you need to manage any overlaps yourself.

See the Pen Smashing Guide to Layout: relative positioning by Rachel Andrew (@rachelandrew) on CodePen.

Absolute Positioning

Set position: absolute on an item and it will be removed completely from normal flow. The space that was left for it will be removed. The item will then be positioned relative to its containing block which, unless it is nested inside another positioned element, will be the viewport.

Therefore, the first thing that will happen if you set position: absolute on an item is that it typically ends up stuck to the top and left of the viewport. You can then use offset values for the properties top, left, bottom and right to move the box from that position to where you want it to be.

.item {
    position: absolute;
    top: 20px;
    right: 20px;
}

Often you don’t want the box positioned according to the viewport, but in reference to a containing element, it is inside. In which case you need to give that containing element a position value other than the default static.

As setting position: relative does not remove the item from normal flow, this is the usual choice. Give the parent element that you wish to set your offsets from position: relative and then offset the absolutely positioned block from the boundaries of that element.

See the Pen Smashing Guide to Layout: absolute positioning by Rachel Andrew (@rachelandrew) on CodePen.

Fixed Positioning

Something with position: fixed will be positioned in most cases relative to the viewport, and removed from document flow so that no space is reserved for it. When the page is scrolled, the fixed element remains in position relative to the viewport as the rest of the content in normal flow scrolls as usual.

.item {
    position: fixed;
    top: 20px;
    left: 100px;
}

This can be helpful to enable a fixed navigation panel which stays on screen, e.g. while the content scrolls. As with other positioning values, you may cause overlaps when doing this so you should take care that all the content can be read and doesn’t end up behind a fixed item.

See the Pen Smashing Guide to Layout: Fixed positioning by Rachel Andrew (@rachelandrew) on CodePen.

To position a fixed item other than relative to the viewport, you need to have a containing element with one of the transformperspective, or filter properties set to something other than their default value of none. In this case, that element will become the containing block and your offsets with relate to that block rather than the viewport.

Sticky Positioning

Setting position: sticky on an element will cause the element to scroll with the document just as it would in normal flow, however, once it reaches a certain point in relation to the viewport (using the usual offsets) it “sticks” and starts to act like position: fixed. This is a newer value and is less well supported in browsers than other methods, however, it falls back to just scrolling with the page os is a value nicely used as an enhancement without causing problems if it is not supported.

.item {
    position: sticky;
    top: 0;
}

This is how to create the popular effect of a navigation bar scrolling with the content and then stopping at the top of the viewport to stay onscreen as you scroll the content.

See the Pen Smashing Guide to Layout: sticky positioning by Rachel Andrew (@rachelandrew) on CodePen.

Resources And Further Reading On Positioning

Flex Layout

Flexible Box Layout (Flexbox) is a layout method designed for one-dimensional layout. One-dimensional means that you wish to lay out your content in a row, or as a column. To turn your element into a flex layout, you use the display property with a value of flex.

.container {
    display: flex;
}

The direct children of that element become flex items, they will lay out as a row, aligned to the start edge in the inline direction.

See the Pen Smashing Guide to Layout: flex by Rachel Andrew (@rachelandrew) on CodePen.

The Axes Of Flexbox

In the above example, I described out items as being laid out aligned to the start edge of our row in the inline direction, rather than describing them as being aligned to the left. Our items are laid out in a row because the default value of the flex-direction property is row, this creates a row in the inline direction, the direction along which sentences run. As we are working in English, a left-to-right language, the start of a row is on the left and so our items start there. The value of flex-direction thus defines the main axis of Flexbox.

The cross axis, therefore, runs across the main axis at right angles. If your flex-direction is row and your items are displayed in the inline direction, your cross axis runs in the Block direction. If your flex-direction is column so the items are running in the Block direction then your cross axis is along the row.

If you get used to thinking in terms of main and cross axis when working with Flexbox, it will make many things easier.

Direction And Order

Flexbox gives you the ability to change the direction of items on the main axis by using a flex-direction value of row-reverse or column-reverse.

See the Pen Smashing Guide to Layout: flex-direction by Rachel Andrew (@rachelandrew) on CodePen.

You can also change the order of individual flex items with the order property. However, you should take great care when doing so as this can cause a problem for any user who is navigating using the keyboard rather than a mouse or touchscreen as the tab order of the document will follow the order the content is in the source. See the section below on Visual and Document Order for more details.

The Flex Properties

The flex properties are how to control the ratios of flex items along the main axis. The three properties are:

  • flex-grow
  • flex-shrink
  • flex-basis

These are usually used in their shorthand form of the flex property, the first value being flex-grow, the second flex-shrink and the third flex-basis.

.item {
    flex: 1 1 200px;
}

The value of flex-basis gives a size that the item will have before any growing or shrinking takes place. In the above example, that size is 200 pixels, so we would give each item 200 pixels of space. It is unlikely that our container will neatly divide by 200 pixels and so there will be space leftover or not enough space for all of the items if they each have 200 pixels. The flex-grow and flex-shrink properties allow us to control what happens to the items if there is too much or not enough space for them.

If flex-grow is set to any positive value, then the item is allowed to grow to take up space. Therefore, in our example above, after giving each item 200 pixels, any extra space will be shared out between the items.

If flex-shrink is set to a positive value, then the item can shrink in the situation where an overflow would happen if all of the items were given their flex-basis. If there was not enough space in the container in our example, each item would shrink an equal amount to reduce until all the items fit in the container.

The flex-grow and flex-shrink values can be any positive value. An item with a greater flex-grow value will be given more of the available space in proportion when growing, and with a greater flex-shrink value more will be removed when shrinking.

See the Pen Smashing Guide to Layout: flex properties by Rachel Andrew (@rachelandrew) on CodePen.

Understanding the way that these flex properties work is really the key to understanding Flexbox, and the resources listed below will give you all of the detail. However, consider using Flexbox when you have a bunch of things that you want to stretch and squish into a container in one dimension. If you find yourself trying to line things up in rows and columns, you want a Grid, and in that case Flexbox probably isn’t the tool for the job.

Resources And Further Reading For Flex Layout

Grid Layout

CSS Grid Layout was designed as a two-dimensional layout method. Two-dimensional means that you wish to lay your content out in rows and columns. As with Flexbox, Grid Layout is a value of display and so to start using Grid you should start with display: grid on your container, and then set up some columns and/or rows using the grid-template-columns and grid-template-rows properties.

.container {
    display: grid;
    grid-template-columns: 200px 200px 200px;
    grid-template-rows: 200px 200px;
}

The above CSS would create a fixed size grid, with completely fixed column and row tracks. This probably isn’t what you want on the web, and Grid has you well covered. The default for any track is auto, which can generally be thought of as “big enough for the content.” If we didn’t create any row tracks, then rows would be created for us to take any content added, and these would be auto sized. A common pattern is to specify column tracks but allow Grid to create rows as required.

While you can set up your column and row tracks using any length unit or a percentage, you can also use the new fr unit, a unit created for Grid Layout. The fr unit is a flex unit, and denotes a share of the available space in the grid container.

Grid can distribute space for you; you don’t need to calculate percentages to ensure things fit into a container. In the example below, we are creating columns using the fr unit and allowing tracks to create automatically. We are also using grid-gap to space out our tracks (see the section on Box Alignment for more details about gaps and grid layout).

See the Pen Smashing Guide to Layout: a simple grid by Rachel Andrew (@rachelandrew) on CodePen.

As with Flexbox and flex-grow or flex-shrink, the fr unit deals with sharing out available space. A higher fr value for one track means it gets more of the available space in proportion. You can also mix fr units and absolute lengths. The space needed for the lengths will be subtracted from the available space before working out the fr units.

See the Pen Smashing Guide to Layout: fr units and absolute lengths by rachelandrew (@rachelandrew) on CodePen.

Grid Terminology

A Grid always has two axes: the Inline Axis runs in the direction that words are laid out on the page and the Block Axis in the direction that blocks are laid out.

The Grid Container is the element that you have set display: grid on. You then have Grid Lines, created by the column and row tracks you have specified when using grid-template-columns and grid-template-rows. The smallest unit on the grid (between four intersecting lines) is known as a Grid Cell, while a collection of Grid Cells that make up a complete rectangle is called a Grid Area.

Image shows a grid with column and row lines highlighted Grid Lines run between each track of the grid.Image shows a column track highlighted on the grid Grid Tracks are between any two linesImage shows a grid with several one cell areas and an area spanning two rows and two columns. Grid cells are the smallest unit on the grid, a Grid Area is one or more cells together making a rectangular area

Grid Auto-Placement

As soon as you create a Grid, the direct children of your grid container begin to lay themselves out, one in each cell of the grid. They do this according to the grid auto-placement rules. These rules ensure that each item is placed in an empty cell avoiding overlapping items.

Any direct child of the grid container which you have not given a position to will be placed according to the auto-placement rules. In the below example, I have caused every third item to span two-row tracks, while still being auto-placed in terms of the start line.

See the Pen Smashing Guide to Layout: auto-placement by Rachel Andrew (@rachelandrew) on CodePen.

Basic Line-Based Positioning

The simplest way to position items on the Grid is with line-based positioning, giving the item rules to tell it to span from one line of the grid to another. For example, if I have a grid with three column tracks and two-row tracks, I can place an item from column line 1 to column line 3, and row line 1 to row line 3. It will then cover four grid cells in total, spanning two column tracks and two column rows.

.item {
    grid-column-start: 1;
    grid-column-end: 3;
    grid-row-start: 1;
    grid-row-end: 3;
}

These properties can be represented as a shorthand, grid-column and grid-row with the first value being start and the second end.

.item {
    grid-column: 1 / 3;
    grid-row: 1 / 3;
}

Grid Items can occupy the same cells, enabling the creation of designs with overlapping content. Items stack up in the usual way that content stacks on the web, with items lowering down the source appearing on the top of other items. Still, you can use z-index to control this.

See the Pen Smashing Guide to Layout: line-based placement by Rachel Andrew (@rachelandrew) on CodePen.

Positioning With Named Areas

You can also position items on your grid by using Named Areas. To use this method you give each item a name, and then describe the layout as the value of the grid-template-areas property.

.item1 {
    grid-area: a;
}

.item2 {
    grid-area: b;
}

.item3 {
    grid-area: c;
}

.container {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr;
    grid-template-areas: 
     "a a b b"
     "a a c c";
}

There are a few rules to remember when using this method. If you want an item to span multiple cells then you should repeat the name. Areas need to form a complete rectangle, no L-shaped or Tetris pieces allowed! The grid must be complete — every cell must be filled. If you want to leave white space then fill that cell with a .. For example, in the below CSS I am leaving the bottom right corner empty.

.container {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr;
    grid-template-areas: 
     "a a b b"
     "a a c .";
}

This is a nice way to work as anyone looking at the CSS can see exactly how the layout will work.

See the Pen Smashing Guide to Layout: grid-template-areas by rachelandrew (@rachelandrew) on CodePen.

Resources And Further Reading For Grid Layout

There is much more to CSS Grid Layout than this quick overview has shared, and the resources below will help you to learn the specification. Components and your full page layout alike can be grids, choose Grid Layout if you have a two-dimensional layout to create — no matter how large or small.

  • CSS Grid Layout,” Web technology for developers, MDN web docs, Mozilla
  • Grid by Example,” Everything you need to learn CSS Grid Layout, Rachel Andrew
  • Grid Garden,” A fun interactive game to test and improve your CSS skills
  • Layout Land,” Jen Simmons, YouTube

I’ve also written a number of articles here on Smashing Magazine that can help you dig into various Grid concepts:

Visual And Document Order

At the beginning of this article, I suggested that you start with your document in an order that makes sense read top to bottom, as this would be helpful both for accessibility and in terms of the way that CSS layout works. From our short introduction to Flexbox and CSS Grid, you can see that it would be possible to move things around quite dramatically away from that order. This has the potential to cause a problem.

Browsers will follow the document source for any non-visual use of the document. Therefore, a screen reader will read out the document order and anyone using a keyboard to navigate will tab through the document in the order it is in the source and not the display order. Many screen readers users are not completely blind, and so may be using the screen reader alongside being able to see where they are in the document. For both of these cases, a display which is jumbled up when compared to the source could cause a very confusing situation indeed.

Be very aware when you are moving elements way from the order they are in the source. If you find yourself rearranging the order of items in CSS, should you really be going back and reorganizing your document? Test to see if you can still tab around your document and the visual order make sense.

Resources And Further Reading For Visual And Document Order

Box Generation

Everything you put on a web page creates a box, and everything in this article describes how you can use CSS to layout those boxes in your design, however, in certain circumstances you may not want to create a box at all. There are two values of the display property that deal with situations where you do not want boxes.

Do Not Generate The Box Or Contents (display: none)

If you want the element and all of the content of that element, including any child items, to not be generated you can use display: none. The element will now not be displayed, and no space will be reserved for where it would have been.

.item {
    display: none;
}

Do Not Generate This Element, But Generate Any Child Elements (display: contents)

A newer value of display is display: contents. Apply display: contents to an element and the box for that element will not be generated but any children will be generated as normal. This can be helpful if you want indirect child elements to become part of a flex or grid layout.

In the example below, the first flex item contains two nested children, yet as it is set to display: contents its box is not rented and the children display as if they were the direct child and become flex items. Remove display: contents from that element to see how the layout changes.

See the Pen Smashing Guide to Layout: display: contents by Rachel Andrew (@rachelandrew) on CodePen.

Resources And Further Reading For Box Generation

Alignment

Alignment has been something of a tricky subject on the web until recently, with very limited ways to properly align items inside boxes. This is changing with the Box Alignment Module, which currently you will use when controlling alignment in Grid and Flex containers. In the future, other layout methods will also implement these alignment properties. The list of alignment properties detailed in the Box Alignment specification is as follows:

  • justify-content
  • align-content
  • place-content
  • justify-items
  • align-items
  • place-items
  • justify-self
  • align-self
  • place-self
  • row-gap
  • column-gap
  • gap

As layout models have different features, alignment works slightly differently depending on the layout model in use. Let’s take a look at how alignment works with some simple Grid and Flex Layouts.

The align-items and justify-items properties set the align-self and justify-self properties as a group. These properties align the items inside their Grid Area.

See the Pen Smashing Guide to Layout: align-items, justify-items, align-self, justify-self by Rachel Andrew (@rachelandrew) on CodePen.

The align-content and justify-content properties align the grid tracks, where there is more space in the Grid Container than is needed to display the tracks.

See the Pen Smashing Guide to Layout: align-content, justify-content by Rachel Andrew (@rachelandrew) on CodePen.

In Flexbox, align-items and align-self deal with alignment on the Cross Axis, while justify-content deals with space distribution on the main axis.

See the Pen Smashing Guide to Layout: Flex justify-content, align-items, align-self by Rachel Andrew (@rachelandrew) on CodePen.

On the cross axis, you can use align-content where you have wrapped flex lines and additional space in the flex container.

See the Pen Smashing Guide to Layout: flex align-content by Rachel Andrew (@rachelandrew) on CodePen.

See the resources for some links that discuss Box Alignment in detail across layout methods. It really is worth spending some time understanding how alignment works, as it will make working with Flexbox, Grid and future layout methods far easier.

Row And Column Gaps

A multiple-column layout has the column-gap property, and the Grid Layout spec had — until recently — the properties grid-column-gap, grid-row-gap, and grid-gap. These have now been removed from the Grid specification and added to Box Alignment. At the same time, the grid- prefixed properties were renamed to column-gap, row-gap, and gap. Browsers will alias the prefixed properties to the new renamed ones so you do not need to worry if you are using the better supported old names in your code right now.

The renaming means that these properties can be also applied to other layout methods, the obvious candidate being Flexbox. While no browser supports gaps in Flexbox at the moment, in future we should be able to use column-gap and row-gap to create space between flex items.

Resources And Further Reading For Alignment

Is your pattern library up to date today? Alla Kholmatova has just finished a fully fledged book on Design Systems and how to get them right. With common traps, gotchas and the lessons she learned. Hardcover, eBook. Just sayin'.

Table of Contents →

Multi-Column Layout

A multiple-column layout is a layout type that enables the creation of columns, such as you might find in a newspaper. A block is split into columns, and you read down a column in the block direction then return to the top of the next column. While reading content in this way is not always useful in a web context as people don’t want to have to scroll up and down to read, it can be a helpful way to display small amounts of content or to collapse down sets of checkboxes or other small UI elements.

A multiple-column layout can also be used to display sets of cards or products which have differing heights.

Setting A Column Width

To set an optimal column width, and instruct the browser to display as many columns as possible at that width use the following CSS:

.container {
    column-width: 300px;
}

This will create as many as 300 pixel columns as possible, any leftover space is shared between the columns. Therefore, unless your space divides into 300 pixels with no remainder, it is likely that your columns will be slightly wider than 300 pixels.

Setting A Number Of Columns

Instead of setting the width, you could set a number of columns using column-count. In this case, the browser will share the space between the number of columns you have asked for.

.container {
    column-count: 3;
}

If you add both column-width and column-count, then the column-count property acts as a maximum. In the below code, columns will be added until there are three columns, at which point any extra space will be shared between those three columns even if there was enough space for an additional column.

.container {
    column-width: 300px;
    column-count: 3;
}

Gaps And Column Rules

You cannot add margins or padding to individual column boxes, to space out columns use the column-gap property. If you do not specify a column-gap, it will default to 1em to prevent columns bumping up against each other. This is a different behavior to the way column-gap is specified for other layout methods, where it defaults to 0. You can use any length unit for your gap, including 0 if you want no gap at all.

The column-rule property gives you the ability to add a rule between two columns. It is a shorthand for column-rule-width, column-rule-color, and column-rule-style, and acts in the same way as border. Note that a rule does not take up any space of its own. It lays on top of the gap so to increase or decrease space between the rule and the content you need to increase or decrease the column-gap.

See the Pen Smashing Guide to Layout: multicol by Rachel Andrew (@rachelandrew) on CodePen.

Allowing Elements To Span Columns

You can span an element inside the multicol container across all of the columns using the column-span property on that element.

h3 {
    column-span: all;
}

When a column-span happens, the multicol container essentially stops above the spanning element, therefore, the content forms into columns above the element and then remaining content forms a new set of column boxes below the spanning element.

See the Pen Smashing Guide to Layout: multicol span by Rachel Andrew (@rachelandrew) on CodePen.

You can only use column-span: all or column-span: none; it isn’t possible to span some of the columns. At the time of writing, Firefox does not support the column-span property.

Resources And Further Reading For Multiple-Column Layout

Fragmentation

Multiple-Column Layout is an example of fragmentation. In this case, the content is broken into columns. It is, however, very similar to the way that content is broken into pages when printing. This process is dealt with by the Fragmentation specification, and this specification contains properties to help control the breaking of content.

For example, if you have laid out a set of cards using multicol and you want to make sure that a card never breaks in half, becoming split between two columns you can use the property break-inside with a value of avoid. Due to browser compatibility reasons, you will also want to use the legacy page-break-inside property as well.

.card {
    page-break-inside: avoid;
    break-inside: avoid;
}

If you want to avoid a break directly after a heading, you can use the break-after property.

.container h2 {
    page-break-after: avoid;
    break-after: avoid;
}

These properties can be used when preparing a print stylesheet and also in multicol. In the example below, I have three paragraphs in a multicol container that fragments into three columns. I have given break-inside: avoid to the p element meaning that the paragraphs end up one in each column (even if this makes the columns uneven).

See the Pen Smashing Guide to Layout: multicol fragmentation by Rachel Andrew (@rachelandrew) on CodePen.

Resources And Further Reading For Fragmentation

Selecting Layout Types: How To Choose?

Most web pages will use a mixture of these layout types, and each spec defines exactly how they interact with each other. For example, you might have a Grid Layout in which some Grid Items are also Flex containers. Some of those flex containers might be a containing block for a positioned item or have an image floated inside. The specifications are written with an expectation that we will be mixing layout models, according to what is best for the content that we are laying out. In this guide, I have tried to give an overview of the basic way that each layout type behaves, in order to help you hone in on what is likely to be the best way to achieve a particular effect.

However, don’t be afraid to play around with different ways of creating the design you have in mind. There are fewer places than you might imagine where you should worry about your choices causing any real problem. Start with a good document structure, and take care that you are not disconnecting the visual display from that order. Much of the rest is just a case of testing that things work as you expect in your target browsers.

Smashing Editorial(il)
03:50
11 Amazing jQuery Plugins To Handle Images On Your Websites

May 24 2018

15:43

Top Invoicing and Time Management Apps of 2018

When we perform a task, we try to use our time wisely. That can involve planning ahead, learning or refining a process. It can also mean avoiding or eliminating distractions. The task might involve manual or repetitive actions, however. In this case, we can only accomplish so much in a given amount of time. No matter how proficient we become, we eventually hit a plateau. Meanwhile, the world around us continues to speed up.

There is a solution to making the most effective use of your time. It is to turn the task, whatever it may be, over to someone or something else; a software system or an app for example.

Let the software do the scheduling, tracking, reporting, invoicing, etc., etc. for you. The task will get done “lickety-split”. You’ll find yourself with minutes, and eventually, hours, to spare. You can devote these to improving your productivity and/or building your business.

Get started with one or more of these time management and invoicing apps.

  1. FreshBooks

FreshBooks is an ideal expense managing, time tracking, invoicing, and proposal generating tool for service-oriented businesses. It allows users to avoid manual, time-consuming data collection and reporting, and all of the errors that can occur when transferring information from one place to another.

Expense and time tracking data is easily converted into personalized invoices for specific clients and can be sent instantly without leaving FreshBooks. Your clients get an emailed invoice which allows them to pay directly online through the invoice itself. FreshBooks really simplifies the billing and payment processes.

The FreshBooks proposal generating feature provides you with a framework where you can define a project’s scope, outline, timeline, and estimate. Once a proposal is accepted it can be converted into a branded invoice to save you even more time.

FreshBooks is super-intuitive, its learning curve is for all intents and purposes nearly flat, and the award-winning support team is superb. Try it free for 30 days.

  1. Jibble.io

Project managers will appreciate what Jibble brings to the table. This cloud-based time and attendance tracking app provides time sheets and reports on a daily, weekly, and monthly basis, or on demand. The weekly and monthly timesheets will be particularly supportive of your payroll review exercises, while the daily reports serve to ensure that you are always kept up to speed on your team’s/staff’s daily efforts and accomplishments.

Timesheets can be downloaded in spreadsheet formats to support accounting activities, and Jibble can also provide personal timesheets that can be added to by team or staff members.

Jibble calculates and reports average daily or weekly hours worked on a team or team member basis; including clock in and out times when appropriate with alerts noted when averages fall outside a selected range.

Jibble also tracks and reports expenses, client billing, and time and attendance for multiple projects.

  1. Invoice Plane

 

            The designers of this invoicing and client management app targeted freelancers, self-employed individuals, and small businesses as its primary users. Invoice Plane is an open source software product that is currently in use in 193 countries. It has been downloaded an estimated 100,000+ times, and you’re invited to download it also – for free.

The authors recommend that you view the demo first. Chances are, you’ll like what you see, and you’ll be ready to put Invoice Plane to work at your first opportunity, as it gives you an easy, cost-effective way to manage your billing cycles and coordinate invoices and payments with your clients.

You won’t have to worry about any constraints as to how you prepare and manage your invoices either. Invoice Plane’s templates and themes are easily customizable to meet your business model.

  1. TimeCamp

            Check the status of your workforce and project activities from your desktop or with a mobile app with TimeCamp. This time and attendance tracking app integrates seamlessly with your helpdesk, accounting, or project management applications; enabling you to view your billing status all the time and at any time. TimeCamp is free for freelancers and self-employed individuals.

  1. AND CO from Fiverr

AND CO will be a good choice for freelancers or studios in need of a time tracking, invoicing and payments application. AND CO is easy to use, its design is clean and attractive, and it can be adjusted to fit your workflow and business needs.

You can also use this time tracking and invoicing app to assist you in preparing your client proposals.

  1. Hiveage

If you work for a small business or are a small business owner, and you’re looking for a way to improve your invoicing and billing process, you might consider joining 60,000 other businesses that have chosen Hiveage to manage not only their invoicing and billing but prepare quotations and provide attractive client payment options as well.

Hiveage can also efficiently manage multiple teams’ projects.

  1. Invoice Ninja

Invoice Ninja is a suite of freelancer & small business apps. Streamline your invoicing, time-tracking, project task management, proposal creations, and much more. Invoice Ninja is free, open-source, and also integrates with over 40 payment gateways!

  1. Scoro

If double data entry and working from spreadsheets is taking up too much of your time, Scoro has the answer. This business management software will handle your time and workforce tracking and scheduling with ease and will give your service-oriented business a definite step up in terms of productivity.

  1. Minterapp

Startups and small businesses looking for more productive ways to track task time and generate their invoices from the billable hours should give Minterapp a try. This invoicing and time tracking app can create an invoice with a single click. It also displays invoicing status (draft, pending, and paid), and helps its users in preparing job estimates.

Conclusion     

Are you a small business owner, a project or team leader, or a freelancer? Then, there’s an invoicing and time tracking app here that can save you time and make you more productive.

Hard work has many virtues, but when you’re working harder and harder just to keep up, it’s time to look for a better way. You’ll find it in one of these multipurpose apps.

The post Top Invoicing and Time Management Apps of 2018 appeared first on Line25.

14:22

Learning Gutenberg: Setting up a Custom webpack Config

Gutenberg introduces the modern JavaScript stack into the WordPress ecosystem, which means some new tooling should be learned. Although tools like create-guten-block are incredibly useful, it’s also handy to know what’s going on under the hood.

Article Series:

  1. Series Introduction
  2. What is Gutenberg, Anyway?
  3. A Primer with create-guten-block
  4. Modern JavaScript Syntax
  5. React 101
  6. Setting up a Custom webpack (This Post)
  7. A Custom "Card" Block (Coming Soon!)
The files we will be configuring here should be familiar from what we covered in the Part 2 Primer with create-guten-block. If you’re like me (before reading Andy’s tutorial, that is!) and would rather not dive into the configuration part just yet, the scaffold created by create-guten-block matches what we are about to create here, so you can certainly use that as well.

Let’s jump in!

Getting started

Webpack takes the small, modular aspects of your front-end codebase and smooshes them down into one efficient file. It’s highly extendable and configurable and works as the beating heart of some of the most popular products and projects on the web. It’s very much a JavaScript tool, although it can be used for pretty much whatever you want. For this tutorial, it’s sole focus is JavaScript though.

What we’re going to get webpack doing is watch for our changes on some custom block files and compile them with Babel to generate JavaScript files that can be read by most browsers. It’ll also merge any dependencies that we import.

But first, we need a place to store our actual webpack setup and front-end files. In Part 2, when we poked around the files generated by create-guten-block, we saw that it created an infrastructure for a WordPress plugin that enqueued our front-end files in a WordPress way, and enabled us to activate the plugin through WordPress. I’m going to take this next section to walk us through setting up the infrastructure for a WordPress plugin for our custom block.

Setting up a plugin

Hopefully you still have a local WordPress instance running from our primer in Part 2, but if not, you’ll need to have one installed to continue with what we’re about to do. In that install, navigate to wp-content/plugins and create a fresh directory called card-block (spoiler alert: we’re going to make a card block... who doesn’t like cards?).

Then, inside card-block, create a file called card-block.php. This will be the equivalent to plugin.php from create-guten-block. Next, drop in this chunk of comments to tell WordPress to acknowledge this directory as a plugin and display it in the Plugins page of the Dashboard:

<?php
   /*
   Plugin Name: Card Block
   */

Don’t forget the opening PHP tag, but you can leave the closing one off since we’ll be adding more to this file soon enough.

WordPress looks for these comments to register a plugin in the same way it looks for comments at the top of style.css in a theme. This is an abbreviated version of what you’ll find at the top of other plugins’ main files. If you were planning to release it on the WordPress plugin repository, you’d want to add a description and version number as well as license and author information.

Go ahead and activate the plugin through the WordPress Dashboard, and I’ll take the steering wheel back to take us through setting up our Webpack config!

Getting started with webpack

The first thing we’re going to do is initialize npm. Run the following at the root of your plugin folder (wp-content/plugins/card-block):

npm init

This will ask you a few questions about your project and ultimately generate you a package.json file, which lists dependencies and stores core information about your project.

Next, let’s install webpack:

npm install webpack --save-dev

You might have noticed that we’re installing webpack locally to our project. This is a good practice to get into with crucial packages that are prone to large, breaking changes. It also means you and your team are all singing off the same song sheet.

Then run this:

npm install extract-text-webpack-plugin@next --save-dev

Then these Sass and CSS dependencies:

npm install node-sass sass-loader css-loader --save-dev

Now, NPX to allow us to use our local dependencies instead of any global ones:

npm install npx -g

Lastly, run this:

npm install webpack-cli --save-dev

That will install the webpack CLI for you.

Now that we have this installed, we should create our config file. Still in the root of your plugin, create a file called webpack.config.js and open that file so we can get coding.

With this webpack file, we’re going to be working with traditional ES5 code for maximum compatibility, because it runs with Node JS. You can use ES6 and Babel, but we’ll keep things as simple as possible for this tutorial.

Alight, let’s add some constants and imports. Add the following, right at the top of your webpack.config.js file:

var ExtractText = require('extract-text-webpack-plugin');
var debug = process.env.NODE_ENV !== 'production';
var webpack = require('webpack');

The debug var is declaring whether or not we’re in debug mode. This is our default mode, but it can be overridden by prepending our webpack commands with NODE_ENV=production. The debug boolean flag will determine whether webpack generates sourcemaps and minifies the code.

As you can see, we’re requiring some dependencies. We know that webpack is needed, so we’ll skip that. Let’s instead focus our attention on ExtractText. Essentially, ExtractText enables us to pull in files other than JavaScript into the mix. We’re going to need this for our Sass files. By default, webpack assumes everything is JavaScript, so ExtractText kind of *translates* the other types of files.

Let’s add some config now. Add the following after the webpack definition:

var extractEditorSCSS = new ExtractText({
  filename: './blocks.editor.build.css'
});

var extractBlockSCSS = new ExtractText({
  filename: './blocks.style.build.css'
});

What we’ve done there is instantiate two instances of ExtractText by passing a config object. All that we’ve set is the output of our two block stylesheets. We’ll come to these in the next series, but right now all you need to know is that this is the first step in getting our Sass compiling.

OK, after that last bit of code, add the following:

var plugins = [ extractEditorSCSS, extractBlockSCSS ];

Here we’ve got two arrays of plugins. Our ExtractText instances live in the core plugins set and we’ve got a couple of optimization plugins that are only smooshed into the core plugins set if we’re not in debug mode. We’re running that logic right at the end.

Next up, add this SCSS config object:

var scssConfig = {
  use: [
    {
      loader: 'css-loader'
    },
    {
      loader: 'sass-loader',
      options: {
        outputStyle: 'compressed'
      }
    }
  ]
};

This object is going to tell our webpack instance how to behave when it comes across scss files. We’ve got it in a config object to keep things as DRY as possible.

Last up, the meat and taters of the config:

module.exports = {
  context: __dirname,
  devtool: debug ? 'inline-sourcemap' : null,
  mode: debug ? 'development' : 'production',
  entry: './blocks/src/blocks.js',
  output: {
    path: __dirname + '/blocks/dist/',
    filename: 'blocks.build.js'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader'
          }
        ]
      },
      {
        test: /editor\.scss$/,
        exclude: /node_modules/,
        use: extractEditorSCSS.extract(scssConfig)
      },
      {
        test: /style\.scss$/,
        exclude: /node_modules/,
        use: extractBlockSCSS.extract(scssConfig)
      }
    ]
  },
  plugins: plugins
};

That’s our entire config, so let’s break it down.

The script starts with module.exports which is essentially saying, "when you import or require me, this is what you’re getting." We can determine what we expose to whatever imports our code, which means we could run code above module.exports that do some heavy calculations, for example.

Next, let’s look at some of these following properties:

  • context is our base where paths will resolve from. We’ve passed __dirname, which is the current working directory.
  • devtool is where we define what sort of sourcemap we may or may not want. If we’re not in debug mode, we pass null with a ternary operator.
  • entry is where we tell webpack to start its journey of pack-ery. In our instance, this is the path to our blocks.js file.
  • output is what it says on the tin. We’re passing an object that defines the output path and the filename that we want to call it.

Next is module, which we’ll got into a touch more detail. The module section can contain multiple rules. In our instance, the only rule we have is looking for JavaScript and SCSS files. It’s doing this by searching with a regular expression that’s defined by the test property. The end-goal of the rule is to find the right sort of files and pass them into a loader, which is babel-loader in our case. As we learned in a previous tutorial in this series, Babel is what converts our modern ES6 code into more supported ES5 code.

Lastly is our plugins section. Here, we pass our array of plugin instances. In our project, we have plugins that minify code, remove duplicate code and one that reduces the length of commonly used IDs. This is all to make sure our production code is optimized.

For reference, this is how your full config file should look:

var ExtractText = require('extract-text-webpack-plugin');
var debug = process.env.NODE_ENV !== 'production';
var webpack = require('webpack');

var extractEditorSCSS = new ExtractText({
  filename: './blocks.editor.build.css'
});

var extractBlockSCSS = new ExtractText({
  filename: './blocks.style.build.css'
});

var plugins = [extractEditorSCSS, extractBlockSCSS];

var scssConfig = {
  use: [
    {
      loader: 'css-loader'
    },
    {
      loader: 'sass-loader',
      options: {
        outputStyle: 'compressed'
      }
    }
  ]
};

module.exports = {
  context: __dirname,
  devtool: debug ? 'inline-sourcemap' : null,
  mode: debug ? 'development' : 'production',
  entry: './blocks/src/blocks.js',
  output: {
    path: __dirname + '/blocks/dist/',
    filename: 'blocks.build.js'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader'
          }
        ]
      },
      {
        test: /editor\.scss$/,
        exclude: /node_modules/,
        use: extractEditorSCSS.extract(scssConfig)
      },
      {
        test: /style\.scss$/,
        exclude: /node_modules/,
        use: extractBlockSCSS.extract(scssConfig)
      }
    ]
  },
  plugins: plugins
};
That’s webpack configured. I’ll take the mic back to show us how to officially register our block with WordPress. This should feel pretty familiar to those of you who are used to wrangling with actions and filters in WordPress.

Registering our block

Back in card-block.php, our main task now is to enqueue the JavaScript and CSS files we will be building with webpack. In a theme, we would do this with call wp_enqueue_script and wp_enqueue_style inside an action added to wp_enqueue_scripts. We essentially do the same thing here, except instead we enqueue the scripts and styles with a function specific to blocks.

Drop this code below the opening comment in card-block.php:

function my_register_gutenberg_card_block() {

  // Register our block script with WordPress
  wp_register_script(
    'gutenberg-card-block',
    plugins_url('/blocks/dist/blocks.build.js', __FILE__),
    array('wp-blocks', 'wp-element')
  );

  // Register our block's base CSS  
  wp_register_style(
    'gutenberg-card-block-style',
    plugins_url( '/blocks/dist/blocks.style.build.css', __FILE__ ),
    array( 'wp-blocks' )
  );
  
  // Register our block's editor-specific CSS
  wp_register_style(
    'gutenberg-card-block-edit-style',
    plugins_url('/blocks/dist/blocks.editor.build.css', __FILE__),
    array( 'wp-edit-blocks' )
  );  
  
  // Enqueue the script in the editor
  register_block_type('card-block/main', array(
    'editor_script' => 'gutenberg-card-block',
    'editor_style' => 'gutenberg-card-block-edit-style',
    'style' => 'gutenberg-card-block-edit-style'
  ));
}

add_action('init', 'my_register_gutenberg_card_block');

As the above comments indicate, we first register our script with WordPress using the handle gutenberg-card-block with two dependencies: wp-blocks and wp-elements. This function only registers a script, it does not enqueue it. We do something similar for out edit and main stylesheets.

Our final function, register_block_type, does the enqueuing for us. It also gives the block a name, card-block/main, which identifies this block as the main block within the namespace card-block, then identifies the script and styles we just registered as the main editor script, editor stylesheet, and primary stylesheet for the block.

If you are familiar with theme development, you’ve probably used get_template_directory() to handle file paths in hooks like the ones above. For plugin development, we use the function plugins_url() which does pretty much the same thing, except instead of concatenating a path like this: get_template_directory() . 'https://cdn.css-tricks.com/script.js', plugins_url() accepts a string path as a parameter and does the concatenation for us. The second parameter, _ FILE _, is one of PHP’s magic constants that equates to the full file path of the current file.

Finally, if you want to add more blocks to this plugin, you’d need a version of this function for each block. You could work out what’s variable and generate some sort of loop to keep it nice and DRY, further down the line. Now, I’ll walk us through getting Babel up and running.

Getting Babel running

Babel turns our ES6 code into better-supported ES5 code, so we need to install some dependencies. In the root of your plugin (wp-content/plugins/card-block), run the following:

npm install babel-core babel-loader babel-plugin-add-module-exports babel-plugin-transform-react-jsx babel-preset-env --save-dev

That big ol’ npm install adds all the Babel dependencies. Now we can add our .babelrc file which stores some settings for us. It prevents us from having to repeat them over and over in the command line.

While still in your theme folder, add the following file: .babelrc.

Now open it up and paste the following:

{
  "presets": ["env"],
  "plugins": [
    ["transform-react-jsx", {
      "pragma": "wp.element.createElement"
    }]
  ]
}

So, what we’ve got there are two things:

"presets": ["env"] is basically magic. It automatically determines which ES features to use to generate your ES5 code. We used to have to add different presets for all the different ES versions (e.g. ES2015), but it’s been simplified.

In the plugins, you’ll notice that there’s a React JSX transformer. That’s sorting out our JSX and turning it into proper JavaScript, but what we’re doing is telling it to generate WordPress elements, rather than React elements, which JSX is more commonly associated with.

Generate stub files

The last thing we’re going to do is generate some stub files and test that our webpack and WordPress setup is all good.

Go into your plugin directory and create a folder called blocks and, within that, create two folders: one called src and one called dist.

Inside the src folder, create the following files. We’ve added the paths, too, so you put them in the right place:

  • blocks.js
  • common.scss
  • block/block.js
  • block/editor.scss
  • block/style.scss

OK, so now we’ve generated the minimum amount of things, let’s run webpack. Open up your terminal and move into your current plugin folder—then we can run the following, which will fire-up webpack:

npx webpack

Pretty dang straightforward, huh? If you go ahead and look in your dist folder, you should see some compiled goodies in there!

Wrapping up

A lot of setup has been done, but all of our ducks are in a row. We’ve set up webpack, Babel and WordPress to all work as a team to build out or custom Gutenberg block (and future blocks). Hopefully now you feel more comfortable working with webpack and feel like you could dive in and make customizations to fit your projects.


Article Series:

  1. Series Introduction
  2. What is Gutenberg, Anyway?
  3. A Primer with create-guten-block
  4. Modern JavaScript Syntax
  5. React 101
  6. Setting up a Custom webpack (This Post)
  7. A Custom "Card" Block (Coming Soon!)

The post Learning Gutenberg: Setting up a Custom webpack Config appeared first on CSS-Tricks.

14:13

​High Performance Hosting with No Billing Surprises

(This is a sponsored post.)

With DigitalOcean, you can spin up Droplet cloud servers with industry-leading price-performance and predictable costs. Our flexible configurations are sized for any application, and we save you up to 55% when compared to other cloud providers.

Get started today. Receive a free $100/60-day account credit good towards any DigitalOcean services.

Direct Link to ArticlePermalink

The post ​High Performance Hosting with No Billing Surprises appeared first on CSS-Tricks.

13:00

Code an Image Gallery Android App With Picasso

Final product image What You'll Be Creating

Picasso is a popular open-source Android library for loading both local and remote images. Learn how to easily use it for handling your image loading needs. 

1. What Is Picasso?

Picasso (name inspired by the famous French artist Pablo Picasso) is a very popular open-source Android library for loading images in your Android app. According to the official docs, it states:

...Picasso allows for hassle-free image loading in your application—often in one line of code!

Note that Picasso uses OkHttp (a network library from the same developer) under the hood to load the images over the internet. 

2. So Why Use Picasso?

Now you have learned what Picasso is all about, the next question you might ask is why use it?

Developing your own media loading and display functionality in Java or Kotlin can be a real pain: you have to take care of caching, decoding, managing network connections, threading, exception handling, and more. Picasso is an easy to use, well planned, well documented, and thoroughly tested library that can save you a lot of precious time—and save you some headaches. 

Here are many of the common pitfalls of loading images on Android that are dealt with for you by Picasso, according to the official docs:

  • handling ImageView recycling and download cancellation in an adapter
  • complex image transformations with minimal memory use
  • automatic memory and disk caching

Adding images to your app can make your Android app come alive. So in this tutorial, we'll learn about Picasso 2 by building a simple image gallery app. It will load the images via the internet and display them as thumbnails in a RecyclerView, and when a user clicks on an image, it will open a detail activity containing the larger image. 

A sample project (in Kotlin) for this tutorial can be found on our GitHub repo so you can easily follow along.

Good artists copy, great artists steal. — Pablo Picasso

3. Prerequisites

To be able to follow this tutorial, you'll need:

Fire up Android Studio and create a new project (you can name it PicassoDemo) with an empty activity called MainActivity. Make sure to also check the Include Kotlin support check box.

Android Studios Add an Activity to Mobile dialog

4. Declare Dependencies

After creating a new project, specify the following dependencies in your build.gradle. At the time of writing, the latest version of Picasso is 2.71828

Or with Maven:

Make sure you sync your project after adding Picasso and the RecyclerView v7 artifacts.

5. Add Internet Permission

Because Picasso is going to perform a network request to load images via the internet, we need to include the permission INTERNET in our AndroidManifest.xml

So go do that now!

Note that this is only required if you're going to load images from the internet. This is not required if you are only loading images locally on the device. 

6. Create the Layout

We'll start by creating our RecyclerView inside the activity_main.xml layout file. 

Creating the Custom Item Layout

Next, let's create the XML layout (item_image.xml) that will be used for each item (ImageView) within the RecyclerView

Now that we have created the layouts needed for our simple gallery app, the next step is to create the RecyclerView adapter for populating data. Before we do that, though, let's create our simple data model. 

7. Create a Data Model

We are going to define a simple data model for our RecyclerView. This model implements Parcelable for high-performance transport of data from one component to another in Android. In our case, data will be transported from SunsetGalleryActivity to SunsetPhotoActivity

Note that this model SunsetPhoto has only a single field called url (for demo purposes), but you can have more if you want. This class implements Parcelable, which means we have to override some methods. 

We can make use of Android Studio IDEA to generate these methods for us, but the downside to this is maintenance. How? Anytime we add any new fields to this class, we might forget to explicitly update the constructor and writeToParcel methods, which can lead to some bugs if we don't update the methods.  

Now, to circumvent updating or writing these boilerplate methods, Kotlin 1.1.14 introduced the @Parcelize annotation. This annotation will help us generate the writeToParcel, writeFromParcel, and describeContents methods automatically under the hood for us. 

Now, our code SunsetPhoto class is just two lines! Awesome! 

Remember to add the following code to your app module build.gradle:

In addition, I included a companion object (or static method in Java) getSunsetPhotos() in the SunsetPhoto model class that will simply return an ArrayList of SunsetPhoto when called.

8. Create the Adapter

We'll create an adapter to populate our RecyclerView with data. We'll also implement a click listener to open the detail activity—SunsetPhotoActivity—passing it an instance of SunsetPhoto as an intent extra. The detail activity will show a close-up of the image. We'll create it in a later section.

Notice that we used the apply extension function to put an object as extra to the intent. As a reminder, the apply function returns the object passed to it as an argument (i.e. the receiver object). 

9. Loading Images From a URL

We're going to need Picasso to do its job in this section—not to paint us a work of art, but to fetch images from the internet and display them. We'll display these images individually in their respective ImageViews inside our RecyclerView onBindViewHolder() method as the user scrolls the app. 

Step by step, here's what the calls to Picasso are doing:

The get() Method

This returns the global Picasso instance (singleton instance) initialized with the following default configurations: 

  • LRU memory cache of 15% the available application RAM.
  • Disk cache of 2% storage space up to 50MB but no less than 5MB. Note: this is only available on API 14+.
  • Three download threads for disk and network access.

Note that if these settings do not meet the requirements of your application, you're free to construct your own Picasso instance with full control of these configurations by using Picasso.Builder

Finally, you call the build() method to return you a Picasso instance with your own configurations. 

It's recommended you do this in your Application.onCreate and then set it as the singleton instance with Picasso.setSingletonInstance in that method—to make sure that the Picasso instance is the global one.

The load() Method 

load(String path) starts an image request using the specified path. This path can be a remote URL, file resource, content resource, or Android resource.

  • placeholder(int placeholderResId): a local placeholder resource id or drawable to be used while the image is being loaded and then displayed. It serves as a good user experience to display a placeholder image while the image is downloading.  

Note that Picasso first checks if the image requested is in the memory cache, and if it is, it displays the image from there (we'll discuss caching in Picasso more in a later section).

Other Methods

  • error(int errorResId): a drawable to be used if the requested image could not be loaded—probably because the website is down. 
  • noFade(): Picasso always fades in the image to be displayed into the ImageView. If you don't want this fade-in animation, simply call the noFade() method. 
  • into(ImageView imageView): the target image view into which the image will be placed.

Image Resizing and Transformation

If the server you are requesting the image from doesn't give you the image you need in the required size, you can easily resize that image using resize(int targetWidth, int targetHeight). Calling this method resizes the image and then displays it on the ImageView. Note that the dimensions are in pixels (px), not dp. 

You can pass in an Android dimension resource for both the width and height using the method resizeDimen(int targetWidthResId, int targetHeightResId). This method will convert the dimension size to raw pixels and then call resize() under the hood—passing the converted sizes (in pixels) as arguments. 

Note that these resize methods won't respect aspect ratio. In other words, your image aspect ratio can be distorted. 

Fortunately, Picasso gives us some useful methods to solve this issue: 

  • centerCrop(): scales the image uniformly (maintaining the image's aspect ratio) so that the image fills up the given area, with as much of the image showing as possible. If needed, the image will be cropped horizontally or vertically to fit. Calling this method crops an image inside of the bounds specified by resize().
  • centerInside(): scales the image so that both dimensions are equal to or less than the requested bounds. This will center an image inside of the bounds specified by resize()
  • onlyScaleDown(): only resize an image if the original image size is bigger than the target size specified by resize().
  • fit(): attempt to resize the image to fit exactly into the target ImageView's bounds.

Image Rotation

Picasso has an easy API to rotate an image and then display that image. The rotate(float degrees) method rotates the image by the specified degrees.

In the example above, this would rotate the image by 90 degrees. The rotate(float degrees, float pivotX, float pivotY) method rotates the image by the specified degrees around a pivot point.

Here we are going to rotate the image by 30 degrees around the pivot point 200, 100 pixels. 

Transformation

Apart from just manipulating an image by rotating it, Picasso also gives us the option to apply a custom transformation to an image before displaying it.  

You simply create a class that implements the Picasso Transformation interface. You then have to override two methods: 

  • Bitmap transform(Bitmap source): this transforms the source bitmap into a new bitmap. 
  • String key(): returns a unique key for the transformation, used for caching purposes.

After you're done creating your custom transformation, you simply execute it by invoking transform(Transformation transformation) on your Picasso instance. Note that you can also pass a list of Transformation to transform()

Here, I applied a circle crop transformation to the image from the Picasso Transformations open-source Android library. This library has many transformations you can apply to an image with Picasso—including transformations for blurring or grey-scaling an image. Go check it out if you want to apply some cool transformations to your images.  

10. Initializing the Adapter

Here, we simply create our RecyclerView with GridLayoutManager as the layout manager, initialize our adapter, and bind it to the RecyclerView

11. Creating the Detail Activity

Create a new activity and name it SunsetPhotoActivity. We get the SunsetPhoto extra and load the image—inside onStart()—with Picasso as we did before. 

The Detail Layout

Here's a layout to display the detail activity. It just displays an ImageView that will show the full-resolution version of the loaded image. 

12. Caching Mechanism in Picasso

If you observe carefully, you'll notice that when you revisit an image that was previously loaded, it loads even faster than before. What made it faster? It's Picasso's caching mechanism, that's what.

Here is what's going on under the hood. After an image has been loaded once from the internet, Picasso will cache it both in memory and on disk, saving repeated network requests and permitting faster retrieval of the image. When that image is needed again, Picasso will first check if the image is available in memory, and if it's there, it will return it immediately. If that image is not in memory, Picasso will check the disk next, and if it's there, it returns it. If it's not there, Picasso will finally do a network request for that image and display it. 

In summary, here's what goes on (under the hood) for an image request: memory -> disk -> network. 

Depending on your application, though, you might want to avoid caching—for example, if the images being displayed are likely to change often and not be reloaded.

So How Do You Disable Caching? 

You can avoid memory caching by calling memoryPolicy(MemoryPolicy.NO_CACHE). This will simply skip the memory cache lookup when processing an image request. 

Note that there is another enum: MemoryPolicy.NO_STORE. This is useful if you are very certain that you will only request an image once. Applying this will also not store the image in the memory cache—thereby not forcing out other bitmaps from the memory cache. 

But be very aware that the image will still be cached on the disk—to prevent that also, you use networkPolicy(@NonNull NetworkPolicy policy, @NonNull NetworkPolicy... additional), which takes one or more of the following enum values:

  • NetworkPolicy.NO_CACHE: skips checking the disk cache and forces loading through the network.
  • NetworkPolicy.NO_STORE: skips storing the result into the disk cache.
  • NetworkPolicy.OFFLINE: forces the request through the disk cache only, skipping the network.

To avoid both memory and disk caching altogether, just call both methods one after the other:

13. Request Listeners

In Picasso, you can implement a listener or callback to monitor the status of the request you made as the image loads. Only one of these methods will be called if you implement the Target interface on a request. 

  • void onBitmapFailed(e: Exception?, errorDrawable: Drawable?): triggered whenever the image could not be successfully loaded. Here, we can access the exception that was thrown. 
  • void onBitmapLoaded(Bitmap bitmap, LoadedFrom from): fired whenever an image has been successfully loaded. Here, we get the Bitmap to show the user. 
  • void onPrepareLoad(Drawable placeHolderDrawable): invoked right before your request is submitted. 

Here you could also show and then hide a progress dialog if you had one. 

There is another callback listener you can implement if you want, called Callback. This interface has just two methods: onSuccess() and onError(Exception e). The former is called when the image request load was successful, and the later is called when there is an error in processing the request. 

Going back to our image gallery app (inside SunsetPhotoActivity), let's modify the display a little by using a Callback object that will set the bitmap to the ImageView and also change the background colour of the layout by extracting the dark and vibrant colour of our image using the Android Palette API

So include the palette artifact in your app module's build.gradle:

Let's now implement the Callback interface in our Picasso request. 

14. Testing the App

Finally, you can run the app! Click on a thumbnail to get a full-sized version of the image.

Final app result

15. Prioritizing Requests

When you want to load different images at the same time on the same screen, you have the option to order which one is more important than the other. In other words, you can load important images first. 

You simply call priority() on your Picasso request instance and pass in any of the enums: Priority.LOW, Priority.NORMAL, or Priority.HIGH

16. Tagging Requests

By tagging your Picasso requests, you can resume, pause, or cancel requests which are associated with specific tags. Depending on your use case, you can tag your requests with a string or objects that should define the scope of the request as a Context, an Activity, or a Fragment. You can easily tag a Picasso request by calling tag(@NonNull Object tag) on one. Pass it an instance of Object which serves as the tag. 

Here are the following operations you can perform on tagged Picasso requests:

  • pauseTag(Object tag): pause all requests associated with the given tag. 
  • resumeTag(Object tag): resume paused requests with the given tag.
  • cancelTag(Object tag): cancel any existing requests with the given tag.

Though tagging your requests gives you some control over your requests, you should be very careful when using tags because of the potential for memory leaks. Here's what the official documentation says:

Picasso will keep a reference to the tag for as long as this tag is paused and/or has active requests. Look out for potential leaks.

Loading From the File System

It's straightforward to load images locally in your app.

Conclusion

Nice job! In this tutorial, you've built a complete image gallery app with Picasso, and along the way you've learned how the library works and how you can integrate it into your own project. 

You've also learned how to display both local and remote images, tagging requests, prioritizing requests, and how to apply image transformations like resizing. Not only that, but you've seen how easy it is to enable and disable caching, error handling, and custom request listeners. 

To learn more about Picasso, you can refer to its official documentation. To learn more about coding for Android, check out some of our other courses and tutorials here on Envato Tuts+!

11:30

Lessons Learned While Developing WordPress Plugins

Lessons Learned While Developing WordPress Plugins

Lessons Learned While Developing WordPress Plugins

Jakub Mikita
2018-05-24T13:30:28+02:002018-05-24T12:27:17+00:00

Every WordPress plugin developer struggles with tough problems and code that’s difficult to maintain. We spend late nights supporting our users and tear out our hair when an upgrade breaks our plugin. Let me show you how to make it easier.

In this article, I’ll share my five years of experience developing WordPress plugins. The first plugin I wrote was a simple marketing plugin. It displayed a call to action (CTA) button with Google’s search phrase. Since then, I’ve written another 11 free plugins, and I maintain almost all of them. I’ve written around 40 plugins for my clients, from really small ones to one that have been maintained for over a year now.

Measuring Performance With Heatmaps

Heatmaps can show you the exact spots that receive the most engagement on a given page. Find out why they’re so efficient for your marketing goals and how they can be integrated with your WordPress site. Read article →

Good development and support lead to more downloads. More downloads mean more money and a better reputation. This article will show you the lessons I’ve learned and the mistakes I’ve made, so that you can improve your plugin development.

Getting workflow just right ain't an easy task. So are proper estimates. Or alignment among different departments. That's why we've set up 'this-is-how-I-work'-sessions — with smart cookies sharing what works well for them. A part of the Smashing Membership, of course.

Explore features →

1. Solve A Problem

If your plugin doesn’t solve a problem, it won’t get downloaded. It’s as simple as that.

Take the Advanced Cron Manager plugin (8,000+ active installations). It helps WordPress users who are having a hard time debugging their cron. The plugin was written out of a need — I needed something to help myself. I didn’t need to market this one, because people already needed it. It scratched their itch.

On the other hand, there’s the Bug — fly on the screen plugin (70+ active installations). It randomly simulates a fly on the screen. It doesn’t really solve a problem, so it’s not going to have a huge audience. It was a fun plugin to develop, though.

Focus on a problem. When people don’t see their SEO performing well, they install an SEO plugin. When people want to speed up their website, they install a caching plugin. When people can’t find a solution to their problem, then they find a developer who writes a solution for them.

As David Hehenberger attests in his article about writing a successful plugin, need is a key factor in the WordPress user’s decision of whether to install a particular plugin.

If you have an opportunity to solve someone’s problem, take a chance.

2. Support Your Product

“3 out of 5 Americans would try a new brand or company for a better service experience. 7 out of 10 said they were willing to spend more with companies they believe provide excellent service.”

— Nykki Yeager

Don’t neglect your support. Don’t treat it like a must, but more like an opportunity.

Good-quality support is critical in order for your plugin to grow. Even a plugin with the best code will get some support tickets. The more people who use your plugin, the more tickets you’ll get. A better user experience will get you fewer tickets, but you will never reach inbox 0.

Every time someone posts a message in a support forum, I get an email notification immediately, and I respond as soon as I can. It pays off. The vast majority of my good reviews were earned because of the support. This is a side effect: Good support often translates to 5-star reviews.

When you provide excellent support, people start to trust you and your product. And a plugin is a product, even if it’s completely free and open-source.

Good support is more complex than about writing a short answer once a day. When your plugin gains traction, you’ll get several tickets per day. It’s a lot easier to manage if you’re proactive and answer customers’ questions before they even ask.

Here’s a list of some actions you can take:

  • Create an FAQ section in your repository.
  • Pin the “Before you ask” thread at the top of your support forum, highlighting the troubleshooting tips and FAQ.
  • Make sure your plugin is simple to use and that users know what they should do after they install it. UX is important.
  • Analyze the support questions and fix the pain points. Set up a board where people can vote for the features they want.
  • Create a video showing how the plugin works, and add it to your plugin’s main page in the WordPress.org repository.

It doesn’t really matter what software you use to support your product. The WordPress.org’s official support forum works just as well as email or your own support system. I use WordPress.org’s forum for the free plugins and my own system for the premium plugins.

3. Don’t Use Composer

Composer is package-manager software. A repository of packages is hosted on packagist.org, and you can easily download them to your project. It’s like NPM or Bower for PHP. Managing your third-party packages the way Composer does is a good practice, but don’t use it in your WordPress project.

I know, I dropped a bomb. Let me explain.

Composer is great software. I use it myself, but not in public WordPress projects. The problem lies in conflicts. WordPress doesn’t have any global package manager, so each and every plugin has to load dependencies of their own. When two plugins load the same dependency, it causes a fatal error.

There isn’t really an ideal solution to this problem, but Composer makes it worse. You can bundle the dependency in your source manually and always check whether you are safe to load it.

Composer’s issue with WordPress plugins is still not solved, and there won’t be any viable solution to this problem in the near future. The problem was raised many years ago, and, as you can read in WP Tavern’s article, many developers are trying to solve it, without any luck.

The best you can do is to make sure that the conditions and environment are good to run your code.

4. Reasonably Support Old PHP Versions

Don’t support very old versions of PHP, like 5.2. The security issues and maintenance aren’t worth it, and you’re not going to earn more installations from those older versions.

The Notification plugin’s usage on PHP versions from May 2018. (Large preview)

Go with PHP 5.6 as a minimal requirement, even though official support will be dropped by the end of 2018. WordPress itself requires PHP 7.2.

There’s a movement that discourages support of legacy PHP versions. The Yoast team released the Whip library, which you can include in your plugin and which displays to your users important information about their PHP version and why they should upgrade.

Tell your users which versions you do support, and make sure their website doesn’t break after your plugin is installed on too low a version.

5. Focus On Quality Code

Writing good code is tough in the beginning. It takes time to learn the “SOLID” principles and design patterns and to change old coding habits.

It once took me three days to display a simple string in WordPress, when I decided to rewrite one of my plugins using better coding practices. It was frustrating knowing that it should have taken 30 minutes. Switching my mindset was painful but worth it.

Why was it so hard? Because you start writing code that seems at first to be overkill and not very intuitive. I kept asking myself, “Is this really needed?” For example, you have to separate the logic into different classes and make sure each is responsible for a single thing. You also have to separate classes for the translation, custom post type registration, assets management, form handlers, etc. Then, you compose the bigger structures out of the simple small objects. That’s called dependency injection. That’s very different from having “front end” and “admin” classes, where you cram all your code.

The other counterintuitive practice was to keep all actions and filters outside of the constructor method. This way, you’re not invoking any actions while creating the objects, which is very helpful for unit testing. You also have better control over which methods are executed and when. I wish I knew this before I wrote a project with an infinite loop caused by the actions in the constructor methods. Those kinds of bugs are hard to trace and hard to fix. The project had to be refactored.

The above are but a few examples, but you should get to know the SOLID principles. These are valid for any system and any coding language.

When you follow all of the best practices, you reach the point where every new feature just fits in. You don’t have to tweak anything or make any exceptions to the existing code. It’s amazing. Instead of getting more complex, your code just gets more advanced, without losing flexibility.

Also, format your code properly, and make sure every member of your team follows a standard. Standards will make your code predictable and easier to read and test. WordPress has its own standards, which you can implement in your projects.

6. Test Your Plugin Ahead Of Time

I learned this lesson the hard way. Lack of testing led me to release a new version of a plugin with a fatal error. Twice. Both times, I got a 1-star rating, which I couldn’t turn into a positive review.

You can test manually or automatically. Travis CI is a continuous testing product that integrates with GitHub. I’ve built a really simple test suite for my Notification plugin that just checks whether the plugin can boot properly on every PHP version. This way, I can be sure the plugin is error-free, and I don’t have to pay much attention to testing it in every environment.

Each automated test takes a fraction of a second. 100 automated tests will take about 10 minutes to complete, whereas manual testing needs about 2 minutes for each case.

The more time you invest in testing your plugin up front, the more it will save you in the long run.

To get started with automated testing, you can use the WP-CLI \\`wp scaffold plugin-test\\` command, which installs all of the configuration you need.

7. Document Your Work

It’s a cliche that developers don’t like to write documentation. It’s the most boring part of the development process, but a little goes a long way.

Write self-documenting code. Pay attention to variable, function and class names. Don’t make any complicated structures, like cascades that can’t be read easily.

Another way to document code is to use the “doc block”, which is a comment for every file, function and class. If you write how the function works and what it does, it will be so much easier to understand when you need to debug it six months from now. WordPress Coding Standards covers this part by forcing you to write the doc blocks.

Using both techniques will save you the time of writing the documentation, but the code documentation is not going to be read by everyone.

For the end user, you have to write high-quality, short and easy-to-read articles explaining how the system works and how to use it. Videos are even better; many people prefer to watch a short tutorial than read an article. They are not going to look at the code, so make their lives easier. Good documentation also reduces support tickets.

Conclusion

These seven rules have helped me develop good-quality products, which are starting to be a core business at BracketSpace. I hope they’ll help you in your journey with WordPress plugins as well.

Let me know in the comments what your golden development rule is or whether you’ve found any of the above particularly helpful.

Smashing Editorial(il, ra, yk)
07:30
9 Free Open Source Flipping Clocks Using CSS and JavaScript

May 23 2018

19:41

Learning Gutenberg: React 101

Although Gutenberg is put together with React, the code we’re writing to make custom blocks isn’t. It certainly resembles a React component though, so I think it’s useful to have a little play to get familiar with this sort of approach. There’s been a lot of reading in this series so far, so let’s roll-up our sleeves and make something cool.

Article Series:

  1. Series Introduction
  2. What is Gutenberg, Anyway?
  3. A Primer with create-guten-block
  4. Modern JavaScript Syntax
  5. React 101 (This Post)
  6. Setting up a Custom webpack (Coming Soon!)
  7. A Custom "Card" Block (Coming Soon!)

Let’s make an “About Me” component

We’re going to make a single React component that updates the background color of a page and the intro text based on data you input into a couple of fields. “I thought this was supposed to be cool,” I hear you all mutter. I’ll admit, I may have oversold it, but we’re going to learn some core concepts of state-driven JavaScript which will come in handy when we dig into our Gutenberg block.

For reference, this is what we’re going to end up with:

Getting started

The first thing we’re going to do is fire up CodePen. CodePen can be used for free, so go head over there and create a new Pen.

Next, we’re going to pull in some JavaScript dependencies. There are three editor screens—find the JS screen and click the settings cog. This will open up a Pen Settings modal where you’ll find the section titled Add External Scripts/Pens. Right at the bottom, theres a Quick-add select menu. Go ahead and open that up.

A screenshot of the CodePen interface with the JavaScript settings open. The settings are in a split pane where the settings are on the left in a white box and advanced settings are on the right in a dark gray box.

From the menu, select React. Once that’s selected, open the menu and select ReactDOM. You’ll see that this has pre-filled some text boxes.

Lastly, we need to enable our ES6 code, so at the menu titled JavaScript Preprocessor, select Babel.

Now, go ahead and click the big Save & Close button.

What we’ve done there is pull the main React JS library and ReactDOM library. These will enable us to dive in and write our code, which is our next step.

Setup our CSS

Let’s make it look cool. First up though, let’s setup our CSS editor. The first thing we’re going to do is set it up to compile Sass for us. Just like we did with the JS editor, click on the settings cog which will bring up the Pen Settings modal again—this time with the CSS settings.

At the top, there’s a CSS Preprocessor menu. Go ahead and select SCSS from there.

When that’s done, go down to the Add External Stylesheets/Pens and paste the following three links into separate text-boxes:

https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.css
https://fonts.googleapis.com/css?family=Work+Sans:300
https://rawgit.com/hankchizljaw/boilerform/master/dist/css/boilerform.min.css

Those three in order give us a reset, a fancy font and some helpful form styles.

Now that they’re all set, go ahead and click the "Save & Close" button again.

Adding a bit of style

We’re all setup so this step should be easy. Paste the following Sass into the CSS editor:

:root {
  --text-color: #f3f3f3;
}

* {
  box-sizing: border-box;
}

html {
  height: 100%;
  font-size: 16px;
}

body {
  height: 100%;
  position: relative;
  font-size: 1rem;
  line-height: 1.4;
  font-family: "Work Sans", sans-serif;
  font-weight: 300;
  background: #f3f3f3;
  color: #232323;
}

.about {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  color: var(--text-color);
  transition: all 2000ms ease-in-out;
  
  &__inner {
    display: flex;
    flex-direction: column;
    height: 100%;
    margin: 0 auto;
    padding: 1.2rem;
  }
  
  &__content {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    flex: 1 1 auto;
    font-size: 3rem;
    line-height: 1.2;
    
    > * {
      max-width: 30ch;
    }
  }
  
  &__form {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 2rem 0;
    width: 100%;
    max-width: 60rem;
    margin: 0 auto;

    @media(min-width: 32rem) {
      flex-direction: row;
      justify-content: space-between;
      padding: 2rem;
    }
    
    > * {
      width: 15rem;
    }
    
    > * + * {
      margin: 1rem 0 0 0;
      
      @media(min-width: 32rem) {
        margin: 0;
      }
    }
    
    label {
      display: block;
    }
  }
}

// Boilerform overrides 
.c-select-field {
  &,
  &__menu {
    width: 100%;
  }
}

.c-input-field {
  width: 100%;
}

.c-label {
  color: var(--text-color);
}

That’s a big ol’ chunk of CSS, and it’ll look like nothing has really happened, but it’s all good—we’re not going to have to worry about CSS for the rest of this section.

Digging into React

The first thing we’re going to do is give React something to latch on to. Paste this into the HTML editor of your Pen:

<div id="root"></div>

That’s it for HTML—you can go ahead and maximize your JS editor so we’ve got complete focus.

Let’s start our component code, by creating a new instance of a React component by writing the following JavaScript:

class AboutMe extends React.Component {
}

What that code is doing is creating a new AboutMe component and extending React’s Component class, which gives us a load of code and tooling for free.

Right, so we’ve got a class, and now we need to construct it! Add the following code, inside the brackets:

constructor(props) {
  super(props);
  
  let self = this;
};

We’ve got a few things going on here, so I’ll explain each:

constructor is the method that’s called when you write new AboutMe(), or if you write <AboutMe /> in your JSX. This constructs the object. The props parameter is something you’ll see a lot in React. This is the collection of properties that are passed into the component. For example: if you wrote <AboutMe name="Andy" />, you’d be able to access it in your constructor with props.name.

super is how we tell the class that we’ve extended to construct with its own constructor. You’ll see we’re also passing the props up to it in case any parent components need to access them.

Finally let self = this is a way of controlling the scope of this. Remember, because we’re using let, self will only be available in the constructor function.

Quick note for those readers not-so-confident in JavaScript: I found a deeper look at scope in JavaScript to result in a lot of “aha” moments in my learning. I highly recommend Kyle Simpson’s You Don’t Know JS book series (available for free on GitHub!). Volumes of note: this and Object Prototypes and Scope & Closures. Good stuff, I promise.

Now we’ve covered the constructor, let’s add some more code to it. After the let self = this; line, paste the following code:

self.availableColors = [
  {
    "name": "Red",
    "value": "#ca3814"
  },
  {
    "name": "Blue",
    "value": "#0086cc"
  },
  {
    "name": "Green",
    "value": "#3aa22b"
  }
];

What we’ve got there is an array of objects that define our options for picking your favorite color. Go ahead and add your own if it’s not already there!

Your class definition and constructor should now look like this:

class AboutMe extends React.Component {
  
  constructor(props) {
    super(props);
    
    let self = this;
    
    // Set a list of available colors that render in the select menu
    self.availableColors = [
      {
        "name": "Red",
        "value": "#ca3814"
      },
      {
        "name": "Blue",
        "value": "#0086cc"
      },
      {
        "name": "Green",
        "value": "#3aa22b"
      }
    ];
  };
}

Pretty straightforward so far, right? Let’s move on and set some initial values to our reactive state. Add the following after the closing of self.availableColors:

// Set our initial reactive state values
self.state = {
  name: 'Foo',
  color: self.availableColors[0].value
};

This initial setting of state enables our component to render both a name and a color on load, which prevents it from looking broken.

Next, we’ll add our render function. This is a pure function, which does nothing but render the component based on the initial state or any state changes during the component’s lifecycle. You may have guessed already, but this is where the main body of our JSX lives.

Wait up! What’s a pure function? Welcome to functional programming, a hot topic in the React world. Pure functions are functions where, for input X, the output will always be Y. In an "impure" function, input X might result in different outputs, depending other parts of the program. Here’s a CodePen comparing pure and impure functions. Check out this article out, too, for more details.

Now, because there’s quite a lot of markup in this single component, we’re going to copy the whole lot into our function. Add the following under your constructor:

render() {
  let self = this;
  
  return (
    <main className="about" style={ { background: self.state.color } }>
      <section className="about__inner">
        <article className="about__content">
          { self.state.name ? <p>Hello there. My name is { self.state.name }, and my favourite color is { self.getActiveColorName() }</p> : null }
        </article>
        <form className="[ about__form ] [ boilerform ]">
          <div>
            <label className="c-label" htmlFor="name_field">Your name</label>
            <input className="c-input-field" type="text" id="name_field" value={ self.state.name } onChange={ self.updateName.bind(self) } />
          </div>
          <div>
            <label className="c-label" htmlFor="color_field">Your favourite color</label>
            <div className="c-select-field">
              <select className="c-select-field__menu" value={ self.state.color } onChange={ self.updateColor.bind(self) } id="color_field">
                { self.availableColors.map((color, index) => {
                  return (
                    <option key={ index } value={ color.value }>{ color.name }</option>
                  );
                })}
              </select>
              <span className="c-select-field__decor" aria-hidden="true" role="presentation">▾</span>
            </div>
          </div>
        </form>
      </section>
    </main>
  );
};

You may be thinking something like: “Holy cow, there’s a lot going on here.” Let’s dissect it, so don’t worry about copying code for a bit—I’ll let you know where we’re going to do that again. Let’s just focus on some key bits for now.

In JSX, you need to return a single element, which can have child elements. Because all of our code is wrapped in a <main> tag, we’re all good there. On that <main> tag, you’ll see we have an expression in an attribute, like we covered in Part 2. This expression sets the background color as the current active color that’s set in our state. This will update like magic when a user changes their color choice without us having to write another line of code for it in this render function. Pretty cool, huh?

Inside the <article class="about__content"> element, you’ll notice this:

{ self.state.name ? <p>Hello there. My name is { self.state.name }, and my favourite color is { self.getActiveColorName() }</p> : null }

This ternary operator checks to see if there’s a name set and renders either a sentence containing the name or null. Returning null in JSX is how you tell it to render nothing to the client. Also related to this snippet: we were able to run this ternary operator within our JSX because we created an expression by opening some brackets. It’s a really useful way of sprinkling small, simple bits of display logic within your render function.

Next up, let’s look at an event binding:

<input className="c-input-field" type="text" id="name_field" value={ self.state.name } onChange={ self.updateName.bind(self) } />

If you don’t bind an event to your input field, it’ll be read only. Don’t panic about forgetting though. React helpfully warns you in your console.

Remember, self is equal to this, so what we’re doing is attaching the updateName function to the input’s onChange event, but we’re also binding self, so that when we’re within the updateName function, this will equal AboutMe, which is our component.

The last thing we’re going to look at in the render function is loops. Here’s the snippet that renders the color menu:

<select className="c-select-field__menu" value={ self.state.color } onChange={ self.updateColor.bind(self) } id="color_field">
  { self.availableColors.map((color, index) => {
    return (
      <option key={ index } value={ color.value }>{ color.name }</option>
    );
  }) }
</select>

The value and change setup is the same as the above <input /> element, so we’ll ignore them and dive straight in to the loop. What we’ve done is open up an expression where we run a pretty standard Array Map function, but, importantly, it returns JSX in each iteration, which allows each option to render with the rest of the JSX.

Wiring it all up

Now that we’ve got our core aspects of the component running, we need to wire it up. You’ll notice that your CodePen isn’t doing anything at the moment. That’s because of two things:

  • We haven’t attached the component to the DOM yet
  • We haven’t written any methods to make it interactive

Let’s start with the former and add our change event handlers. Add the following underneath your constructor function:

updateName(evt) {
  let self = this;
  
  self.setState({
    name: evt.target.value
  })
};

updateColor(evt) {
  let self = this;
  
  self.setState({
    color: evt.target.value
  })
};

These two functions handle the onChange events of the <select> and <input> and set their values in state using React’s setState function. Now that the values are in state, anything that is subscribed to them will update automatically. This means that the ternary statement that renders your name and the background color will change in realtime as you type/select. Awesome. right?

Now, it would be recommended to make your code more DRY by combining these two as one change event handler that updates the relevant state. For this series though, let’s keep things simple and more understandable. 😀

Next up, let’s add the last method to our component. Add the following under your recently added update methods:

// Return active color name from available colors, based on state value
getActiveColorName() {
  let self = this;
  
  return self.availableColors.filter(color => color.value === self.state.color)[0].name;
};

This function uses one of my favorite JavaScript array methods: filter. With ES6, we can cherry pick array items based on their object value in one line, which is powerful stuff. With that power, we can pick the currently active availableColors item’s human-readable name and return it back.

JavaScript array methods are very cool and commonly spotted in the React ecosystem. Sarah Drasner made a seriously amazing “Array Explorer”—check it out here!

Attaching the component to the DOM

The last thing we’re going to do is attach our component to the DOM, using ReactDOM. What we’re doing is saying, “Hey browser, fetch me the <div id="root"> element and render this React component in it.” ReactDOM is doing all the magic that makes that possible.

ReactDOM is a really smart package that takes changes in your dynamic React components, calculates what needs to be changed in the DOM and applies those changes in the most efficient possible way. With ReactDOM’s renderToString() method, you can also render your React components to a static string, which can then be inserted to your page with your server-side code. What’s smart about this is that references are added so that if your front-end picks up some server-rendered React, it’ll work out which components are needed and make the whole chunk of static markup dynamic automatically. Pretty damn smart, huh?

Anyway, back to our Pen. Add this right at the bottom of your JS editor:

// Attach our component to the <div id="root"> element
ReactDOM.render(<AboutMe />, document.getElementById('root'));

Now, you’ll notice that your preview window has suddenly come alive! Congratulations — you just wrote a React component 🎉

See the Pen About Me React Component by Andy Bell (@hankchizlja) on CodePen.

Wrapping up

In this part, you’ve learned about reactive, component JavaScript by writing a React component. This is relevant to your learning because custom Gutenberg blocks follow a very similar setup to a React component. Now that you’ve got a better understanding of how a React component works, you should be able to understand how a custom Gutenberg block works too.

It took me a bit to wrap my mind around the fact that, in terms of Gutenberg, React is only relevant to building blocks within the admin. In Gutenberg, React functions as a means of preparing the markup to be saved to the database in the post_content column. Using React on the front-end of a WordPress site to build something like this would be separate from what we will be doing in this series.

Next up in this series, we’re going to edit our WordPress theme so that we can build our custom Gutenberg block.


Article Series:

  1. Series Introduction
  2. What is Gutenberg, Anyway?
  3. A Primer with create-guten-block
  4. Modern JavaScript Syntax
  5. React 101 (This Post)
  6. Setting up a Custom webpack (Coming Soon!)
  7. A Custom "Card" Block (Coming Soon!)

The post Learning Gutenberg: React 101 appeared first on CSS-Tricks.

17:00

WordPress Gutenberg Block API: Creating Custom Blocks

The new WordPress editor (codenamed Gutenberg) is due for release in version 5.0. Now is the perfect time to get to grips with it before it lands in WordPress core. In this series, I'm showing you how to work with the Block API and create your very own content blocks which you can use to build out your posts and pages.

In the previous post, we saw how to use the create-guten-block toolkit to create a plugin containing a sample block ready for us to work with. We can easily extend this as required, but it's a good idea to know how to create a block from scratch to fully understand all aspects of Gutenberg block development.

  • WordPress
    WordPress Gutenberg Block API: Block Look and Feel
    David Gwyer

In this post we'll create a second block in our my-custom-block plugin to display a random image from the PlaceIMG web service. You'll also be able to customize the block by selecting the image category from a drop-down select control.

But first we'll learn how block scripts and styles are enqueued before moving on to the all-important registerBlockType() function, which is fundamental to creating blocks in Gutenberg.

Enqueueing Block Scripts and Styles

To add the JavaScript and CSS required by our blocks, we can use two new WordPress hooks provided by Gutenberg:

  • enqueue_block_editor_assets
  • enqueue_block_assets

These are only available if the Gutenberg plugin is active, and they work in a similar way to standard WordPress hooks for enqueueing scripts. However, they are intended specifically for working with Gutenberg blocks.

The enqueue_block_editor_assets hook adds scripts and styles to the admin editor only. This makes it ideal for enqueueing JavaScript to register blocks and CSS to style user interface elements for block settings.

For block output, though, you'll want your blocks to render the same in the editor as they do on the front end most of the time. Using enqueue_block_assets makes this easy as styles are automatically added to both the editor and front end. You can also use this hook to load JavaScript if required.

But you might be wondering how to enqueue scripts and styles only on the front end. There isn't a WordPress hook to allow you to do this directly, but you can get around this by adding a conditional statement inside the enqueue_block_assets hook callback function.

To actually enqueue scripts and styles using these two new hooks, you can use the standard wp_enqueue_style() and wp_enqueue_scripts() functions as you normally would.

However, you need to make sure that you're using the correct script dependencies. For enqueueing scripts on the editor, you can use the following dependencies:

  • scripts: array( 'wp-blocks', 'wp-i18n', 'wp-element', 'wp-components' )
  • styles: array( 'wp-edit-blocks' )

And when enqueueing styles for both the editor and front end, you can use this dependency:

  • array( 'wp-blocks' )

One thing worth mentioning here is that the actual files enqueued by our my-custom-block plugin are the compiled versions of JavaScript and CSS and not the files containing the JSX and Sass source code.

This is just something to bear in mind when manually enqueueing files. If you try to enqueue raw source code that includes React, ES6+, or Sass then you'll encounter numerous errors.

This is why it's useful to use a toolkit such as create-guten-block as it processes and enqueues scripts for you automatically!

Registering Gutenberg Blocks

To create a new block, we need to register it with Gutenberg by calling registerBlockType() and passing in the block name plus a configuration object. This object has quite a few properties that require proper explanation.

Firstly, though, let's take a look at the block name. This is the first parameter and is a string made up of two parts, a namespace and the block name itself, separated by a forward slash character.

For example:

If you're registering several blocks in a plugin then you can use the same namespace to organize all your blocks. The namespace must be unique to your plugin, though, which helps prevent naming conflicts. This can happen if a block with the same name has already been registered via another plugin.

The second registerBlockType() parameter is a settings object and requires a number of properties to be specified:

  • title (string): displayed in the editor as the searchable block label
  • description (optional string): describes the purpose of a block
  • icon (optional Dashicon or JSX element): icon associated with a block
  • category (string): where the block appears in the Add blocks dialog
  • keywords (optional array): up to three keywords used in block searches
  • attributes (optional object): handles the dynamic block data
  • edit (function): a function that returns markup to be rendered in the editor
  • save (function): a function that returns markup to be rendered on the front end
  • useOnce (optional boolean): restrict block from being added more than once
  • supports (optional object): defines block-supported features

Assuming we're using JSX for block development, here's what an example registerBlockType() call could look like for a very simple block:

Notice how we didn't include an entry for the description, attributes, useOnce, and supports properties? Any fields that are optional (and not relevant to your block) can be safely omitted. For example, as this block didn't involve any dynamic data, we don't need to worry about specifying any attributes.

Let's now cover the registerBlockType() configuration object properties in more detail one by one.

Title and Description

When inserting or searching for a block in the editor, the title will be displayed in the list of available blocks.

It's also displayed in the block inspector window, along with the block description if defined. If the block inspector isn't currently visible then you can use the gear icon in the top right corner of the Gutenberg editor to toggle visibility.

Block title and description

Both the title and description fields should ideally be wrapped in i18n functions to allow translation into other languages.

Category

There are five block categories currently available:

  • common
  • formatting
  • layout
  • widgets
  • embed

These determine the category section where your block is listed inside the Add block window.

Block categories

The Blocks tab contains Common Blocks, Formatting, Layout Elements, and Widgets categories, while the Embeds category has its own tab.

Categories are currently fixed in Gutenberg, but this could be subject to change in the future. This would be useful, for instance, if you were developing multiple blocks in a single plugin and you wanted them all to be listed under a common category so users could locate them more easily.

Icon

By default, your block is assigned the shield Dashicon, but you can override this by specifying a custom Dashicon in the icon field.

Dashicons

Each Dashicon is prefixed with dashicons- followed by a unique string. For example, the gear icon has the name dashicons-admin-generic. To use this as a block icon, just remove the dashicons- prefix for it to be recognised, e.g. icon: 'admin-generic'.

However, you aren't just limited to using Dashicons as the icon property. The function also accepts a JSX element, which means you can use any image or SVG element as your block icon. 

Just make sure to keep the icon size consistent with other block icons, which is 20 x 20 pixels by default.

Keywords

Choose up to three translatable keywords to help make your block stand out when users search for a block. It's best to choose keywords that closely relate to the functionality of your block for best results.

You could even declare your company and/or plugin name as keywords so that if you have multiple blocks, users can start typing your company name and all your blocks will appear in search results.

Although adding keywords is entirely optional, it's a great way to make it easier for users to find your blocks.

Attributes

Attributes help with managing dynamic data in a block. This property is optional as you don't need it for very simple blocks that output static content.

However, if your block deals with data that could change (such as the contents of an editable text area) or you need to store block settings, then using attributes is the way to go. 

Attributes work by storing dynamic block data either in the post content saved to the database or in post meta. In this tutorial we'll only be using attributes that store data along with the post content.

To retrieve attribute data stored in post content, we need to specify where it's located in the markup. We can do this by specifying a CSS selector that points to the attribute data.

For example, if our block contained an anchor tag, we can use its title field as our attribute as follows:

Here, the attribute name is linktitle, which is an arbitrary string and can be anything you like.

For example, we could use this attribute to store the link title <a title="some title"> that's been entered via a textbox in block settings. Doing so suddenly makes the title field dynamic and allows you to change its value in the editor.

When the post is saved, the attribute value is inserted into the links title field. Similarly, when the editor is loaded, the value of the title tag is retrieved from the content and inserted into the linktitle attribute.

There are more ways you can use source to determine how block content is stored or retrieved via attributes. For instance, you can use the 'text' source to extract the inner text from a paragraph element.

You can also use the children source to extract all child nodes of an element into an array and store it in an attribute.

This selects the element with class .parent and stores all child nodes in the editablecontent attribute.

If you don't specify a source then the attribute value is saved in HTML comments as part of the post markup when saved to the database. These comments are stripped out before the post is rendered on the front end.

We'll be seeing a specific example of this type of attribute when we get into implementing our random image block later in this tutorial.

Attributes can take a little getting used to, so don't worry if you don't fully understand them first time around. I'd recommend taking a look at the attributes section of the Gutenberg handbook for more details and examples.

Edit

The edit function controls how your block appears inside the editor interface. Dynamic data is passed to each block as props, including any custom attributes that have been defined.

It's common practice to add className={ props.className } to the main block element to output a CSS class specific to your block. WordPress doesn't add this for you inside the editor, so it has to be added manually for each block if you want to include it.

Using props.className is standard practice and is recommended as it provides a way to tailor CSS styles for each individual block. The format of the generated CSS class is .wp-block-{namespace}-{name}. As you can see, this is based on the block namespace/name and makes it ideal to be used as a unique block identifier.

The edit function requires you to return valid markup via the render() method, which is then used to render your block inside the editor.

Save

Similar to the edit function, save displays a visual representation of your block but on the front end. It also receives dynamic block data (if defined) via props.

One main difference is that props.className isn't available inside save, but this isn't a problem because it's inserted automatically by Gutenberg.

Supports

The supports property accepts an object of boolean values to determine whether your block supports certain core features.

The available object properties you can set are as follows.

  • anchor (default false): allows you to link directly to a specific block
  • customClassName (true): adds a field in the block inspector to define a custom className for the block 
  • className (true): adds a className to the block root element based on the block name
  • html (true): allows the block markup to be edited directly

The useOnce Property

This is a useful property that allows you to restrict a block from being added more than once to a page. An example of this is the core More block, which can't be added to a page if already present.

useOnce property

As you can see, once the More block has been added, the block icon is grayed out and can't be selected. The useOnce property is set to false by default.

Let's Get Creative!

It's time now to use the knowledge we've gained so far to implement a solid working example of a block that does something more interesting than simply output static content.

We'll be building a block to output a random image obtained via an external request to the PlaceIMG website, which returns a random image. Furthermore, you'll be able to select the category of image returned via a select drop-down control.

Our random image block

For convenience, we'll add our new block to the same my-custom-block plugin, rather than creating a brand new plugin. The code for the default block is located inside the /src/block folder, so add another folder inside /src called random-image and add three new files:

  • index.js: registers our new block
  • editor.scss: for editor styles
  • style.scss: styles for the editor and front end

Alternatively, you could copy the /src/block folder and rename it if you don't want to type everything out by hand. Make sure, though, to rename block.js to index.js inside the new block folder.

We're using index.js for the main block filename as this allows us to simplify the import statement inside blocks.js. Instead of having to include the path and full filename of the block, we can just specify the path to the block folder, and import will automatically look for an index.js file.

Open up /src/blocks.js and add a reference to our new block at the top of the file, directly underneath the existing import statement.

Inside /src/random-image/index.js, add the following code to kick-start our new block.

This sets up the framework of our block and is pretty similar to the boilerplate block code generated by the create-guten-block toolkit.

We start by importing the editor and front-end style sheets, and then we'll extract some commonly used functions from wp.i18n and wp.blocks into local variables.

Inside registerBlockType(), values have been entered for the title, icon, category, and keywords properties, while the edit and save functions currently just output static content.

Add the random image block to a new page to see the output generated so far.

Bare bones block output

Make sure you're still watching files for changes so any block source code (JSX, ES6+, Sass, etc.) is transpiled into valid JavaScript and CSS. If you aren't currently watching files for changes, then open a command line window inside the my-custom-block plugin root folder and enter npm start.

You might be wondering why we didn't have to add any PHP code to enqueue additional block scripts. The block scripts for the my-custom-block block are enqueued via init.php, but we don't need to enqueue scripts specifically for our new block as this is taken care of for us by create-guten-block.

As long as we import our main block file into src/blocks.js (as we did above) then we don't need to do any additional work. All JSX, ES6+, and Sass code will automatically be compiled into the following files:

  • dist/blocks.style.build.css: styles for editor and front end
  • dist/blocks.build.js: JavaScript for editor only
  • dist/blocks.editor.build.css: styles for editor only

These files contain the JavaScript and CSS for all blocks, so only one set of files needs to be enqueued, regardless of the number of blocks created!

We're now ready to add a bit of interactivity to our block, and we can do this by first adding an attribute to store the image category.

This creates an attribute called category, which stores a string with a default value of 'nature'. We didn't specify a location in the markup to store and retrieve the attribute value, so special HTML comments will be used instead. This is the default behavior if you omit an attribute source.

We need some way of changing the image category, which we can do via a select drop-down control. Update the edit function to the following:

Here is what it will look like:

Adding a block select drop down control

This is quite different from the previous static edit function, so let's run through the changes.

First we've added a select drop-down control with several choices matching the image categories available on the PlaceIMG site.

PlaceIMG image categories

When the drop-down value changes, the setCategory function is called, which finds the currently selected category and then in turn calls the setAttributes function. This is a core Gutenberg function and updates an attribute value correctly. It's recommended that you only update an attribute using this function.

Now, whenever a new category is selected, the attribute value updates and is passed back into the edit function, which updates the output message.

Image category updated

We have to complete one last step to get the random image to display. We need to create a simple component that will take in the current category and output an <img> tag with a random image obtained from the PlaceIMG site.

The request we need to make to PlaceIMG is of the form: https://placeimg.com/[width]/[height]/[category]

We'll keep the width and height fixed for now, so we only have to add the current category onto the end of the request URL. For example, if the category was 'nature' then the full request URL would be: https://placeimg.com/320/220/nature.

Add a RandomImage component above registerBlockType():

To use it, just add it inside the edit function and remove the static output message. While we're at it, do the same for the save function.

The full index.js file should now look like this:

Finally (for now), add the following styles to editor.scss to add a colored border around the image.

You'll also need some styles in style.css.

Whenever the page is refreshed in the editor or on the front end, a new random image will be displayed. 

Finished editor view Final front end view

If you're seeing the same image displayed over and over, you can do a hard refresh to prevent the image being served from your browser cache.

Conclusion

In this tutorial we've covered quite a lot of ground. If you've made it all the way through then give yourself a well-deserved pat on the back! Gutenberg block development can be a lot of fun, but it's definitely challenging to grasp every concept on first exposure.

Along the way, we've learned how to enqueue block scripts and styles and covered the registerBlockType() function in depth.

We followed this up by putting theory into practice and creating a custom block from scratch to display a random image from a specific category using the PlaceIMG web service.

In the next and last part of this tutorial series, we'll add more features to our random image block via the settings panel in the block inspector.

If you've been following along with this tutorial and just want to experiment with the code without typing everything in, you'll be able to download the final my-custom-block plugin in the next tutorial.

16:09

25 Creative Website Templates with Smart and Eye-Catching Designs

Today’s article is about creativity in web design. Whether you’re a photographer, a sketch artist, a DJ or a fashion blogger, we’re sure this list of 25 creative website templates will definitely help you better understand which kind of template is best for your website.

Haar

Haar is a WordPress theme with minimalist design best suited for any painters and designers. It’s easy to use, has a powerful and simple admin interface, a fully responsive design, is retina ready, has a large collection of pages, a visual composer page builder, slider revolution plugin, various layout pages and many other helpful options. It’s easy to install and use and has many customization tools.

1 Haar Creative Website Templates

Artday

Artday is a fully responsive WordPress theme better suited for online shop websites. The design is classy, minimalistic and modern, fully responsive and highly customizable. Other features include a content builder, a revolution slider plugin, various page styles, WooCommerce plugin, automatic theme updates, is retina ready, has many blog layouts you can choose from and other great options.

2 Artday Creative Website Templates

FullScreen Artist

Fullscreen Artist is a WordPress theme better suited for any graphic designer, artist, craftsman, painter, sculptor or photographer that seeks a deep visual impact on their website. The design is minimalistic and offers a dynamic experience.

3 FullScreen Creative Website Templates

Mixtape

Mixtape is a WordPress theme dedicated to any music related professional. The design is highly customizable, fully responsive on any mobile device, no coding is required to install and use, has a visual composer plugin, slider revolution, many album layouts and album related buttons and icons, great image gallery and many other great options.

4 Mixtape Creative Website Templates

Fotografia

This theme has a simple but interesting design, minimalistic and modern, which can be used by any photography professional or blogger. Some features include a great photo showcase template, different visual layouts for the blog, image and video slideshows, many layout options, great customization tools and a fully responsive design that looks great on any mobile device.

5 Fotografia Creative Website Templates

Artiste

Artiste has a high-tech aspect and it comes with full background slider and videos, an animated footer, a great background image gallery and many other cool features. It’s best suited for any graphic design professionals for showcasing portfolio works.

6 ARTISTE Creative Website Templatess

Artist Sketch

This WordPress theme has a simple design made to look like a hand drawing and it’s perfect for any hand sketch artist to showcase works. Some features include SEO optimization, great portfolio layouts and sections, customizable columns and sections, responsive galleries and design, and other helpful options.

7 Artist Sketch Creative Website Templates

Wonder

Wonder has a simple, classy, modern and minimalistic look and it’s best suited for portfolio websites. It comes with audio and video galleries, many portfolio layouts and sections, simple customization tools and a fully responsive design.

8 Wonder Creative Website Templates

Astir

Astir is elegant, simple and modern and it’s perfect for photographers, digital artist, architects, designers, and any other creative websites. It is SEO optimized, has a drag and drop builder, many color schemes and great customization tools.

9 Astir Creative Website Templates

Natural Born Artist

Natural Born Artist is another fully responsive WordPress theme which can be used for multiple types of websites. It includes a light and dark theme, different color schemes, various homepage options, portfolio layouts, many page templates, great support and a highly responsive design.

10 Natural Born Artist Creative Website Templates

FolioBlog

FolioBlog has a minimalistic and neat look and it’s fully responsive on any device. This theme can be used for any creative websites, such as blogs, portfolios or agency websites.

11 FolioBlog Creative Website Templates

Nava

Nava is elegant, minimalistic and modern and seems like the perfect choice for any music related professionals, freelancers or just DJ’s that need to display any music works. Background colors and images are easily changeable, the theme has many customization tools, the design is fully responsive, it comes with unlimited color schemes, is retina ready and easy to install and use.

12 Nava Creative Website Templates

Artist Painter 

Artist Painter is another WordPress theme with a fully responsive design, which is best suited for any painters or drawing artists. The design is minimalistic, modern and has a deep visual impact through the imposing fullscreen image, which is easily changeable. Other features include a cool drag and drop page builder, an easy setup, many customization tools and much more.

13 Artist Painter Creative Website Templates 

Polyphonic

Polyphonic WordPress theme was created especially for music related professionals and can be used as an audio portfolio website. It comes with an easy to use admin panel, 6 homepage styles, a large gallery of layouts and sections, a useful custom map pin plugin for events, full-screen image slider, a highly customizable design and many other great features.

14 Polyphonic Creative Website Templates

Mindest

Mindest is another WordPress minimalistic theme which can be used for any creative website or blogs such as for photographers, graphic design portfolios, fashion blogs or an elegant magazine website. It’s easy to install and customize, has many great features and a highly responsive design on any device.

15 Mindest Creative Website Templates

Red Art Photography 

Red Art Photography WordPress theme is an excellent choice for any type of portfolio. It can be used by photographers, artisans, designers, and architects. It comes with many page styles, a full-screen slider, many layout options, a great visual composer and much more.

16 Red Art Photography Creative Website Templates

Apolo

Apolo has a uniquely modern and minimalistic look and it’s best suited for any photography or travel blogs. This theme is retina ready, has a fully responsive design, it’s easy to install, modify and customize, 8 homepage layouts, 3 different portfolio layouts, 7 header options and 3 footer layouts.

17 APOLO Creative Website Templates

Ergo7

Ergo7 is another WordPress theme dedicated to any music related website and comes with a modern and minimalistic design, a fully responsive layout and many customization tools.

18 Ergo7 Creative Website Templates

HandArt

If you’re searching for an online store for home design products, then Handart is a perfect choice. This theme has a fully responsive design, is retina ready, has more than 4 homepage layout styles, an easy to use admin panel, many customization tools, and other great features.

19 HandArt Creative Website Templates

The Curator

The Curator is a timeline WordPress theme created especially for artists that need to showcase their works in a chronological line.

20 The Curator Creative Website Templates

Koi

Koi comes with a dynamic layout in multiple images and colors which can be easily changed. The design is modern, minimalistic and neat, has a grid-based structure, many portfolio options, and it’s best suited for any photographers and artist websites.

21 Koi Creative Website

Presskit/Résumé

This minimalistic theme is dedicated to artists and musicians who need to have a presentation website. Presskit comes with 7-page templates, many image galleries, an audio player, an easy setup process and many other helpful tools.

22 Presskit:Résumé Creative Website

Ultra Vibes

Ultra Vibes is another music-related WordPress theme and it’s dedicated to professionals like DJ’s and producers.

23 Ultra Vibes Creative Website

Tore

Tore has a simple and modern look, a fully responsive design and great optimization tools. It’s a perfect choice for any architectural portfolio website.

24 Tore Creative Website

Slide

Slide is another WordPress music theme, suitable for musicians, artists, music bands, producers or anyone working in the music industry. The design is minimalistic, modern and catchy and it comes with great customization tools and features.

25 Slide Creative Website

The post 25 Creative Website Templates with Smart and Eye-Catching Designs appeared first on Line25.

14:03

Learning Gutenberg: Modern JavaScript Syntax

One of the key changes that Gutenberg brings to the WordPress ecosystem is a heavy reliance on JavaScript. Helpfully, the WordPress team have really pushed their JavaScript framework into the present and future by leveraging the modern JavaScript stack, which is commonly referred to as ES6 in the community. It’s how we’ll refer to it as in this series too, to avoid confusion.

Let’s dig into this ES6 world a bit, as it’s ultimately going to help us understand how to structure and build a custom Gutenberg block.

Article Series:

  1. Series Introduction
  2. What is Gutenberg, Anyway?
  3. A Primer with create-guten-block
  4. Modern JavaScript Syntax (This Post)
  5. React 101 (Coming Soon!)
  6. Setting up a Custom webpack (Coming Soon!)
  7. A Custom "Card" Block (Coming Soon!)

What is ES6?

ES6 is short for “EcmaScript 6” which is the 6th edition of EcmaScript. It’s official name is ES2015, which you may have also seen around. EcmaScript has since gone through many iterations, but modern JavaScript is still often referred to as ES6. As you probably guessed, the iterations have continued ES2016, ES2017 and so-on. I actually asked a question on ShopTalk show about what we could name modern JavaScript, which I the conclusion was... ES6.

I’m going to run through some key features of ES6 that are useful in the context of Gutenberg.

Functions

Functions get a heck of an update with ES6. Two changes I want to focus on are Arrow Functions and Class Methods.

Inside a class you don’t actually need to write the word function anymore in ES6. This can be confusing, so check out this example:

class Foo { 
  // This is your 'bar' function
  bar() {
    return 'hello';
  }
}

You’d invoke bar() like this:

const fooInstance = new Foo();
const hi = fooInstance.bar();

This is commonplace in the land of modern JavaScript, so it’s good to clear it up.

Fun fact! ES6 Classes in JavaScript aren’t really “classes” in an object-oriented programming sense—under the hood, it’s the same old prototypical inheritance JavaScript has always had. Prior to ES6, the bar() method would be defined like so: Foo.prototype.bar = function() { ... }. React makes great use of ES6 classes, but it’s worth noting that ES6 classes are essentially syntactic sugar and hotly contested by some. If you’re interested in more details, checkout the MDN docs and this article on 2ality.

Right, let’s move on to arrow functions. 🚀

An arrow function gives us a compact syntax that is often used as a one-liner for expressions. It’s also used to maintain the value of this, as an arrow function won’t rebind this like setInterval or an event handler would usually do.

An example of an arrow function as an expression is as follows:

// Define an array of fruit objects
const fruit = [
  {
    name: 'Apple',
    color: 'red'
  },
  {
    name: 'Banana',
    color: 'yellow'
  },
  {
    name: 'Pear',
    color: 'green'
  }
];

// Select only red fruit from that collection
const redFruit = fruit.filter(fruitItem => fruitItem.color === 'red');

// Output should be something like Object { name: "Apple", color: "red" }
console.log(redFruit[0]);

As you can see above, because there was a single parameter and the function was being used as an expression, we can redact the brackets and parenthesis. This allows us to really compact our code and improve readability.

Let’s take a look at how we can use an arrow function as an event handler in our Foo class from before:

class Foo {
        
  // This is your 'bar' function
  bar() {
    let buttonInstance = document.querySelector('button');
    
    buttonInstance.addEventListener('click', evt => {
      console.log(this);
    });
  }
}

// Run the handler
const fooInstance = new Foo();
fooInstance.bar();

When the button is clicked, the output should be Foo { }, because this is the instance of Foo. If we were to replace that example with the following:

class Foo {
        
  // This is your 'bar' function
  bar() {
    let buttonInstance = document.querySelector('button');
    
    buttonInstance.addEventListener('click', function(evt) {
      console.log(this);
    });
  }
}

// Run the handler
const fooInstance = new Foo();
fooInstance.bar();

When the button is clicked, the output would be <button> because the function has bound this to be the <button> that was clicked.

You can read more about arrow functions with Wes Bos, who wrote an excellent article about them.

const, let, and var

You may have noticed that I’ve been using const and let in the above examples. These are also a part of ES6 and I’ll quickly explain what each one does.

If a value is absolutely constant and won’t change through re-assignment, or be re-declared, use a const. This would commonly be used when importing something or declaring non-changing properties such as a collection of DOM elements.

If you have a variable that you want to only be accessible in the block it was defined in, then use a let. This can be confusing to understand, so check out this little example:

function foo() {
  if (1 < 2) {
    let bar = 'always true';
    
    // Outputs: 'always true'
    console.log(bar);
  }
  
  // Outputs 'ReferenceError: bar is not defined'
  console.log(bar);
}

// Run the function so we can see our logs
foo();

This is a great way to keep control of your variables and make them disposable, in a sense.

Lastly, var is the same old friend we know and love so well. Unfortunately, between const and let, our friend is becoming more and more redundant as time goes on. Using var is totally acceptable though, so don’t be disheartened—you just won’t see it much in the rest of this tutorial!

Destructuring assignment

Destructuring allows you to extract object keys at the point where you assign them to your local variable. So, say you’ve got this object:

const foo = {
  people: [
    {
      name: 'Bar',
      age: 30
    },
    {
      name: 'Baz',
      age: 28
    }
  ],
  anotherKey: 'some stuff',
  heyAFunction() {
    return 'Watermelons are really refreshing in the summer' 
  }
};

Traditionally, you’d extract people with foo.people. With destructuring, you can do this:

let { people } = foo;

That pulls the people array out of the the foo object, so we can dump the foo. prefix and use it as it is: people. It also means that anotherKey and heyAFunction are ignored, because we don’t need them right now. This is great when you’re working with big complex objects where being able to selectively pick stuff out is really useful.

You can also make use of destructuring to break up an object into local variables to increase code readability. Let’s update the above snippet:

let { people } = foo;
let { heyAFunction } = foo;

Now we’ve got those two separate elements from the same object, while still ignoring anotherKey. If you ran console.log(people), it’d show itself an array and if you ran console.log(heyAFunction), you guessed it, it’d show itself as a function.

JSX

Most commonly found in React JS contexts: JSX is an XML-like extension to JavaScript that is designed to be compiled by preprocessors into normal JavaScript code. Essentially, it enables us to write HTML(ish) code within JavaScript, as long as we’re preprocessing it. It’s usually associated with a framework like React JS, but it’s also used for Gutenberg block development.

Let’s kick off with an example:

const hello = <h1 className="heading">Hello, Pal</h1>;

Pretty cool, huh? No templating system or escaping or concatenating required. As long as you return a single element, which can have many children, you’re all good. So let’s show something a touch more complex, with a React render function:

class MyComponent extends React.Component {
  /* Other parts redacted for brevity */
  
  render() {
    return (
      <article>
        <h2 className="heading">{ this.props.heading }</h2>
        <p className="lead">{ this.props.summary }</p>
      </article>
    );
  }
};

You can see above that we can drop expressions in wherever we want. This is also the case with element attributes, so we can have something like this:

<h2 className={ this.props.headingClass }> 
  { this.props.heading }
</h2> 

You might be thinking, “What are these random braces doing?”

The answer is that this is an expression, which you will see a ton of in JSX. Essentially, it’s a little inline execution of JavaScript that behaves very much like a PHP echo does.

You’ll also probably notice that it says className instead of class. Although it looks like HTML/XML, it’s still JavaScript, so reserved words naturally are avoided. Attributes are camel-cased too, so keep and eye out for that. Here’s a useful answer to why it’s like this.

JSX is really powerful as you’ll see while this series progresses. It’s a great tool in our stack and really useful to understand in general.

I like to think of JSX as made up-tag names that are actually just function calls. Pick out any of the made-up tags you see in Gutenberg, let's use <InspectorControls /> for example, and do a "Find in Folder" for class InspectorControls and you’ll see something structured like Andy’s example here! If you don't find it, then the JSX must be registered as functional component, and should turn up by searching for function InspectorControls.

Wrapping up

We’ve had a quick run through some of the useful features of ES6. There’s a ton more to learn, but I wanted to focus your attention on the stuff we’ll be using in this tutorial series. I’d strongly recommend your further your learning with Wes Bos’ courses, JavaScript 30 and ES6.io.

Next up, we’re going to build a mini React component!


Article Series:

  1. Series Introduction
  2. What is Gutenberg, Anyway?
  3. A Primer with create-guten-block
  4. Modern JavaScript Syntax (This Post)
  5. React 101 (Coming Soon!)
  6. Setting up a Custom webpack (Coming Soon!)
  7. A Custom "Card" Block (Coming Soon!)

The post Learning Gutenberg: Modern JavaScript Syntax appeared first on CSS-Tricks.

14:00

What Is Holistic Web Design?

Google “holistic web design” and you’ll see a lot of results that encompass health and wellness. But that’s not really what designers and developers usually mean when they mention holistic web design.

In the most simple of explanations – we’ll dig deeper after this – holistic web design is a process of thinking about all the parts of a project, and understanding and accounting for how they connect. Great content will fall apart if the visuals are poor. And equally, the best-looking website in the world doesn’t do anything if it isn’t highly usable. These are the issues that holistic web design solves before they even become problems.

Here’s how it works (and can work for you), with examples from the Design Shack Gallery.

Holistic Design Philosophy

holistic web design

When it comes down to it, holistic web design is about a process. The steps and planning can be a little different for every design/dev team, but they do have a lot of commonalities.

Design, technology, performance and business impacts are major considerations from the designer standpoint. Other phases such as planning and research are often conducted by someone else, although if you are a one-person shop, you might perform these roles as well. These elements can be further broken into other procedural steps as well: content and messaging, UI design, UX design, visual design, development, testing, training, and feedback.

All these steps can look different depending on who is planning the project. One of the best checklists to help you make sure you fully understand the idea behind holistic web design is from Webdesigner Depot. The article includes six questions to ask before you make anything:

In web design and development, cause and effect can usually be seen almost immediately. Things happen fast, and everything you do will affect your users, yourself, any employees you have, your shareholders, and some people you might not even consider in the equation. It will affect all of your lives whether for good or ill.

Planning and Research

holistic web design

In the planning and research phase of a web design project you should really do three major things:

  • Identify goals for the project
  • Define the scope of the project
  • Define an audience or user persona for the project

These elements will shape how the project comes together and should be the foundation for everything else moving forward. If a project doesn’t meet project goals or fall within scope, it should be re-evaluated.

Design

holistic web design

The design phases are often the most fun parts of a website design project (for creatives, anyway). This is when the wireframes, content, and visuals all start to come together.

Tasks in this part of the process include:

  • Drawing a sitemap and wireframes (based on the scope of the project)
  • Creating and gathering all the content – photos, text, video, animations, etc.
  • Crafting visual elements that include anything from mood boards to actual palettes for the project
  • Developing a strong layout and hierarchy with an efficient information architecture

Technology and Performance

holistic web design

Make sure to incorporate an SEO strategy into the design.

One of the greatest functions (and limitations) of a website design can relate to technology. Will the website that you’ve designed actually work? And does it work efficiently and understandably for all users?

There are too many technological concerns to list from website speed to tools that you might incorporate and integrate to meet goals. The takeaway is this: They need to work for the website owner (collecting the right data in a manner they understand) and the user (the site has to be fast and easy to use).

When it comes to performance, there are the technical considerations plus one more – search. A solid segment of most website traffic is directed to a website because of search. Make sure to incorporate an SEO strategy into the design. (Something as simple as uploading images into the content management system relates to search, so plan for it before you get too far along.)

You can weigh the pros and cons of what tools to use, CMS to install, and plugins to offer based on the scope of individual projects. But know that technology and performance are not a one-size-fits-all solution.

Business Impacts

holistic web design

Once you have a great design, the work isn’t done. A good holistic website strategy looks at how the design and the function help a company meet business goals as well. (That’s probably why a website is part of the overall strategy in the first place.)

How will the website design actually impact the business? Is it to help people find information and learn about a company? Is it made for sales or e-commerce?

This is where other considerations come into play as well: Who will be using the website (or maintaining it) on the client side? What feedback, return on investment or analytics data shows that the project is working or is successful?

You probably want to have an idea of the answers from the start. You might design a wholly different interface for an e-commerce design than a website that is purely informational. You might connect the design to other brand channels differently based on the overall goals.

What might be most important though is the circle of feedback. When a user interacts with the website design, they tell you something with every click. You can use that information to ensure that users are performing the desired actions and interacting with the “right” content. You can also use this information to make necessary adjustments. (And that’s the feedback you return to users by making the design even easier for them to use.)

But don’t forget loyal users. This is great advice from the Webdesigner Depot article:

The thing is, those small changes can completely throw existing users, especially if you don’t show them where their old favorite feature went. If you have users who use your site or app every day, it’s important to consider how changes you make will affect their daily lives.

Conclusion

So when approaching a website design project holistically, you are actually thinking about all these things at the same time. The previous and next steps, as well as goals and scope, should always be part of the conversation.

Everything about the design is interrelated. And understanding that is at the root of making a beautiful website that just works.

12:32

Introduction to Popmotion: Pointers and Physics

Welcome back to the Introduction to Popmotion tutorial series. In part 1, we discovered how to use tweens and keyframes to make precise, time-scheduled animations.

In Part 2, we're going to look at pointer tracking and velocity-based animations.

Pointer tracking allows us to create scrollable product shelves, custom value sliders, or drag-and-drop interfaces.

Velocity-based animations are different to a time-based animation like tween in that the primary property that affects how the animation behaves is velocity. The animation itself might take any amount of time.

We'll look at the three velocity-based animations in Popmotion, springdecay, and physics. We'll use the velocity of the pointer tracking animation to start these animations, and that'll demonstrate how velocity-based animations can create engaging and playful UIs in a way that time-based animations simply can't.

First, open this CodePen to play along.

Pointer Tracking

Popmotion provides the pointer function to track and output the coordinates of either a mouse or single touch pointer.

Let's import this along with styler, which will allow us to set the position of the ball.

For this example, we want to drag the ball. Let's add an event that will output the pointer's position to the ball:

We'll also want some code to stop tracking when we release the ball:

If you try and drag the ball now, there's an obvious problem. The ball jumps away when we touch it! Not a great user experience.

This is because, by default, pointer outputs the pointer's position relative to the page.

To output the pointer's position relative to another point, in this case the ball's x/y transform, we can simply pass that position to pointer like this:

Now you've made the ball, in very few lines of code, draggable! However, when the user releases the ball, it stops dead.

This isn't satisfying: Imagine a scrollable carousel of products that a user can drag to scroll. If it just stopped dead instead of momentum scrolling, it'd be less pleasurable to use.

It'd be harder, too, because the overall physical effort needed to scroll the carousel would be higher.

To enable animations like this, we first need to know the velocity of the object being thrown.

Track Velocity

Popmotion provides a function that can help us track velocity. It's called value. Let's import that:

To speak technically for a moment, all of Popmotion's animations are known as actions. Actions are reactive streams of values that can be started and stopped.

A value is, conversely, a reaction. It can't be stopped or started. It just passively responds when its update method is called. It can keep track of values and can be used to query their velocity.

So, after we define ballStyler, let's define a new value for ballXY:

Whenever ballXY updates, we want to update ballStyler. We can pass a second argument to value, a function that will run whenever ballXY updates:

Now we can rewrite our pointer to update ballXY instead of ballStyler.set:

Now, at any pointer, we can call ballXY.getVelocity() and we'll receive the velocities of both x and y, ready to plug into our velocity-based animations.

Velocity-Based Animations

spring

The first velocity-based animation to introduce is spring. It's based on the same equations that govern Apple's CASpringAnimation, the spring animation behind all that iOS springy playfulness.

Import:

Now, amend stopTracking so that instead of stopping the pointerTracker animation, it starts a spring animation like this:

We provide it with the ball's current position, its velocity, and a target, and the simulation is run. It changes depending on how the user has thrown the ball.

The cool thing about springs is they're expressive. By adjusting the massstiffness and damping properties, you can end up with radically different spring-feels.

For instance, if you only change the stiffness above to 1000, you can create a motion that feels like high-energy snapping. Then, by changing mass to 20, you create motion that looks almost like gravity.

There's a combination that will feel right and satisfying for your users, and appropriate to your brand, under almost any circumstance. By playing with different spring-feels, you can communicate different feelings, like a strict out-of-bounds snap or a softer affirmative bounce.

decay

The decay animation, as the name suggests, decays the provided velocity so that the animation gradually slows to a complete stop.

This can be used to create the momentum scrolling effect found on smartphones, like this:

Import the decay function:

And replace the stopTracking function with the following:

decay automatically calculates a new target based on the provided from and velocity props.

It's possible to adjust the feel of the deceleration by messing with the props outlined in the docs linked above but, unlike spring and physicsdecay is designed to work out of the box. 

physics

Finally, we have the physics animation. This is Popmotion's Swiss Army knife of velocity-based animations. With it, you can simulate:

  • constant velocity
  • acceleration
  • springs
  • friction

spring and decay offer super-precise motion and a wider variety of "feels". Soon, they'll both also be scrubbable.

But both are immutable. Once you've started either, their properties are set in stone. Perfect for when we want to start an animation based on the initial from/velocity state, but not so good if we want ongoing interaction.

physics, instead, is an integrated simulation closer to that of a video game. It works by, once per frame, taking the current state and then modifying it based on the current properties at that point in time.

This allows it to be mutable, which means we can change those properties, which then changes the outcome of the simulation.

To demonstrate this, let's make a twist on classic pointer smoothing, with elastic smoothing.

Import physics:

This time, we're going to change the startTracking function. Instead of changing ballXY with pointer, we'll use physics:

Here, we're setting from and velocity as normal. friction and springStrength both adjust the properties of the spring.

restSpeed: false overrides the default behaviour of the animation stopping when motion stops. We want to stop it manually in stopTracking.

On its own, this animation won't do anything because we set to, the spring's target, to the same as from. So let's reimplement the pointer tracking this time to change the spring target of physics. On the last line of startTracking, add:

Here, we're using a similar pointer animation as before. Except this time, we're using it to change the target of another animation. In doing so, we create this elasticated pointer tracking:

Conclusion

Velocity-based animations paired with pointer tracking can create engaging and playful interfaces.

spring can be used to create a wide-variety of spring-feels, while decay is specifically tailored for momentum scroll animations. physics is more limited than either in terms of configurability, but also provides the opportunity to change the simulation in progress, opening new interaction possibilities.

In the next and final part of this introductory series on Popmotion, we're going to take everything we've learned in the first two parts and use them along with some light functional composition to create a scrubbable animation, along with a scrubber to do the scrubbing with!

12:23

What Are the WordPress PHP Coding Standards?

What are the WordPress PHP coding standards? In this video from my course, Learn PHP for WordPress, you'll learn all about the coding standards and why they're important.

The WordPress PHP Coding Standards

 

What Are the WordPress PHP Coding Standards?

You can find the full WordPress PHP coding standards in the official WordPress handbook.

WordPress PHP coding standards

They're essentially a set of best practices on how to use PHP in WordPress. We'll go through some examples of what that means in practice in the rest of this tutorial.

As you can see, there are standards not only for PHP but also for accessibility and for the other languages that you'd use within WordPress. 

Why Are the PHP Coding Standards Important?

Why is it important that we all adhere to these standards? 

Well, there are two reasons. One of them is about quality of code, and the other is about consistency. 

So firstly, quality is important because it means that everybody coding in WordPress is creating code that will work, that will do its job, and that will be written in an up-to-date and high-quality fashion.

The second, which is about consistency, is equally important. It's very likely that you're going to be working with other people's code from time to time. For example, if you're creating a child theme, you might have to copy some of the code from the parent theme. And if you're creating a plugin, that plugin could be a fork of an existing third-party plugin that you're copying and adding extra functionality to. It's really important that the way you code is consistent with the way that everybody else who codes PHP for WordPress writes code themselves. 

Examples of PHP Coding Standards for WordPress

So let's take a look at some of the PHP coding standards. And I'm going to show you examples of these in some of the files in my theme.

Naming Conventions and Cases

Let's start with naming conventions and cases. When you're thinking about naming conventions, there are four things to think about:

  1. the functions within your theme or your plugin
  2. the files and the way that you name those
  3. any classes that you write
  4. any variables that you create

So let's start with functions. Here's the functions.php file in my theme as an example. 

the functionsphp file in my theme

You can see that I've got a function that I've defined called rachelmcc_register_widgets. That's all written in lower case, and I'm using underscores between the words, which is how you should always write a function in WordPress.

As you'll also see, I've used a prefix. That's to ensure that this function doesn't clash with any other functions that might be provided by my theme or by another plugin. So if I wrote a function that was just called register_widgets and one of my plugins also had a function called register_widgets, the two of them could clash. You might find that one of them overrides the other or that the plugin doesn't work. 

So instead, I'm using a unique function that's relevant to my theme. My theme is called rachelmccollin, so my functions have rachelmcc as a prefix. And it's also important to use underscores for your functions and not to use hyphens.

You do use hyphens in two places. Firstly, you use hyphens when you're defining CSS classes. So you can see that within my widgets, I'm defining CSS classes for my h3 element and also for the id of that widget area. And here, you use hyphens.

The other place that you use hyphens is in your file names. So this is front-page.php. 

the front-pagephp file

You should always use hyphens in your file names within your themes and your plugins; don't use underscores. So here there is a call using locate_template. And loop-frontpage.php is a file, a template part that I'm calling, and you can see that that's got a hyphen and not an underscore. 

On the other hand, my post type ID, which is a custom post type I've registered, uses an underscore: rmcc_blurb

Now you also might need to think about variables within your theme. Let's look at loop-frontpage.php:

loop-frontpagephp file

Within this particular file, which is the one I was calling from that previous file, I've defined some variables, one called count and one called title. And you can see that I'm using lower case for both of those. 

The other place where you need to think about underscores and capitalization is when you're using a class. Let's go back to front-page.php:

the  front-pagephp file

And you can see here, I'm using the WP_Query class. So a class has a capital letter after the underscore, as well as at the beginning. So that's where you use capitalization when you're defining a class. It helps people working with your code instantly identify that it's a class and not a function.

Using Single and Double Quotes

Now let's have a look at how you would use single and double quotes in PHP for WordPress. 

You can use either single quotes or double quotes, depending on which works best for the specific code that you're working with.

The reason that double quotes can sometimes be more helpful is that they make it easier to work with special characters. Here's an example:

how to use single and double quotes in WordPress

Say you were writing a search template file, search.php. And within that, if nothing was found, you would put a paragraph that says, "I'm sorry, your search didn't find anything. Why don't you try again?"

I've put that within double quotes because the text contains apostrophes. Let me show you how that would work if we did it in single quotes. 

Example of single and double quotes

You need to put a backslash before the apostrophes in order for them to be output correctly within the HTML—otherwise, it'll give you errors. Now I don't know about you, but I'd rather just type it normally within double quotes than do all this within single quotes.

The other thing you need to remember is that if you need to put quotes within quotes, you either put single quotes within double quotes, or vice versa. It doesn't matter which way around, but you can't put single quotes within single quotes or double quotes within double quotes.

So here's an example going back to my functions.php file. 

Example of single and double quotes in PHP

Within here I've got single quotes for the value of before_widget, and then within that, I've got double quotes for the ID and the class of that. I couldn't use double quotes here and then put double quotes inside it, so that's why I'm using single quotes there, because it's better to use double quotes with your CSS. 

Indentation

Now, let's look at indentation. And let's continue looking at the functions.php file, which is quite a good example because I've indented a number of lines of code within it. 

You can see that the function name is on the left, and then within that the register_sidebar function is indented at one level. And the contents of that are indented again. 

So each time you're putting content within braces or curly braces, everything inside that should be indented. And also for indentation, you should use line breaks. 

So let's take a look at another file where there are single lines as well as double lines. 

Line breaks with a block of PHP

So here you can see I've got an if statement that's got two lines of code within it. So I've put a line break above and below those two lines of code.

If there was only one line of code within that, I wouldn't have to put those line spaces in—I would just put that straight inside my braces. 

Using spacing like this helps make it clear where your blocks of code are. And you can see also that indentation has been used. So there are multiple layers of indentation. 

The other thing you need to bear in mind is where you open and close your PHP tag and whether that is on the same line as your code or a different line. And that also depends on whether you're coding a block of code or a single line.

Where you've got a block of code, you put your opening tag on one line and your closing tag on another line. That helps to make it obvious that it's a block of PHP and that everything within those tags is PHP.

The other thing you have to make sure you do is use a full opening PHP tag. So don't just use a question mark, as you might have done in some other systems that use PHP, because in WordPress you have to use the full PHP tag. 

If I wrote some PHP that was just on one line, I would put the PHP opening and closing tags on the same line.

PHP opening and closing tags on the same line

You can see that we've got some PHP that's all in one line, and then after that I've got HTML. So the opening and closing tags go on the same line as my code. 

Conclusion

That's an introduction to some of the elements of the WordPress PHP coding standards, and I've shown you some examples of them in my files and changed some as I've gone along to show you how things are done correctly. 

If you want to know more about the coding standards, there's documentation on the WordPress website. And you can also check out this Envato Tuts+ series, which goes into all of the elements of the coding standards in detail.

Watch the Full Course

In the full course, Learn PHP for WordPress, you'll learn all about PHP, the programming language that WordPress is built in.  

I'll give you an overview of what PHP is and how it's used for WordPress themes and plugins, with examples. You'll go on to learn how to create a PHP file and use it to output HTML. Then you'll learn to use functions, loops and if statements for coding custom WordPress themes and plugins.

You can take this course straight away with a subscription to Envato Elements. For a single low monthly fee, you get access not only to this course, but also to our growing library of over 1,000 video courses and industry-leading eBooks on Envato Tuts+. 

Plus you now get unlimited downloads from the huge Envato Elements library of 580,000+ creative assets. Create with unique fonts, photos, graphics and templates, and deliver better projects faster.

10:00

Creating The Feature Queries Manager DevTools Extension

Creating The Feature Queries Manager DevTools Extension

Creating The Feature Queries Manager DevTools Extension

Ire Aderinokun
2018-05-23T12:00:00+02:002018-05-23T13:42:58+00:00

Within the past couple of years, several game-changing CSS features have been rolled out to the major browsers. CSS Grid Layout, for example, went from 0 to 80% global support within the span of a few months, making it an incredibly useful and reliable tool in our arsenal. Even though the current support for a feature like CSS Grid Layout is relatively great, not all recent or current browsers support it. This means it’s very likely that you and I will currently be developing for a browser in which it is not supported.

The modern solution to developing for both modern and legacy browsers is feature queries. They allow us to write CSS that is conditional on browser support for a particular feature. Although working with feature queries is almost magical, testing them can be a pain. Unlike media queries, we can’t easily simulate the different states by just resizing the browser. That’s where the Feature Queries Manager comes in, an extension to DevTools to help you easily toggle your feature query conditions. In this article, I will cover how I built this extension, as well as give an introduction to how developer tools extensions are built.

Working With Unsupported CSS

If a property-value pair (e.g. display: grid), is not supported by the browser the page is viewed in, not much happens. Unlike other programming languages, if something is broken or unsupported in CSS, it only affects the broken or unsupported rule, leaving everything else around it intact.

Getting the process just right ain't an easy task. That's why we've set up 'this-is-how-I-work'-sessions — with smart cookies sharing what works really well for them. A part of the Smashing Membership, of course.

Explore features →

Let’s take, for example, this simple layout:

The layout in a supporting browserLarge preview

We have a header spanning across the top of the page, a main section directly below that to the left, a sidebar to the right, and a footer spanning across the bottom of the page.

Here’s how we could create this layout using CSS Grid:

See the Pen layout-grid by Ire Aderinokun (@ire) on CodePen.

In a supporting browser like Chrome, this works just as we want. But if we were to view this same page in a browser that doesn’t support CSS Grid Layout, this is what we would get:

The layout in an unsupporting browser Large preview

It is essentially the same as if we had not applied any of the grid-related styles in the first place. This behavior of CSS was always intentional. In the CSS specification, it says:

In some cases, user agents must ignore part of an illegal style sheet, [which means to act] as if it had not been there

Historically, the best way to handle this has been to make use of the cascading nature of CSS. According to the specification, “the last declaration in document order wins.” This means that if there are multiple of the same property being defined within a single declaration block, the latter prevails.

For example, if we have the follow declarations:

body {
  display: flex;
  display: grid;
}

Assuming both Flexbox and Grid are supported in the browser, the latter — display: grid — will prevail. But if Grid is not supported by the browser, then that rule is ignored, and any previous valid and supported rules, in this case display: flex, are used instead.

body {
  display: flex;
  display: grid;
}

Cascading Problems

Using the cascade as a method for progressive enhancement is and has always been incredibly useful. Even today, there is no simpler or better way to handle simple one-liner fallbacks, such as this one for applying a solid colour where the rgba() syntax is not supported.

div {
    background-color: rgb(0,0,0);
    background-color: rgba(0,0,0,0.5);
}

Using the cascade, however, has one major limitation, which comes into play when we have multiple, dependent CSS rules. Let’s again take the layout example. If we were to attempt to use this cascade technique to create a fallback, we would end up with competing CSS rules.

See the Pen layout-both by Ire Aderinokun (@ire) on CodePen.

In the fallback solution, we need to use certain properties such as margins and widths, that aren’t needed and in fact interfere with the “enhanced” Grid version. This makes it difficult to rely on the cascade for more complex progressive enhancement.

Feature Queries To The Rescue!

Feature queries solve the problem of needing to apply groups of styles that are dependent on the support of a CSS feature. Feature queries are a “nested at-rule” which, like the media queries we are used to, allow us to create a subset of CSS declarations that are applied based on a condition. Unlike media queries, whose condition is dependent on device and screen specs, feature query conditions are instead based on if the browser supports a given property-value pair.

A feature query is made up of three parts:

  1. The @supports keyword
  2. The condition, e.g. display: flex
  3. The nested CSS declarations.

Here is how it looks:

@supports (display: grid) {
    body { display: grid; }
}

If the browser supports display: grid, then the nested styles will apply. If the browser does not support display: grid, then the block is skipped over entirely.

The above is an example of a positive condition within a feature query, but there are four flavors of feature queries:

  1. Positive condition, e.g. @supports (display grid)

  2. Negative condition, e.g. @supports not (display: grid)

  3. Conjunction, e.g. @supports (display:flex) and (display: grid)

  4. Disjunction, e.g. @supports (display:-ms-grid) or (display: grid)

Feature queries solve the problem of having separate fallback and enhancement groups of styles. Let’s see how we can apply this to our example layout:

See the Pen Run bunny run by Ire Aderinokun (@ire) on CodePen.

Introducing The Feature Queries Manager

When we write media queries, we test them by resizing our browser so that the styles at each breakpoint apply. So how do we test feature queries?

Since feature queries are dependent on whether a browser supports a feature, there is no easy way to simulate the alternative state. Currently, the only way to do this would be to edit your code to invalidate/reverse the feature query.

For example, if we wanted to simulate a state in which CSS Grid is not supported, we would have to do something like this:

/* fallback styles here */

@supports (display: grrrrrrrrid) {
    /* enhancement styles here */
}

This is where the Feature Queries Manager comes in. It is a way to reverse your feature queries without ever having to manually edit your code.

(Large preview)

It works by simply negating the feature query as it is written. So the following feature query:

@supports (display: grid) {
    body { display: grid; }
}

Will become the following:

@supports not (display: grid) {
    body { display: grid; }
}

Fun fact, this method works for negative feature queries as well. For example, the following negative feature query:

@supports not (display: grid) {
    body { display: block; }
}

Will become the following:

@supports not (not (display: grid)) {
    body { display: block; }
}

Which is actually essentially the same as removing the “not” from the feature query.

@supports (display: grid) {
    body { display: block; }
}

Building The Feature Queries Manager

FQM is an extension to your browser’s Developer Tools. It works by registering all the CSS on a page, filtering out the CSS that is nested within a feature query, and giving us the ability to toggle the normal or “inverted” version of that feature query.

Creating A DevTools Panel

Before I go on to how I specifically built the FQM, let’s cover how to create a new DevTools panel in the first place. Like any other browser extension, we register a DevTools extension with the manifest file.

{
  "manifest_version": 2,
  "name": "Feature Queries Manager",
  "short_name": "FQM",
  "description": "Manage and toggle CSS on a page behind a @supports Feature Query.",
  "version": "0.1",
  "permissions": [
    "tabs",
    "activeTab",
    "<all_urls>"
  ],
  "icons": {
    "128": "images/icon@128.png",
    "64": "images/icon@64.png",
    "16": "images/icon@16.png",
    "48": "images/icon@48.png"
  }
}

To create a new panel in DevTools, we need two files — a devtools_page, which is an HTML page with an attached script that registers the second file, panel.html, which controls the actual panel in DevTools.

The devtools script creates the panel pageLarge preview

First, we add the devtools_page to our manifest file:

{
  "manifest_version": 2,
  "name": "Feature Queries Manager",
  ...
  "devtools_page": "devtools.html",
}

Then, in our devtools.html file, we create a new panel in DevTools:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8"></head>
<body>
<!-- Note: I’m using the browser-polyfill to be able to use the Promise-based WebExtension API in Chrome -->
<script src="../browser-polyfill.js"></script>

<!-- Create FQM panel -->
<script>
browser.devtools.panels.create("FQM", "images/icon@64.png", "panel.html");
</script>
</body>
</html

Finally, we create our panel HTML page:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8"></head>
<body>
  <h1>Hello, world!</h1>
</body>
</html>

If we open up our browser, we will see a new panel called “FQM” which loads the panel.html page.

A new panel in browser DevTools showing the “Hello, World” textLarge preview

Is your pattern library up to date today? Alla Kholmatova has just finished a fully fledged book on Design Systems and how to get them right. With common traps, gotchas and the lessons she learned. Hardcover, eBook. Just sayin'.

Table of Contents →

Reading CSS From The Inspected Page

In the FQM, we need to access all the CSS referenced in the inspected document in order to know which are within feature queries. However, our DevTools panel doesn’t have direct access to anything on the page. If we want access to the inspected document, we need a content script.

The content script reads CSS from the HTML documentLarge preview

A content script is a javascript file that has the same access to the html page as any other piece of javascript embedded within it. To register a content script, we just add it to our manifest file:

{
      "manifest_version": 2,
      "name": "Feature Queries Manager",
      ...
      "content_scripts": [{
        "matches": [""],
        "js": ["browser-polyfill.js", "content.js"]
      }],
    }

In our content script, we can then read all the stylesheets and css within them by accessing document.styleSheets:

Array.from(document.styleSheets).forEach((stylesheet) => {
      let cssRules;
      
      try {
        cssRules = Array.from(stylesheet.cssRules);
      } catch(err) {
        return console.warn(`[FQM] Can't read cssRules from stylesheet: ${ stylesheet.href }`);
      }
      
      cssRules.forEach((rule, i) => {
      
        /* Check if css rule is a Feature Query */
        if (rule instanceof CSSSupportsRule) {
          /* do something with the css rule */
        }
        
      });
    });

Connecting The Panel And The Content Scripts

Once we have the rules from the content script, we want to send them over to the panel so they can be visible there. Ideally, we would want something like this:

The content script passes information to the panel and the panel sends instructions to modify CSS back to the contentLarge preview

However, we can’t exactly do this, because the panel and content files can’t actually talk directly to each other. To pass information between these two files, we need a middleman — a background script. The resulting connection looks something like this:

The content and panel scripts communicate via a background scriptLarge preview

As always, to register a background script, we need to add it to our manifest file:

{
  "manifest_version": 2,
  "name": "Feature Queries Manager",
  ...
  "background": {
    "scripts": ["browser-polyfill.js", "background.js"]
  },
}

The background file will need to open up a connection to the panel script and listens for messages coming from there. When the background file receives a message from the panel, it passes it on to the content script, which is listening for messages from the background. The background script waits for a response from the content script and relays that message back to the panel.

Here’s a basic of example of how that works:

// Open up a connection to the background script
const portToBackgroundScript = browser.runtime.connect();

// Send message to content (via background)
portToBackgroundScript.postMessage("Hello from panel!");

// Listen for messages from content (via background)
portToBackgroundScript.onMessage.addListener((msg) => {
  console.log(msg);
  // => "Hello from content!"
});
// backrgound.js

// Open up a connection to the panel script
browser.runtime.onConnect.addListener((port) => {
  
  // Listen for messages from panel
  port.onMessage.addListener((request) => {
  
    // Send message from panel.js -> content.js
    // and return response from content.js -> panel.js
    browser.tabs.sendMessage(request.tabId, request)
      .then((res) => port.postMessage(res));
  });
});
// content.js

// Listen for messages from background
browser.runtime.onMessage.addListener((msg) => {

  console.log(msg)
  // => "Hello from panel!"
  
  // Send message to panel
  return Promise.resolve("Hello from content!");
});

Managing Feature Queries

Lastly, we can get to the core of what the extension does, which is to “toggle” on/off the CSS related to a feature query.

If you recall, in the content script, we looped through all the CSS within feature queries. When we do this, we also need to save certain information about the CSS rule:

  1. The rule itself
  2. The stylesheet it belongs to
  3. The index of the rule within the stylesheet
  4. An “inverted” version of the rule.

This is what that looks like:

cssRules.forEach((rule, i) => {
  
  const cssRule = rule.cssText.substring(rule.cssText.indexOf("{"));
  const invertedCSSText = `@supports not ( ${ rule.conditionText } ) ${ cssRule }`;
  
  FEATURE_QUERY_DECLARATIONS.push({ 
    rule: rule,
    stylesheet: stylesheet,
    index: i, 
    invertedCSSText: invertedCSSText
  });
  
});

When the content script receives a message from the panel to invert all declarations relating to the feature query condition, we can easily replace the current rule with the inverted one (or vice versa).

function toggleCondition(condition, toggleOn) {
  FEATURE_QUERY_DECLARATIONS.forEach((declaration) => {
    if (declaration.rule.conditionText === condition) {
      
      // Remove current rule
      declaration.stylesheet.deleteRule(declaration.index);
      
      // Replace at index with either original or inverted declaration
      const rule = toggleOn ? declaration.rule.cssText : declaration.invertedCSSText;
      declaration.stylesheet.insertRule(rule, declaration.index);
    }    
  });
}

And that is essentially it! The Feature Query Manager extension is currently available for Chrome and Firefox.

Limitations Of The FQM

The Feature Queries Manager works by “inverting” your feature queries, so that the opposite condition applies. This means that it cannot be used in every scenario.

Fallbacks

If your “enhancement” CSS is not written within a feature query, then the extension cannot be used as it is dependent on finding a CSS supports rule.

Unsupported Features

You need to take note of if the browser you are using the FQM in does or does not support the feature in question. This is particularly important if your original feature query is a negative condition, as inverting it will turn it into a positive condition. For example, if you wrote the following CSS:

div { background-color: blue; }

@supports not (display: grid) {
  div { background-color: pink; }
}

If you use the FQM to invert this condition, it will become the following:

div { background-color: blue; }

@supports (display: grid) {
  div { background-color: pink; }
}

For you to be able to actually see the difference, you would need to be using a browser which does in fact support display: grid.

I built the Feature Queries Manager as a way to more easily test the different CSS as I develop, but it isn’t a replacement for testing layout in the actual browsers and devices. Developer tools only go so far, nothing beats real device testing.

Smashing Editorial(ra, yk, il)
Older posts are this way If this message doesn't go away, click anywhere on the page to continue loading posts.
Could not load more posts
Maybe Soup is currently being updated? I'll try again automatically in a few seconds...
Just a second, loading more posts...
You've reached the end.

Don't be the product, buy the product!

Schweinderl