This site is dedicated to all things I see and that I think are interesting to publish almost always are other very smart people.

CSS

A Guide to Custom Elements for React Developers

CSS-Tricks by Charles Peters

I had to build a UI recently and (for the first time in a long while) I didn’t have the option of using React.js, which is my preferred solution for UI these days. So, I looked at what the built-in browser APIs had to offer and saw that using custom elements (aka Web Components) may just be the remedy that this React developer needed.

Custom elements can offer the same general benefits of React components without being tied to a specific framework implementation. A custom element gives us a new HTML tag that we can programmatically control through a native browser API.

Let’s talk about the benefits of component-based UI:

  • Encapsulation – concerns scoped to that component remain in that component’s implementation
  • Reusability – when the UI is separated into more generic pieces, they’re easier to break into patterns that you’re more likely to repeat
  • Isolation – because components are designed to be encapsulated and with that, you get the added benefit of isolation, which allows you scope bugs and changes to a particular part of your application easier

Use cases

You might be wondering who is using custom elements in production. Notably:

  • GitHub is using custom elements for their modal dialogs, autocomplete and display time.
  • YouTube’s new web app is built with Polymer and web components.

Similarities to the Component API

When trying to compare React Components versus custom elements, I found the APIs really similar:

  • They’re both classes that aren’t “new” and are able that extend a base class
  • They both inherit a mounting or rendering lifecycle
  • They both take static or dynamic input via props or attributes

Demo

So, let’s build a tiny application that lists details about a GitHub repository.

If I were going to approach this with React, I would define a simple component like this:

<Repository name="charliewilco/obsidian" />

This component takes a single prop — the name of the repository — and we implement it like this:

class Repository extends React.Component {
  state = {
    repo: null
  };

  async getDetails(name) {
    return await fetch(`https://api.github.com/repos/${name}`, {
      mode: 'cors'
    }).then(res => res.json());
  }

  async componentDidMount() {
    const { name } = this.props;
    const repo = await this.getDetails(name);
    this.setState({ repo });
  }

  render() {
    const { repo } = this.state;

    if (!repo) {
      return <h1>Loading</h1>;
    }

    if (repo.message) {
      return 
Error: {repo.message}
; } return (

{repo.full_name}

{repo.description}
); } }

See the Pen React Demo – GitHub by Charles (@charliewilco) on CodePen.

To break this down further, we have a component that has its own state, which is the repo details. Initially, we set it to be null because we don’t have any of that data yet, so we’ll have a loading indicator while the data is fetched.

During the React lifecycle, we’ll use fetch to go get the data from GitHub, set up the card, and trigger a re-render with setState() after we get the data back. All of these different states the UI takes are represented in the render() method.

Defining / Using a Custom Element

Doing this with custom elements is a little different. Like the React component, our custom element will take a single attribute — again, the name of the repository — and manage its own state.

Our element will look like this:

<github-repo name="charliewilco/obsidian"></github-repo>
<github-repo name="charliewilco/level.css"></github-repo>
<github-repo name="charliewilco/react-branches"></github-repo>
<github-repo name="charliewilco/react-gluejar"></github-repo>
<github-repo name="charliewilco/dotfiles"></github-repo>

See the Pen Custom Elements Demo – GitHub by Charles (@charliewilco) on CodePen.

To start, all we need to do to define and register a custom element is create a class that extends the HTMLElement class and then register the name of the element with customElements.define().

class OurCustomElement extends HTMLElement {}
window.customElements.define('our-element', OurCustomElement);

And we can call it:

<our-element></our-element>

This new element isn’t very useful, but with custom elements, we get three methods to expand the functionality of this element. These are almost analogous to React’s lifecycle methods for their Component API. The two lifecycle-like methods most relevant to us are the disconnectedCallBack and the connectedCallback and since this is a class, it comes with a constructor.

Name Called when
constructor An instance of the element is created or upgraded. Useful for initializing state, settings up event listeners, or creating Shadow DOM. See the spec for restrictions on what you can do in the constructor.
connectedCallback The element is inserted into the DOM. Useful for running setup code, such as fetching resources or rendering UI. Generally, you should try to delay work until this time
disconnectedCallback When the element is removed from the DOM. Useful for running clean-up code.

To implement our custom element, we’ll create the class and set up some attributes related to that UI:

class Repository extends HTMLElement {
  constructor() {
    super();

    this.repoDetails = null;

    this.name = this.getAttribute("name");
    this.endpoint = `https://api.github.com/repos/${this.name}`    
    this.innerHTML = `<h1>Loading</h1>`
  }
}

By calling super() in our constructor, the context of this is the element itself and all the DOM manipulation APIs can be used. So far, we’ve set the default repository details to null, gotten the repo name from element’s attribute, created an endpoint to call so we don’t have to define it later and, most importantly, set the initial HTML to be a loading indicator.

In order to get the details about that element’s repository, we’re going to need to make a request to GitHub’s API. We’ll use fetch and, since that’s Promise-based, we’ll use async and await to make our code more readable. You can learn more about the async/await keywords here and more about the browser’s fetch API here. You can also tweet at me to find out whether I prefer it to the Axios library. (Hint, it depends if I had tea or coffee with my breakfast.)

Now, let’s add a method to this class to ask GitHub for details about the repository.

class Repository extends HTMLElement {
  constructor() {
    // ...
  }

  async getDetails() {
    return await fetch(this.endpoint, { mode: "cors" }).then(res => res.json());
  }
}

Next, let’s use the connectedCallback method and the Shadow DOM to use the return value from this method. Using this method will do something similar as when we called Repository.componentDidMount() in the React example. Instead, we’ll override the null value we initially gave this.repoDetails — we’ll use this later when we start to call the template to create the HTML.

class Repository extends HTMLElement {
  constructor() {
    // ...
  }

  async getDetails() {
    // ...
  }

  async connectedCallback() {
    let repo = await this.getDetails();
    this.repoDetails = repo;
    this.initShadowDOM();
  }

  initShadowDOM() {
    let shadowRoot = this.attachShadow({ mode: "open" });
    shadowRoot.innerHTML = this.template;
  }
}

You’ll notice that we’re calling methods related to the Shadow DOM. Besides being a rejected title for a Marvel movie, the Shadow DOM has its own rich API worth looking into. For our purposes, though, it’s going to abstract the implementation of adding innerHTML to the element.

Now we’re assigning the innerHTML to be equal to the value of this.template. Let’s define that now:

class Repository extends HTMLElement {
  get template() {
    const repo = this.repoDetails;
  
    // if we get an error message let's show that back to the user
    if (repo.message) {
      return `
Error: ${repo.message}
` } else { return `

${repo.full_name}

${repo.description}
` } } }

That’s pretty much it. We’ve defined a custom element that manages its own state, fetches its own data, and reflects that state back to the user while giving us an HTML element to use in our application.

After going through this exercise, I found that the only required dependency for custom elements is the browser’s native APIs rather than a framework to additionally parse and execute. This makes for a more portable and reusable solution with similar APIs to the frameworks you already love and use to make your living.

There are drawbacks of using this approach, of course. We’re talking about various browser support issues and some lack of consistency. Plus, working with DOM manipulation APIs can be very confusing. Sometimes they are assignments. Sometimes they are functions. Sometimes those functions take a callback and sometimes they don’t. If you don’t believe me, take a look at adding a class to an HTML element created via document.createElement(), which is one of the top five reasons to use React. The basic implementation isn’t that complicated but it is inconsistent with other similar document methods.

The real question is: does it even out in the wash? Maybe. React is still pretty good at the things it’s designed to be very very good at: the virtual DOM, managing application state, encapsulation, and passing data down the tree. There’s next to no incentive to use custom elements inside that framework. Custom elements, on the other hand, are simply available by virtue of building an application for the browser.

Learn more

The post A Guide to Custom Elements for React Developers appeared first on CSS-Tricks.


Poly Fluid Sizing

Jake Wilson digs in, and while he finds that calc() isn’t quite up for the job (e.g. font-size: calc(3vw * 3vw); /* This doesn't work in CSS */), he does land on a technique he’s calling Poly Fluid Sizing, which takes a map of breakpoints and font sizes and linear interpolates them just about as good (*it depends*).

Direct Link to ArticlePermalink

Poly Fluid Sizing is a post from CSS-Tricks


Sass for Web Designers review

I had this little book by Dan Cederholmlaying around for quite some time. I’ve bought it as a reference for when I would try to get my head around Sass. Now I finally managed to write the review. Let’s get right into it.
Sass for Web Designers book

Table of contents

I’ve hesitated to start with Sass. This book was written to help with that: an informative, concise introduction to all things Sass. Honestly, I think Sass needs a getting started guide for a designer anyway.

Foreword

The foreword in Dan’s book is written by a person that knows a thing or two about CSS, and runs a hugely valuable web site called CSS Tricks. If you’ve ever googled something CSS related, Chris Coyier will most likely be high up there in the search results. Chris says “By the time you finish this book and give Sass a real try on your first project, you’ll be a master of 95% of the important, truly value-adding parts of Sass”

  • Chapter 1: Why Sass
  • Chapter 2: Sass Workflow
  • Chapter 3: Using Sass
  • Chapter 4: Sass and Media Queries

Chapter 1: Why Sass

In this first part Dan tells the story of how he was reluctant to start with Sass as he writes his stylesheets by hand. It took him a while to come around. In this chapter Dan explains what Sass is and he also goes into the misconceptions about Sass.

Chapter 2: Sass Workflow

In chapter two it is time to get your hands dirty and start using it. When you are on a Mac it’s relatively easy to get started but there still is a need to fire up Terminal. Dan also shows all the necessary commands. I’m not scared of using Terminal, but if I can avoid messing around with my system I opt for that and use a tool instead. My tool of choice is CodeKit. Luckily Dan also sums up all others as well. There are plenty of options at your disposal. The last part in this chapter deals with choosing your output.

Chapter 3: Using Sass

Chapter three is where the real adventure starts. You’ll use a fictional project (Sasquatch Records) as an example to get your head around the most valuable and easiest to add core Sass features such as nesting rules, referencing parent selectors, variables, mixins, extends and content blocks. Here Dan takes the time to explain each part in an understandable manner, step by step. If you’re done with this section you’ve got the basics of Sass covered.

Chapter 4 Sass and Media Queries

The final chapter takes things a serious step further. This section is where I needed to re-read things a few times to get my head around it. Dan explains some useful techniques for simplifying the use of media queries. You’ll learn how to nest media queries, using variables to define breakpoints and how to‘Retinize’ your HiDPI background images. The book ends with a valuable and useful resource section with links to the most useful Sass tutorials, mixin libraries, apps and frameworks.

Conclusion

Just like Dan I was reluctant to start with Sass as I mentioned earlier. When I first dangled my feet into this world of preprocessors I’ve used Compass, but now I’ve switched to pure Sass as it kinda feels like the world has moved on and Compass isn’t getting any updates anymore. This book was a great companion and reference to see if I did things correctly. If you’ve been writing , CSS the traditional way like I’ve done for many years, Sass feels like a radical change. When something radical takes place you need help and Dan’s approach is wonderful just like in his other books, Bulletproof CSS, Handcrafted CSS, andCSS3 for Web Designers. Dan takes the time to explain his examples thoroughly so you fully understand what’s going on. For me such a thorough instruction was needed to grasp how things work. I would recommend it if you are still doubting about Sass. Dan’s guidance is a reassuring way to get started with the important concepts. There’s much more to learn, but when you’re done with this book you’re off to a great start. You can buy the book over at A Book Apart.


Scroll Drawing

We’ve taken an in-depth look at how SVG line drawing works before. It’s a clever trick where you use dashed lines for the stroke, but the gap in the dash is so long it covers the entire path. Then you can move it such that it covers the entire path again, which makes it appear as if it’s drawing itself.

Using a bit of JavaScript, we can get a little fancier, drawing the shape to completion as page is scrolled to the bottom.

Demo

See the Pen Scroll Drawing by Chris Coyier (@chriscoyier) on CodePen.

Step 1: Get a <path>

It has to be a <path>. Any other kind of SVG element won’t work (e.g. <rect>). You can force elements to be paths though. I have a Lodge video on this. You may need to resort to trickery like adding an additional vector point along an already straight edge.

In my demo here, I just copy-and-pasted the shape right out of Illustrator.

Give the path an ID if it doesn’t have one:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100.6 107.6" id="star-svg">
  <path id="star-path" fill="none" stroke="black" stroke-width="2"  d=" ... " />
</svg>

Step 2: Find length of that path

// Get a reference to the <path>
var path = document.querySelector('#star-path');

// Get length of path... ~577px in this demo
var pathLength = path.getTotalLength();

Step 3: Hide shape by offsetting dash

// Make very long dashes (the length of the path itself)
path.style.strokeDasharray = pathLength + ' ' + pathLength;

// Offset the dashes so the it appears hidden entirely
path.style.strokeDashoffset = pathLength;

Step 4: When page scrolls, offset dash same amount as % scrolled

// When the page scrolls...
window.addEventListener("scroll", function(e) {
 
  // What % down is it? 
  var scrollPercentage = (document.documentElement.scrollTop + document.body.scrollTop) / (document.documentElement.scrollHeight - document.documentElement.clientHeight);
    
  // Length to offset the dashes
  var drawLength = pathLength * scrollPercentage;
  
  // Draw in reverse
  path.style.strokeDashoffset = pathLength - drawLength;
  
});

Step 5: If scrolled to bottom, remove dashing

If you don’t do this, the shape doesn’t look quite as neatly/sharply finished as if you didn’t applying any dashing at all.

I’m not sure why. I don’t think you can fiddle with the numbers to fix it. But it’s easy enough to remove.

  // ... at bottom of scrolling function

  // When complete, remove the dash array, otherwise shape isn't quite sharp
  if (scrollPercentage >= 0.99) {
    path.style.strokeDasharray = "none";
  } else {
    path.style.strokeDasharray = pathLength + ' ' + pathLength;
  }

The 0.99 is to account for fuzzy math. Sometimes you don’t get a perfect 1.0 from the division.

See a full page demo.

Scroll Drawing is a post from CSS-Tricks


Spriting with

Sprites aren’t limited to background-image, as with the object-fit and object-positionproperties we can nudge an inline image around its content-box to act just like a sprite. For example, let’s say we want the image below to be added to our HTML page like a regular ol’ image:

Sprite
<img src='sprite.png' alt='Icons'> 

Then we’ll crop the image so that only the first icon is visible on screen:

img {
  object-fit: none;
  object-position: 0 0;
  width: 100px;
  height: 100px;
}
Sprite image cropped to reveal the world icon

Here, the content-box of the <img> should be 100px wide and 100px tall, but because the image extends beyond those boundaries, it’s automatically cropped for us with object-fit: none. We might then want to use a class to nudge the image and reveal another part of it altogether:

.book {
  object-position: 0 -234px;
}
Sprite cropped to reveal the book icon

These sprites can be in any regular image format but it’s also possible to use the same technique with SVG. Here’s an example that currently works in the latest stable version of Chrome:

See the Pen Sprites with object-position by Robin Rendle (@robinrendle) on CodePen.

Image Slider

Using a dab of JavaScript, we can actually use this same concept to create an image slider out of a single <img> tag. When the image is clicked, just change some classes which change the object-position.

See the Pen SVG sprite with object-position by Robin Rendle (@robinrendle) on CodePen.

Support

Keep this in mind for the future, since unfortunately the browser support for object-fitisn’t particularly great at the moment. The current desktop versions of Safari and Firefox don’t support it and neither does iOS. So make sure to double check the almanac entry forobject-fit before using this trick anytime soon.

Spriting with <img> is a post from CSS-Tricks


Simple CSS-Only Row and Column Highlighting

Highlighting rows of a table is pretty darn easy in CSS. tr:hover { background: yellow; } does well there. But highlighting columns has always been a little trickier, because there is no single HTML element that is parent to table cells in a column. A dash of JavaScript can handle it easily, but Andrew Howe recently emailed me to share a little trick he found on StackOverflow, posted by Matt Walton.

It was a few years old, so I thought I’d just clean it up and post it here.

The trick is using huge pseudo elements on the <td>s, hidden by the table overflow

You don’t really know how big the table is from CSS, so just make the pseudo elements super tall with a negative top value of half of that.

table {
  overflow: hidden;
}

tr:hover {
  background-color: #ffa;
}

td:hover::after,
th:hover::after {
  content: "";
  position: absolute;
  background-color: #ffa;
  left: 0;
  top: -5000px;
  height: 10000px;
  width: 100%;
  z-index: -1;
}

The negative z-index keeps it below the content. Negative z-index is a fun trick, but beware this table then can’t be nested within other elements with backgrounds, otherwise the highlight will go below them.

You can see that in action here:

See the Pen Row and Column Highlighting with CSS Only by Chris Coyier (@chriscoyier) onCodePen.

Making it work with touch

Hover pseudo classes only kinda work on touch devices. First, the element needs to be focusable, which table cells are not by default. You could certainly add a click event handler to the table cells and just do everything in JavaScript, but here’s a method to keep most of the work in CSS:

// Whatever kind of mobile test you wanna do.
if (screen.width < 500) {
  
  // :hover will trigger also once the cells are focusable
  // you can use this class to separate things
  $("body").addClass("nohover");

  // Make all the cells focusable
  $("td, th")
    .attr("tabindex", "1")
    // When they are tapped, focus them
    .on("touchstart", function() {
      $(this).focus();
    });
  
}

Then in the CSS you add :focus styles as well.

td:focus::after,
th:focus::after { 
  content: '';  
  background-color: lightblue;
  position: absolute;  
  left: 0;
  height: 10000px;
  top: -5000px;
  width: 100%;
  z-index: -1;
}

td:focus::before {
  background-color: lightblue;
  content: '';  
  height: 100%;
  top: 0;
  left: -5000px;
  position: absolute;  
  width: 10000px;
  z-index: -1;
}

In my final demo, I got a little fancier with the CSS selectors ensuring that empty table cells didn’t trigger anything, table headers in the <thead> only selected columns, and table headers in the <tbody> only selected rows.

You can see that in the final demo. And here’s touch working:

Simple CSS-Only Row and Column Highlighting is a post from CSS-Tricks


How to Roll Your Own Simple WordPress Podcast Plugin

The following is a guest post by Geoff Graham. Geoff told me: “I love WordPress plugins but sometimes feel we rely on them without really understanding what they do.” Ain’t that true? Here, he walks us through how you might build this functionality yourself into WordPress. This might be just the ticket for those of you who resolved to start a podcast in 2015!

Let’s say you plan to get into podcasting. You have the recording equipment, an interesting topic, and a good voice that other people want to hear. You seem well on your way to filling earbuds everywhere.

Then there’s the issue of hosting your podcast. iTunes requires an RSS feed so it can distribute your episodes to subscribers when they’re available, but how do you do that? The good news is that there are plenty of ways to host a podcast. For example, you could use a hosting service that provides you storage and distribution in one tidy place, usually for a fee. If you use WordPress and have looked into podcasting, you may have seen all the powerful podcasting plugins that are available there as well.

We’re going to skip over those options in this post and see how we can host our own podcast using nothing more than a WordPress site and two additional files. Specifically, we’re going to:

  • Set up a new plugin
  • Register a custom RSS feed
  • Make a custom post type for our podcast
  • Assign custom fields to our custom post type
  • Create the template for our RSS feed

The goal is not to overthink this too much. If you already have a WordPress site and all you need is a feed to submit to iTunes, then that’s exactly what we’re going to do. Let’s rock ‘n’ roll.

Setting Up the Plugin

Creating a plugin is a nice alternative to writing code in your theme’s `functions.php` file. In addition to keeping your theme’s functions clean and clutter-free, it keeps the podcast feed functionality in your `/wp-content/plugins/` directory which stays with you even if you change themes.

Create the Plugin Directory

First things first. Let’s create a new folder called `my-awesome-podcast` in our `/wp-content/plugins/` directory.

Create the Plugin

Now let’s make a new PHP file in the folder we just created and call it `my-awesome-podcast.php`. This will be the primary file that registers our plugin and where we write the functionality for our podcast.

With that file in place, we will add the following code comments that tell WordPress the name, description and version of the plugin. There are other bits of information we can add, but this will do.

/**
Plugin Name: My Awesome Podcast
Description: A really simple RSS feed and custom post type for a podcast
Version: 1.0
**/

// This is where we will start writing our plugin

Register the RSS Feed

Next up, we need to register a new RSS feed. Thankfully, the WordPress API has a handyadd_feed() function that we can hook into to make this relatively easy.

add_action('init', 'podcast_rss');
function podcast_rss(){
  add_feed('my-awesome-podcast', 'my_podcast_rss');
}

What’s happening here is we’ve defined a new function called podcast_rss() and are extending the WordPress add_feed() function to create a new RSS feed called “my_podcast_rss” that will live at `/feed/my-awesome-podcast` on our site.

Note: You can change “my-awesome-podcast” here to anything you want. This the URL slug of your feed, so it could be the title of your podcast or whatever else you fancy.

Register a Podcast Custom Post Type

Once we have our feed established, we’ll need to set up a new post type that we can use to publish the posts for our episodes. So instead of a “Post” or “Page” that are default to WordPress, we’ll create a brand new one called “Podcast”. The WordPress Codex does a good job of explaining how to create custom post types, so there’s no need to rehash that here. There are even a handful of plugins that will do this, if that’s how you prefer to roll. In any case, let’s assume we’re doing it without the help of a plugin and make the Podcast custom post type here in our file.

function custom_post_type() {

  $labels = array(
    'name'                => _x( 'Podcasts', 'Podcast General Name', 'text_domain' ),
    'singular_name'       => _x( 'Podcast', 'Course Singular Name', 'text_domain' ),
    'menu_name'           => __( 'Podcasts', 'text_domain' ),
    'parent_item_colon'   => __( 'Parent Podcast:', 'text_domain' ),
    'all_items'           => __( 'All Podcasts', 'text_domain' ),
    'view_item'           => __( 'View Podcast', 'text_domain' ),
    'add_new_item'        => __( 'Add New Podcast', 'text_domain' ),
    'add_new'             => __( 'Add New', 'text_domain' ),
    'edit_item'           => __( 'Edit Podcast', 'text_domain' ),
    'update_item'         => __( 'Update Podcast', 'text_domain' ),
    'search_items'        => __( 'Search Podcasts', 'text_domain' ),
    'not_found'           => __( 'Not found', 'text_domain' ),
    'not_found_in_trash'  => __( 'Not found in Trash', 'text_domain' ),
  );
  $args = array(
    'label'               => __( 'podcasts', 'text_domain' ),
    'description'         => __( 'Podcast Description', 'text_domain' ),
    'labels'              => $labels,
    'supports'            => array( 'title', 'editor', 'thumbnail' ),
    'taxonomies'          => array( 'category', 'post_tag' ),
    'hierarchical'        => false,
    'public'              => true,
    'show_ui'             => true,
    'show_in_menu'        => true,
    'show_in_nav_menus'   => true,
    'show_in_admin_bar'   => true,
    'menu_position'       => 5,
    'menu_icon'           => 'dashicons-format-audio',
    'can_export'          => true,
    'has_archive'         => true,
    'exclude_from_search' => false,
    'publicly_queryable'  => true,
    'capability_type'     => 'page'
  );
  register_post_type( 'podcasts', $args );
}

add_action( 'init', 'custom_post_type', 0 );

This is a lot of code, but it’s just configuration to register a new post type called Podcasts. It defines the various labels for it in the WordPress dashboard, and tells WordPress how to handle it. Again, the WordPress Codex explains these things much more exhaustively, if you’re interested.

At this point in time, we can head into the Plugins section of our WordPress admin and seeMy Awesome Podcast listed as an available plugin. Go ahead and activate it.

Create Custom Fields for Podcast Posts

WordPress posts do a lot for us right out of the box, but sometimes we need additional fields that allow us to publish specific content. In this case, iTunes has a very specific format for what kind of information needs to be available in our RSS feed.

There is a way to add custom fields to our custom post type with extra development, but I actually prefer using the Advanced Custom Fields plugin for this sort of thing. It allows us to have a nice clean custom UI for each field we add, rather than the generic key/value pair UI you get with default custom fields.

Using Advanced Custom Fields, let’s set up a new field group called Podcasts, assign them to the Podcast post type and create the following fields:

  • podcast_file: Use the “File” field type so we can upload our podcast file directly to the post. Set the field to Return Value to “File ID” because this will help us auto-detect the file size later.
  • podcast_duration: This is a simple text field that we’ll use to publish the length of our episode in HH:MM:SS format.

Note: While I used the “File” field type in this example, you could theoretically use a text field if you plan on hosting your podcast files somewhere other than your server (say Amazon S3 or something like that), and paste the URL directly in there. However, we won’t be able to auto-detect the file size this way, though we could use another text field for that purpose.

Create the RSS Template

We’ve done a lot so far. The last thing to do is create the template that will be used to display the data for our podcast posts.

Apple has outlined the specs for an acceptable podcast RSS feed and it’s very specific. Using that outline as a guide, let’s create one more file in our plugin folder and call it `podcast-rss-template.php`. The name says it all, right?

The nice thing is that our RSS template is technically no different from any other WordPress template. We will query our posts, create a loop, and plug our data in where it needs to go.

/** 
Template Name: Podcast RSS
**/

// Query the Podcast Custom Post Type and fetch the latest 100 posts
$args = array( 'post_type' => 'podcasts', 'posts_per_page' => 100 );
$loop = new WP_Query( $args );

// Output the XML header
header('Content-Type: '.feed_content_type('rss-http').'; charset='.get_option('blog_charset'), true);
echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>';
?>

<?php // Start the iTunes RSS Feed: https://www.apple.com/itunes/podcasts/specs.html ?>
<rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0">
  
  <?php 
    // The information for the podcast channel 
    // Mostly using get_bloginfo() here, but these can be custom tailored, as needed
  ?>
  <channel>
    <title><?php echo get_bloginfo('name'); ?></title>
    <link><?php echo get_bloginfo('url'); ?></link>
    <language><?php echo get_bloginfo ( 'language' ); ?></language>
    <copyright><?php echo date('Y'); ?> <?php echo get_bloginfo('name'); ?></copyright>
    
    <itunes:author><?php echo get_bloginfo('name'); ?></itunes:author>
    <itunes:summary><?php echo get_bloginfo('description'); ?></itunes:summary>
    <description><?php echo get_bloginfo('url'); ?></description>
    
    <itunes:owner>
      <itunes:name><?php echo get_bloginfo('name'); ?></itunes:name>
      <itunes:email><?php echo get_bloginfo('admin_email'); ?></itunes:email>
    </itunes:owner>
    
    <?php // Change to your own image. Must be at least 1400 x 1400: https://www.apple.com/itunes/podcasts/creatorfaq.html
    <itunes:image href="http://your-site.com/path/to/podcast/image.png" />
    
    <itunes:category text="Technology">
      <itunes:category text="Tech News"/>
    </itunes:category>
    
    <?php // Start the loop for Podcast posts
    while ( $loop->have_posts() ) : $loop->the_post(); ?>
    <item>
      <title><?php the_title_rss(); ?></title>
      <itunes:author><?php echo get_bloginfo('name'); ?></itunes:author>
      <itunes:summary><?php the_excerpt_rss(); ?></itunes:summary>
      <?php // Retrieve just the URL of the Featured Image: http://codex.wordpress.org/Function_Reference/wp_get_attachment_image_src
      if (has_post_thumbnail( $post->ID ) ): ?>
        <?php $image = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'full' ); ?>
        <itunes:image href="<?php echo $image[0]; ?>" />
      <?php endif; ?>
      
      <?php // Get the file field URL and filesize
        $attachment_id = get_field('podcast_file');
        $fileurl = wp_get_attachment_url( $attachment_id );
        $filesize = filesize( get_attached_file( $attachment_id ) );
      ?>
      
      <enclosure url="<?php echo $fileurl; ?>" length="<?php echo $filesize; ?>" type="audio/mpeg" />
      <guid><?php echo $fileurl; ?></guid>
      <guid><?php the_field('podcast_file'); ?></guid>
      <pubDate><?php the_time( 'D, d M Y G:i:s T') ?></pubDate>
      <itunes:duration><?php the_field('podcast_duration'); ?></itunes:duration>
    </item>
    <?php endwhile; ?>
  
  </channel>

</rss>

Note: the code above assumes you’re uploading the MP3 file to your own site/server. When that’s the case, it can get the file size in bytes, which iTunes requires as part of the RSS feed, which is super handy. However, if you’re hosting the MP3 file elsewhere (can be smart, most web hosts aren’t built for serving large assets), this won’t work. Instead, add an additional field with ACF for the byte size and output it where we’re outputting$filesize above.

Now let’s call this RSS template in our `my-awesome.podcast.php` file by adding the following:

function my_podcast_rss(){
  require_once( dirname( __FILE__ ) . '/podcast-rss-template.php' );
}

Putting it All Together

Let’s recap how everything fits together.

The Files

In short, we now have a new folder in our plugin directory called `my-awesome-podcast`.

WordPress Root Directory
└── wp-content
    └── plugins
        └── my-awesome-podcast
            ├── my-awesome-podcast.php
            └── podcast-rss-template.php
  • my-awesome.podcast.php: This registers our plugin, creates a custom RSS feed, defines a new custom post type and calls our RSS template.
  • podcast-rss-template.php: This contains the template for our RSS feed, providing the information from our Podcasts posts in a format that iTunes can read and use to deliver our content to subscribers.

Publishing a Podcast

Go ahead and publish a new Podcast post. The option will be in your WordPress menu under Podcasts.

  • Give the podcast a title
  • Upload the podcast episode file
  • Specify the episode length (in HH:MM:SS format)
  • (if not hosting locally) Specify the episode file size (in bytes)
  • Provide a summary of the episode in the content area

Awesome, we just published your first podcast episode!

Submit the Podcast to iTunes

Finally, go visit the URL of the feed at: `[your-site]/feed/[slug]`, where `[slug]` is what we defined in the add_feed() function back in the second step. It wouldn’t hurt to validate the feed just to make sure it’s healthy and happy. This is the URL you will submit to iTunes, which you can do from the iTunes app under iTunes Store > Podcasts > Quick Links > Submit a Podcast.

If you’re getting a Page Not Found (404), try flushing your permalinks. This can be done by heading to Settings > Permalinks from your WordPress dashboard and doing nothing more than clicking the Save Settings button. Strange, but true.

Go Forth and Podcast

There you go! A simple, but effective way to host your podcast using resources you probably already have lying around. Sure, there may be more powerful or even more elegant solutions, but this gives us exactly what we need with nothing more and nothing less.

How to Roll Your Own Simple WordPress Podcast Plugin is a post from CSS-Tricks


Stairway Navigation (A jQuery Plugin?) by Chris Coyier

On a whim the other day I thought I’d build out an idea for navigation I had. It’s nothing but a visual effect in which the hovered (or active) navigation item becomes the tallest “stair” and other items before and after it step down. It’s simple, but it’s not something you see very often. Probably for one major reason: you can’t select “previous” elements in CSS.

 

stairwaynav View Demo 

You can select “next” elements in CSS. You’d use the general sibling combinator  to get all the next elements or theadjacent sibling combinator  to get the very next one (which you could chain). Neither of those allow you to get the previous elements which, as you can see by the image above, is needed to do this effect justice.

In pseudo code, we’re trying to do this:

/* Not Real Code */

a:hover { /* top stair stuff */ }

a:hover-1,
a:hover+1 { /* second stair stuff *}

a:hover-2,
a:hover-2 { /* third stair stuff *}

Rather than get too tricky for our own good with CSS, let’s rely on a technology that can select previous elements: jQuery. jQuery has a .prev()  function (and a few other related functions) that we can use to get what we need. Our psuedo code would become more like this real code:

$("nav a").hover(function() {
  $(this)
   .addClass("stair-1")
   .prev()
     .addClass("stair-2")
     .prev()
       .addClass("stair-3")
       .end()
     .end()
   .next()
     .addClass("stair-2")
     .next()
       .addClass("stair-3");  
});

Presumably we’d clear all classes on all nav elements on a mouseleave event as well. That means to be most efficient we’d already have a pointer to all those elements.

var navEls = $("nav a");

navEls
  .on("mouseenter", function() {
     // add classes as above
  })
  .on("mouseleave", function() {
     navsEls.removeClass("stair-1 stair-2 stair-3);
  })

So now that we have a set, we might as well get a bit more efficient. Using .next() and .prev() means a lot of jQuery going back out to the DOM to figure out what to select (I think, correct me if I’m wrong there). Rather than do that, we can just select based on the set we already have selected based on it’s position within that set. The .index() function helps us figure that out and .eq() let’s us grab the element based on its index.

navEls
  .mouseenter(function() {

    $(this).addClass("stair-1");

    var index = $(this).index();
    
    allLinks.eq(index+1).addClass("stair-2");
    allLinks.eq(index-1).addClass("stair-2");

    allLinks.eq(index+2).addClass("stair-3");
    allLinks.eq(index-2).addClass("stair-3");

  })

That’ll do the trick.

CSS does the design work

Notice that all the jQuery is doing is adding and removing classes. That’s how UI and JavaScript should hang out the majority of the time. JavaScript is in charge of knowing about and changing states – CSS does the work of making the page look different.

The entire “stairway” visual effect comes in now, when we apply styles based on those classes.

.stair-1 {
  transform:
    scale(1.10)
    translateX(24px)
  box-shadow: 0 0 10px rgba(black, 0.75);
  z-index: 3;
}
.stair-2 {
  transform:
    scale(1.07)
    translateX(12px)
  box-shadow: 0 0 10px rgba(black, 0.5);
  z-index: 2;
}
.stair-3 {
  transform:
    scale(1.04)
    translateX(4px)
  z-index: 1;
}

The “top” stair (stair-1) enlarges, moves to the right, and has a deep shadow. Each of the subsequents stairs does a bit less of all those things. You could also change colors here or do anything else that would make sense to your own application.

A jQuery Plugin?

I put those words in the title of this post because I think this is interesting territory.

Does this kind of thing “deserve” to be pluginized? For one thing – this is heavily dependent on CSS. Calling it a “Stairway Navigation” plugin isn’t descriptive of what the actual jQuery code is doing. It also doesn’t make use of any of jQuery’s built-in features that are built for this, like it’s ability to animate things – we instead leave that to CSS.

Anyway – we are going to pluginize it because it makes things more interesting.

Plugin Options

We’ll make it the simplest set of options possible: how many stairs do you want stepping down? You’ll call it on a navigation element that contains only anchor links:

$(".main-nav").stairwayNav({
  stairs: 2
});

Then in the plugin, we make sure we have access to a “stairs” variable that is either the passed in value or some default.

$.fn.stairwayNav = function(options) {
  
  var defaults = {
     stairs: 3
  };
  this.options = $.extend({}, defaults, options);
  var stairs = this.options.stairs;

I love that pattern. It means we don’t have to do any fancy crap checking if the object contains certain keys and ensuring they aren’t blank and blah blah. If you pass in a value for “stairs”, that’s what ends up in the options object. If you don’t, it gets a default value. Cool.

Looping

To honor that option, we now just run a little for loop as many times as there are stairs. We adjust the index value the more iterations it runs, just never selecting negative values.

navEls
  .mouseenter(function() {
    $(this).addClass("stair-1");
    var index = $(this).index(), i, bef, aft;
    for(i = 1; i < stairs; i++) {
      
      bef = index - i;
      aft = index + i;
     
      allLinks.eq(aft).addClass("stair-" + (i+1));
      if (bef > 0) {
        allLinks.eq(bef).addClass("stair-" + (i+1));
      }
    }   
  })

Stairway Navigation Demo

Here is the demo on CodePen .

 

Stairway Navigation (A jQuery Plugin?)  is a post from CSS-Tricks

 

Enhanced by Zemanta

About normalize.css

…things by Nicolas Gallagher

Normalize.css is a small CSS file that provides better cross-browser consistency in the default styling of HTML elements. It’s a modern, HTML5-ready, alternative to the traditional CSS reset.

Normalize.css is currently used in some form by Twitter Bootstrap,HTML5 BoilerplateGOV.UKRdioCSS Tricks, and many other frameworks, toolkits, and sites.

Overview

Normalize.css is an alternative to CSS resets. The project is the product of 100′s of hours of extensive research by @necolas and @jon_neal on the differences between default browser styles.

The aims of normalize.css are as follows:

  • Preserve useful browser defaults rather than erasing them.
  • Normalize styles for a wide range of HTML elements.
  • Correct bugs and common browser inconsistencies.
  • Improve usability with subtle improvements.
  • Explain the code using comments and detailed documentation.

It supports a wide range of browsers (including mobile browsers) and includes CSS that normalizes HTML5 elements, typography, lists, embedded content, forms, and tables.

Despite the project being based on the principle of normalization, it uses pragmatic defaults where they are preferable.

Normalize vs Reset

It’s worth understanding in greater detail how normalize.css differs from traditional CSS resets.

Normalize.css preserves useful defaults

Resets impose a homogenous visual style by flattening the default styles for almost all elements. In contrast, normalize.css retains many useful default browser styles. This means that you don’t have to redeclare styles for all the common typographic elements.

When an element has different default styles in different browsers, normalize.css aims to make those styles consistent and in line with modern standards when possible.

Normalize.css corrects common bugs

It fixes common desktop and mobile browser bugs that are out of scope for resets. This includes display settings for HTML5 elements, correctingfont-size for preformatted text, SVG overflow in IE9, and many form-related bugs across browsers and operating systems.

For example, this is how normalize.css makes the new HTML5 searchinput type cross-browser consistent and stylable:

/*
 * 1. Addresses appearance set to searchfield in S5, Chrome
 * 2. Addresses box-sizing set to border-box in S5, Chrome (include -moz to future-proof)
 */

input[type="search"] {
    -webkit-appearance: textfield; /* 1 */
    -moz-box-sizing: content-box;
    -webkit-box-sizing: content-box; /* 2 */
    box-sizing: content-box;
}

/*
 * Removes inner padding and search cancel button in S5, Chrome on OS X
 */

input[type="search"]::-webkit-search-decoration,
input[type="search"]::-webkit-search-cancel-button {
    -webkit-appearance: none;
}

Resets often fail to bring browsers to a level starting point with regards to how an element is rendered. This is particularly true of forms – an area where normalize.css can provide some significant assistance.

Normalize.css doesn’t clutter your debugging tools

A common irritation when using resets is the large inheritance chain that is displayed in browser CSS debugging tools.

A common sight in browser debugging tools when using a CSS reset

This is not such an issue with normalize.css because of the targeted styles and the conservative use of multiple selectors in rulesets.

Normalize.css is modular

The project is broken down into relatively independent sections, making it easy for you to see exactly which elements need specific styles. Furthermore, it gives you the potential to remove sections (e.g., the form normalizations) if you know they will never be needed by your website.

Normalize.css has extensive documentation

The normalize.css code is based on detailed cross-browser research and methodical testing. The file is heavily documented inline and further expanded upon in the GitHub Wiki. This means that you can find out what each line of code is doing, why it was included, what the differences are between browsers, and more easily run your own tests.

The project aims to help educate people on how browsers render elements by default, and make it easier for them to be involved in submitting improvements.

How to use normalize.css

First, download normalize.css from GitHub. There are then 2 main ways to make use of it.

Approach 1: use normalize.css as a starting point for your own project’s base CSS, customising the values to match the design’s requirements.

Approach 2: include normalize.css untouched and build upon it, overriding the defaults later in your CSS if necessary.

Closing comments

Normalize.css is significantly different in scope and execution to CSS resets. It’s worth trying it out to see if it fits with your development approach and preferences.

The project is developed in the open on GitHub. Anyone can report issues and submit patches. The full history of the project is available for anyone to see, and the context and reasoning for all changes can be found in the commit messages and the issue threads.

Related reading

Detailed information on default UA styles: WHATWG suggestions for rendering HTML documentsInternet Explorer User Agent Style Sheets andCSS2.1 User Agent Style Sheet Defaults.

Translations

Enhanced by Zemanta

Another CSS image replacement technique

…things by Nicolas Gallagher

A new image replacement technique was recently added to the HTML5 Boilerplate project. This post explains how it works and how it compares to alternative image replacement techniques.

Here’s the CSS behind the recent update to the image replacement helper class in HTML5 Boilerplate. It has also made its way into the Compassframework.

.ir {
    font: 0/0 a;
    text-shadow: none;
    color: transparent;
}

What does each declaration do?

  • font:0/0 a – a shorthand property that zeros out the font size and line-height. The a value acts as a very short font-family (an idea taken from theBEM implementation of this method). The CSS validator complains that using 0/0 in the shorthand font property is not valid, but every browser accepts it and this appears to be an error in the validator. Usingfont:0px/0 a passes validation but it displayed as font:0/0 a in the code that the validator flags as valid.
  • text-shadow:none – makes sure that any inherited text shadow is removed for the text. This prevents the chance of any text shadow colors showing over the background.
  • color:transparent – needed for browsers than don’t completely crush the text to the point of being invisible. Safari 4 (extremely rare) is an example of such a browser. There may also be mobile browsers than require this declaration. IE6/7/8 don’t recognise this value for color, but fortunately IE7/8 don’t show any trace of the text. IE6 shows a faint trace.

In the HTML5 Boilerplate image replacement helper, we’ve also removed any border and background-color that may be on the element. This makes it easier to use the helper class on elements like button or with links that may included background or border properties as part of a design decision.

Benefits over text-indent methods

The new technique avoids various problems with any text-indent method, including the one proposed by Scott Kellum to avoid iPad 1 performance problems related to large negative text indents.

  • Works in IE6/7 on inline-block elements. Techniques based on text indentation are basically “broken”, as shown by this test case:http://jsfiddle.net/necolas/QZvYa/show/
  • Doesn’t result in any offscreen box being created. The text-indentmethods result in a box being drawn (sometimes offscreen) for any text that have been negatively or positively indented. It can sometimes cause performance problems but the font-based method sidesteps those concerns.
  • No need to specify a text-alignment and hide the overflow since the text is crushed to take up no space.
  • No need to hide br or make all fallback HTML display:inline to get around the constraints of using a text indentation. This method is not affected by those problems.
  • Fewer styles are needed as a result of these improvements.

Drawbacks

No image replacement hack is perfect.

  • Leaves a very small trace of the text in IE6.
  • This approach means that you cannot use em units for margins on elements that make use of this image replacement code. This is because the font size is set to 0.
  • Windows-Eyes has a bug that prevents the reading of text hidden using this method. There are no problems with all other screenreaders that have been tested. Thanks to @jkiss for providing these detailed results and to@wilto for confirming this technique works for JAWS 12 in IE 6/7/8 and Firefox 4/5/6.
  • Like so many IR methods, it doesn’t work when CSS is loaded but images are not.
  • Text may not be hidden if a visitor is using a user style sheet which has explicitly set important font-size declarations for the element type on which you have applied the IR class.

It’s worth noting that the NIR image replacement technique avoids these drawbacks, but lacks support in IE6/7.

Closing comments

I’ve been using this technique without significant problems for nearly a year, ever since Jonathan Neal and I used it in a clearfix experiment. The BEM framework also makes use of it for their icon components. The core idea was even proposed back in 2003 but the browser quirks of the day may have prevented wider use.

If you come across any problems with this technique, please report them at the HTML5 Boilerplate GitHub issue tracker and include a test case when appropriate.

Translations

 

Enhanced by Zemanta