Our Team Keeps Getting Stronger

We’re launching new projects, getting busier, and growing our team. Another Backend Developer has joined us. Meet Jeremy and find out what he brings to WebDevStudios (WDS).

Jeremy Ward, Backend Developer

A native of St. Paul, Minnesota, Jeremy got his start in web development as a hobby, learning to build static websites for his bands and friends. This part-time curiosity eventually blossomed into an interest in database queries and server-side languages and, by 2013, he found himself working at a local agency developing custom WordPress themes for small businesses and non-profits.

Jeremy currently volunteers on the organizing committee for WordCamp Minneapolis-St. Paul and also co-organizes a bi-monthly meetup for WordPress developers in the Twin Cities. He is passionate about code quality, modular design, and developer tools, and has begun converting that passion into speaking engagements at local meetups and conferences.

When he’s not geeking out about software development, Jeremy enjoys playing board games, seeing live stand-up comedy, and taking walks around his neighborhood.

Check out Jeremy’s website at J Michael Ward, and follow him on Twitter and Instagram. Connect with him at GitHub. And if you’re interested in adding your talents into the mix at WDS, then learn more about our job openings here.

JavaScript: Reusable Components and API

Over the past year, I have been working very hard to learn JavaScript deeply. I have even purposefully taken the approach to learn it outside of the WordPress ecosystem. Why? Because it promotes exploring and learning different techniques that you can then take and apply to WordPress!

The purpose of this post is to try and provide a different approach to building a thing. In this case, that thing will be a modal UI component. Yes, another modal! There are many facets of JavaScript that I love and building UI components is one of them.

It’s important to note what I stated above. We will be looking at a different approach, not a new one. While the example I will be using is written in ES2015 there’s nothing new or groundbreaking about it. It just might take a different approach than what you might normally see.

On many of the projects we work on here at WDS, there is almost always a requirement to have at least one modal and in some cases even multiple modals on the same page. While this may seem simple to implement, there are a lot of questions and observations that should be taken into consideration.

  • What is going to be the trigger for opening a modal?
  • If there are multiple modals on one page, then we will need multiple, unique triggers.
  • What will be the close trigger for each of the modals?
  • What will be the contents of the modals?
  • Will the content be created on the fly, or will it be markup that has already been rendered to the page but is just hidden?
  • How can we nicely present the modal?
  • Implementing a nice animation into a modal can be tricky!
  • Do you need to apply a CSS class to another element on the page when the modal is open and the remove it when the modal is closed?

In a lot of cases, a typical approach would be to create a JavaScript module or file for the particular project you are working on and code a solution to meet the requirements for that project. Then two months later when a new project starts, you follow the same process and re-code something new to meet the requirements of the new project.

What I’m trying to point out here is that the modal we’ve ended up writing is not very reusable from project to project. Sure, you might be able to take bits and pieces of code and move them from project to project, but in the end, you are creating a unique solution for each new project.

Let’s explore a different approach! One that would allow for code reuse across projects.

Building Reusable Components

The concept that I’d like to drive home in this post is to start thinking about building reusable components that are powered by their API. I’ve really learned a lot about this concept by learning React and Redux. Feel free to check out the experimental WordPress theme I built using React and Redux.

You don’t need to be using any fancy frameworks in order to implement the idea of building reusable components. To be honest, the thought of having a UI component such as a modal that has default options you can override and callback functions you can tap into is super exciting!

For this post, we are going to focus on building a modal UI component in vanilla ES2015 that is reusable. This isn’t going to be a full-blown solution, but it will hopefully be enough to show the power behind building reusable components that expose an API for powering them.

Since we will be using ES2015, let’s start by scaffolding out a class that we will use for our component:

/**
 * Modal Class
 */
class Modal {

    /**
     * Constructor
     *
     * @param openTrigger The element that will trigger opening the modal.
     * @param options Options that will override defaults.
     */
    constructor( openTrigger, options ) {
        
    }

    // Bind events.
    bindEvents() {
    
    }

    // Open the modal.
    open() {
    
    }

    // Close the modal.
    close() {

    }

    // Render the modal.
    render() {

    }

    // Modal HTML template.
    htmlTemplate() {
        
    }
}

Next, just like in PHP, the constructor function is going to be run each time the Modal class is instantiated. Our Modal class will take two parameters. The openTrigger will be the HTML element that triggers opening the modal and the options parameter will be the options we pass in to override the defaults.

/**
 * Modal Class
 */
class Modal {

    /**
     * Constructor
     *
     * @param openTrigger The element that will trigger opening the modal.
     * @param options Options that will override defaults.
     */
    constructor( openTrigger, options ) {
        
        /**
         * Configuration options.
         *
         * Merge any user defined options into default config.
         */
        this.config = Object.assign( {
            backgroundColor: '',
            modalTitle: 'This is a modal!',
            modalText: 'Default modal description text.',
            onBefore: null,
            onAfter: null
        }, options );

        // Bind callback functions to the Modal.
        this.config.onBefore = this.config.onBefore.bind( this );
        this.config.onAfter = this.config.onAfter.bind( this );

        // Set open trigger.
        this.openTrigger = openTrigger;

        // Set modal events.
        this.bindEvents();
        
    }
}

You will notice in the code above that we are using Object.assign(). This is an exciting new method in ES2015 that allows for merging two objects. I would encourage you to read and learn more about Object.assign(). Anyways, we are just merging the options object being passed in with the default options provided.

For this example, we are going to use a new ES2015 feature called template literals to create the markup needed for our modal. Notice how we are able to display variables right inside our template literal strings.

/**
 * Modal Class
 */
class Modal {

    /**
     * Constructor
     *
     * @param openTrigger The element that will trigger opening the modal.
     * @param options Options that will override defaults.
     */
    constructor( openTrigger, options ) {
        
        /**
         * Configuration options.
         *
         * Merge any user defined options into default config.
         */
        this.config = Object.assign( {
            backgroundColor: '',
            modalTitle: 'This is a modal!',
            modalText: 'Default modal description text.',
            onBefore: null,
            onAfter: null
        }, options );

        // Bind callback functions to the Modal.
        this.config.onBefore = this.config.onBefore.bind( this );
        this.config.onAfter = this.config.onAfter.bind( this );

        // Set open trigger.
        this.openTrigger = openTrigger;

        // Set modal events.
        this.bindEvents();
        
    }

    // Modal HTML template.
    htmlTemplate() {
        return `
            <div id="my-modal" class="my-modal" style="background-color:${this.config.backgroundColor}";>
                
                <div class="my-modal-content">
                    <button id="close">X</button>
                    <h1>${this.config.modalTitle}!</h1>
                    <p>${this.config.modalText}</p>
                </div>

            </div>
        `;
    }
}

Next, we will need a render() method that will be responsible for putting together the template and attaching it to the DOM. As you can see, we are using a document fragment to build out the markup. A document fragment is a minimal document object that isn’t actually a part of the DOM. It’s a performant way of composing some markup in memory then attaching it to an element.

/**
 * Modal Class
 */
class Modal {

    /**
     * Constructor
     *
     * @param openTrigger The element that will trigger opening the modal.
     * @param options Options that will override defaults.
     */
    constructor( openTrigger, options ) {
        
        /**
         * Configuration options.
         *
         * Merge any user defined options into default config.
         */
        this.config = Object.assign( {
            backgroundColor: '',
            modalTitle: 'This is a modal!',
            modalText: 'Default modal description text.',
            onBefore: null,
            onAfter: null
        }, options );

        // Bind callback functions to the Modal.
        this.config.onBefore = this.config.onBefore.bind( this );
        this.config.onAfter = this.config.onAfter.bind( this );

        // Set open trigger.
        this.openTrigger = openTrigger;

        // Set modal events.
        this.bindEvents();
        
    }

    // Render the modal.
    render() {

        // Set the template.
        const html = this.htmlTemplate();

        // Create a document fragment.
        const docFrag = document.createDocumentFragment();

        // Create a <div> on the fly.
        this.containerDiv = document.createElement( 'div' );

        // Set the HTML of the <div> to the HTML template.
        this.containerDiv.innerHTML = html;

        // Append the modal HTML to the body.
        document.body.appendChild( this.containerDiv );
    }

    // Modal HTML template.
    htmlTemplate() {
        return `
            <div id="my-modal" class="my-modal" style="background-color:${this.config.backgroundColor}";>
                
                <div class="my-modal-content">
                    <button id="close">X</button>
                    <h1>${this.config.modalTitle}!</h1>
                    <p>${this.config.modalText}</p>
                </div>

            </div>
        `;
    }
}

Now we need open and close methods. These two function will be somewhat similar, but let’s touch on a few key points.

/**
 * Modal Class
 */
class Modal {

    /**
     * Constructor
     *
     * @param openTrigger The element that will trigger opening the modal.
     * @param options Options that will override defaults.
     */
    constructor( openTrigger, options ) {
        
        /**
         * Configuration options.
         *
         * Merge any user defined options into default config.
         */
        this.config = Object.assign( {
            backgroundColor: '',
            modalTitle: 'This is a modal!',
            modalText: 'Default modal description text.',
            onBefore: null,
            onAfter: null
        }, options );

        // Bind callback functions to the Modal.
        this.config.onBefore = this.config.onBefore.bind( this );
        this.config.onAfter = this.config.onAfter.bind( this );

        // Set open trigger.
        this.openTrigger = openTrigger;

        // Set modal events.
        this.bindEvents();
        
    }

    // Open the modal.
    open() {
        this.render();

        // Cache DOM.
        this.modalDiv = document.getElementById( 'my-modal' );
        this.myModalContent = document.querySelector( '.my-modal-content' );

        // Bind close event.
        this.modalDiv.addEventListener( 'click', this.close.bind( this ) );

        // Call onBefore if it is defined.
        if ( this.config.onBefore ) {
            this.config.onBefore();
        }

        // Add classes.
        this.modalDiv.classList.add( 'opened' );
        this.myModalContent.classList.add( 'animate-in' );

        // Remove animate class.
        setTimeout( () => {
            this.myModalContent.classList.remove( 'animate-in' )
        }, 600 );
    }

    // Close the modal.
    close( e ) {

        // If we click the close button.
        if ( e.target.id === 'close' && e.type === 'click' ) {
            this.myModalContent.classList.add( 'animate-out' );


            // Remove classes.
            setTimeout( () => {

                // Remove classes.
                this.myModalContent.classList.remove( 'animate-out' );
                this.modalDiv.classList.remove( 'opened' );

                // Remove <div> from the DOM.
                this.containerDiv.parentNode.removeChild( this.containerDiv );

                // If onAfter is defined then call it.
                if ( this.config.onAfter ) {
                    this.config.onAfter();
                }
            }, 600 );
        }

        return false;
    }

    // Render the modal.
    render() {

        // Set the template.
        const html = this.htmlTemplate();

        // Create a document fragment.
        const docFrag = document.createDocumentFragment();

        // Create a <div> on the fly.
        this.containerDiv = document.createElement( 'div' );

        // Set the HTML of the <div> to the HTML template.
        this.containerDiv.innerHTML = html;

        // Append the modal HTML to the body.
        document.body.appendChild( this.containerDiv );
    }

    // Modal HTML template.
    htmlTemplate() {
        return `
            <div id="my-modal" class="my-modal" style="background-color:${this.config.backgroundColor}";>
                
                <div class="my-modal-content">
                    <button id="close">X</button>
                    <h1>${this.config.modalTitle}!</h1>
                    <p>${this.config.modalText}</p>
                </div>

            </div>
        `;
    }
}

First, both functions check to see if a callback function has been passed in via the Modal options. For the open() method the callback that is checked for is this.config.onBefore() and for the close method the callback checked for is this.config.onAfter(). If either has been set, it will be called.

Second, we are utilizing a setTimeout() function along with arrow functions to add and remove CSS classes that will help us animate in the modal. This perhaps isn’t the best solution here, but for the sake of this example, it works just fine. You could explore using transition or animation events as other possible solutions.

The last function is a simple bindEvents() function that’s sole purpose is to bind the open() function to the open trigger specified by the user.

/**
 * Modal Class
 */
class Modal {

    /**
     * Constructor
     *
     * @param openTrigger The element that will trigger opening the modal.
     * @param options Options that will override defaults.
     */
    constructor( openTrigger, options ) {
        
        /**
         * Configuration options.
         *
         * Merge any user defined options into default config.
         */
        this.config = Object.assign( {
            backgroundColor: '',
            modalTitle: 'This is a modal!',
            modalText: 'Default modal description text.',
            onBefore: null,
            onAfter: null
        }, options );

        // Bind callback functions to the Modal.
        this.config.onBefore = this.config.onBefore.bind( this );
        this.config.onAfter = this.config.onAfter.bind( this );

        // Set open trigger.
        this.openTrigger = openTrigger;

        // Set modal events.
        this.bindEvents();
        
    }

    // Bind events.
    bindEvents() {
        this.openTrigger.addEventListener( 'click', this.open.bind( this ) );
    }

    // Open the modal.
    open() {
        this.render();

        // Cache DOM.
        this.modalDiv = document.getElementById( 'my-modal' );
        this.myModalContent = document.querySelector( '.my-modal-content' );

        // Bind close event.
        this.modalDiv.addEventListener( 'click', this.close.bind( this ) );

        // Call onBefore if it is defined.
        if ( this.config.onBefore ) {
            this.config.onBefore();
        }

        // Add classes.
        this.modalDiv.classList.add( 'opened' );
        this.myModalContent.classList.add( 'animate-in' );

        // Remove animate class.
        setTimeout( () => {
            this.myModalContent.classList.remove( 'animate-in' )
        }, 600 );
    }

    // Close the modal.
    close( e ) {

        // If we click the close button.
        if ( e.target.id === 'close' && e.type === 'click' ) {
            this.myModalContent.classList.add( 'animate-out' );


            // Remove classes.
            setTimeout( () => {

                // Remove classes.
                this.myModalContent.classList.remove( 'animate-out' );
                this.modalDiv.classList.remove( 'opened' );

                // Remove <div> from the DOM.
                this.containerDiv.parentNode.removeChild( this.containerDiv );

                // If onAfter is defined then call it.
                if ( this.config.onAfter ) {
                    this.config.onAfter();
                }
            }, 600 );
        }

        return false;
    }

    // Render the modal.
    render() {

        // Set the template.
        const html = this.htmlTemplate();

        // Create a document fragment.
        const docFrag = document.createDocumentFragment();

        // Create a <div> on the fly.
        this.containerDiv = document.createElement( 'div' );

        // Set the HTML of the <div> to the HTML template.
        this.containerDiv.innerHTML = html;

        // Append the modal HTML to the body.
        document.body.appendChild( this.containerDiv );
    }

    // Modal HTML template.
    htmlTemplate() {
        return `
            <div id="my-modal" class="my-modal" style="background-color:${this.config.backgroundColor}";>
                
                <div class="my-modal-content">
                    <button id="close">X</button>
                    <h1>${this.config.modalTitle}!</h1>
                    <p>${this.config.modalText}</p>
                </div>

            </div>
        `;
    }
}

Now that we have our modal class built out with the basic functionality we can now create a couple of different modals that will work independently of each other.

Here is code that will instantiate two different modals. Each will have a different openTrigger parameter as well as different options.

// Declare two modal triggers.
const modalOneTrigger = document.getElementById( 'open-modal-1' );
const modalTwoTrigger = document.getElementById( 'open-modal-2' );

// Get the header element.
const header = document.getElementsByTagName( 'header' );

new Modal( modalOneTrigger, {
    modalTitle: 'Overriding the Title!',
    onAfter: function() {
        // Let's remove a class to the header!
        header[0].classList.remove( 'modal-open' );
    },
    onBefore: function() {
        // Let's remove a class to the header!
        header[0].classList.add( 'modal-open' );
    }
} );

new Modal( modalTwoTrigger, {
    modalTitle: 'This is modal two!',
    onAfter: function() {
        // Set the background back to the original.
        document.querySelector( '.container' ).style.background = '';
    },
    onBefore: function() {
        // Change the background color of the container!
        document.querySelector( '.container' ).style.background = '#88C542';
    }
} );

First, we are declaring two different button elements that will act as our modal triggers.

Then we ‘new-up’ each modal with their respective trigger button, as well as their custom options. Notice how I am writing an anonymous function that will be called in our open() and close() methods.

Check out this CodePen for a working demo.

I hope that this post shows the power of creating reusable components. It doesn’t have to be confined to just JavaScript, as well. No matter what you are coding, it’s always great to do it with the mindset of reusability.

Feel free to leave a comment below to further the discussion!

He’s Back! Backend Developer Rejoins WebDevStudios

Benjamin Mueller, Backend Developer

After a short hiatus, Backend Developer Benjamin Mueller has returned to WebDevStudios. He began using WordPress with version 2.7 and has been in love ever since. This romance has grown and taken him to multiple WordPress events all along the West Coast. Benjamin is enthralled with connecting and learning from his fellow WordPress pioneers. Attending WordCamps allows him to explore his passion for WordPress and become better connected with the community. Throughout Benjamin’s career, he has worked with numerous development firms and organizations. He believes everything in the world can be described in code and is a strong advocate for open source software.

When he’s not coding in a coffee shop, he’s out in his garage building and creating things out of any material within hand’s reach. These activities have taught him the joy of solving complex problems with simple solutions. As much as he loves putting things together, he also loves taking things apart, with explosives. Working Pyrotechnic shows is his ideal weekend getaway and he hopes to one day complete his Pyrotechnics license. So next time you see a firework, think of Benjamin, ’cause baby he’s a fiiiiirrework!

Connect with Benjamin on Github and follow him on Twitter. If you want to be like Benjamin and join an amazing team of developers and project managers, then you should check out our job openings here.

5 Steps to Planning the Ultimate Workcation

When you started your journey as a freelancer or remote worker, I’m sure you imagined working on a beach with your laptop and a Piña Colada. Maybe you imagined taking a road trip to a new city and working out of a local coffee shop or co-working space. Now think of this last year, how many of those trips did you actually get to take? The idea that you can work anywhere in the world as long as you have a strong wifi connection is certainly a perk and benefit to this lifestyle, however, with the demands of life we often forget to take advantage of it.

Continue Reading

Rebuilding the Feature 5 Grid to Create More Than a Comeback

WebDevStudios recently completed a challenging, yet very satisfying, WordPress project for The Comeback, a popular sports fan website. Among many duties, our team was tasked with rebuilding the Feature 5 grid functionality and extending it to support multiple grids, archive pages, and update styling. These changes involved creating a new “grid” CPT with the category taxonomy, refactoring the existing functionality into a plugin, and cleaning up how grids are created.

If you’re unfamiliar with the Feature 5 Grid, it is a grid at the top of a page the features or highlights five popular posts from various categories. It provides the editorial staff with the ability to curate these five stories to create a personalized experience for each site and page in the network.

cameron campbell

Cameron Campbell

Our main developers on this successful project were Cameron Campbell, Senior Frontend Developer/Designer, and Matt McAchran, Senior Backend Developer. Here’s their account of the obstacles they faced, the solutions they provided, and how they enhanced the overall experience of The Comeback.

 

 

Matt McAchran

 

“The old functionality was built directly into the theme; and since the grid was stored as an option, only one could exist at a time. The first step was to move the existing functionality into a plugin and refactor the code to store different grid attributes (posts, show on homepage, mobile settings) as postmeta. This enables multiple grids to be created in a scalable way.

 

 

The cross network searching for posts is powered by ElasticSearch and hits the global network alias, which points to all indices on the network. We only needed to store three pieces of information for each grid item (the location in the grid, ID of the post, and the ID for the blog the post belongs to).

The grid template was refactored to use a single template to allow for easy restyling and grids are cached on the front-end for performance.

The Comeback team wanted to also address the visuals of the Feature 5 grid. Some of the key goals were to provide a more visually complex/appealing experience for users in order to capture their attention and funnel them deeper into the site.

On the plugin side (in the Admin area), the grid needed to mimic the front end view as opposed to selecting posts from a meta box and only seeing the name of the post. This would allow their team to get a sense for the aesthetic of the grid and how images would work together. It also provided them with a way to quickly see if images needed to be edited in order to provide the aesthetic they were looking for. So we implemented the front end styles in an admin stylesheet and tweaked some of the proportions in order to account for any WordPress elements such as sidebars.

Some of other improvements we made to the front end of the grid were to bake in a more accessible experience, allowing the grid items to be tabbed through via screen reader for a better overall experience.”

You dream it. We build it. Let’s work together. Check out our portfolio, and when you’re ready to let WebDevStudios turn your big ideas into a big website, contact us.

Accessibility in Chrome DevTools

Overlay of Chrome logo and post title over stylized code snippets
Oh, the internet is a wondrous place – full of avenues to connect people, regardless of geography, language, or hardware.

Accessibility is so broad and the usership is so diverse. When building a WordPress theme, I encourage you to think about the benefits of removing any potential barriers from someone being able to access information. (Yay usability and inclusion!) As a reminder, the WordPress Accessibility Handbook is an excellent resource, which outlines minimum requirements you’ll need to meet in order to make your theme “accessibility-ready”.

There are several tools and resources out there that can assist in this process. Since my default browser is Chrome, I’d like to dive a bit deeper into how you can use Accessibility Developer Tools (a free extension from Google) to help out.

Note: “Accessibility” is often referred to as “a11y” and will be used interchangeably throughout this overview.

Running an a11y Audit:

Screenshop of Chrome Dev Tools 'Audit' tab with accessibility audit option availableSo, you’ve started to develop your WordPress theme and you want to check on how things are shaping up on the a11y side of things.

Once installed, you will want to select the “Audits” tab. In addition to the usual “Web Page Performance” and “Network Utilization”, there is now also an “Accessibility” option listed. By checking that option and running an audit (either for present state or on page reload, depending on preference), it will return a basic report from the current site.

The audit will (potentially) return a list from severe to passing of accessibility errors it calculated within your code. What is helpful about this is that it will show you the actual node in the DOM where this issue is taking place. It provides a link to the DevTools a11y wiki that relates to that issue, which in turn links you to the relevant area of the w3 spec.

Screenshop of Chrome Dev Tools 'Audit' tab with audit results listed

So much of accessibility documentation can seem quite dense and overwhelming. I know that for me, this really helps to break it down and give me a better idea of what should be happening within my code AND how to fix it.

Debugging Existing accessibility:

What if you’re trying to debug issues that have already been implemented that aren’t translating properly into actual functionality? Follow me once more to a magical place called “Accessibility Properties” that lives within your DevTools in the Elements panel. Just a note, depending on how your DevTools is laid out, it could be listed under the right-pointing double angle quotation mark ».

Screenshot of Chrome DevTools Existing Accessibility Properties List

Depending on which element you have selected, it will provide a list of properties that can help in validating ARIA roles/attributes and debugging colour issues, focus/visibility roles and text computation.

Focus and Visibility

This will list what is happening with tabindex and visibility. This is great to have consolidated in one place to double check properties. I’ve found it to be most helpful with elements like modals where something is focusable but behind other content and needs adjusting. Focus and visibility are two examples of things to be conscious when developing so people are able to navigate via keyboard. Again, remember to double check these and other WordPress standards as you’re developing your theme!

Colour Contrast

This will show you the current contrast ratio of your element. You will also see a suggested colour value pair to match the WCAG AA or AAA recommendation. WordPress aims to to maintain contrast at the WCAG AA level, which means a ratio of 4.5:1 for normal text and 3:1 for large text. And if you want to see what that would hypothetically look like, you can toggle to test it by clicking on the square icon to the right of the hex values.

Keep in mind that this also applies to a change of state (:focus or :hover) is there is no additional indicator like a text decoration change. Ideally, you’ll have worked out these things in the design phase but sometimes buttons or other smaller elements might fall under the radar. If you want to play with different shades, there are several contract checkers online (for example, here’s one by WebAIM).

ARIA Role and Attribute Validation

ARIA roles and attributes help screen readers understand the purpose of various sections of a web page by assigning certain regions. Certain landmarks should only be applied once per page.

Similar to what we see with styling properties, if it is invalid somehow or being overwritten, it will be struck out when inspected. This is useful to narrow down whether it’s a browser bug, a screenreader bug, or if the markup is just plain ol’ incorrect (as seen in the instance below for the aria-describedby attribute).

Screenshot of Chrome DevTools with an invalid ARIA property value listed

In my journey of learning more about accessibility, debugging has helped solidify how different components interact with attributes, which allows me to read up more and then use them more effectively in the future.

If you weren’t already familiar with these accessibility add-ons in Chrome, welcome to a whole new world! And if you were, is there anything I missed that is a total gem?

Thinking About Accessibility

As of late, I’ve been on a bit of a journey to become more adept and knowledgeable in the area of website accessibility. It’s not simply as easy as throwing a few extra alt or title tags here and there, or making sure you have a “Skip To Content” button. What I am finding is that there is a fundamental shift in philosophy required to tackle the challenges of accessibility.

Here, I’ll discuss some of those, as well as why we all need to become more mindful of the web in which we are working and the web for which we are building our sites, so that they can be used by all people regardless of their capabilities. Let’s start at the very beginning. What is web accessibility? W3C defines web accessibility as such:

Web accessibility means that people with disabilities can use the Web. More specifically, Web accessibility means that people with disabilities can perceive, understand, navigate, and interact with the Web, and that they can contribute to the Web. Web accessibility also benefits others, including older people with changing abilities due to aging.
– Introduction to Web Accessibility

This makes sense, right? We don’t want to limit the information on the web due to conditions beyond a person’s control. Instead, we should be ensuring that information is not only available and accessible to those with disabilities, but also presented seamlessly to those without disabilities. In essence, web accessibility should be invisible.

“Inclusive Design Patterns” by Heydon Pickering (and a bonus Ellen Ripley)

The very idea that creating fully accessible websites shouldn’t require any extra work didn’t occur to me until I started reading “Inclusive Design Patterns” by Heydon Pickering. What this means to me is that we need to shift the baseline for the websites we build. Accessibility isn’t (or shouldn’t be) a feature, an add-on, or a line item in a scope of work. It should simply be. It should be built into the core of our development process from the beginning, but to do so requires us to first build these thoughts and processes into ourselves.

Within the first few pages of the introduction of “Inclusive Design Patterns” the author writes:

The potential audience of a website or app is anyone human. Inclusivity of ability, preference and circumstance is paramount. Where people differ — and they always do — inclusive interfaces are robust interfaces.

This, and the other passages in the book, resonated with me quite a bit. It helped to take me from a place of, “We need to make sure we check to make sure the site is accessible,” to, “We need to set higher accessibility standards in our framework.”

Too often, I think, accessibility does become an afterthought because those of us who are building a site may not have any personal experience with a disability or condition which precludes us from using the site to its full potential. For this reason, it is easy for accessibility to become an “out of sight, out of mind” (for lack of a better phrase) issue. That, combined with just assuming that the website will magically be accessible to all users, is where we as developers find our pitfalls.

We can’t just assume that because a website looks good to and works well for us and the client that it is a flawless masterpiece, which works for all users. More often than not, this will likely not be the case. Perhaps we haven’t checked our color contrast levels, and there are some questionable light fonts on light backgrounds. Maybe some of the triggers on the site which should be buttons are actually spans or divs styled in such a way to act as buttons. It could even be as surface-level as heading tags not being used properly throughout a document, creating a confusing experience for a screen reader.

Whatever the case may be, these are all more than cases of code cleanup or QA. These are perfect cases for changing the way we look at the web, the way we think of the web, and the way we build the web.

Woman working at a laptop

Photo by #WOCinTech

Think about it like this: you are building a website for a service which, primarily, will be used by an audience who is very in-tune with the design and functionality trends of the day. You want a sleek design with sharp, modern fonts, which aren’t too in-your-face in regards to size and weight. Generally speaking, larger font sizes are associated with users who have a harder time reading smaller fonts. In fact, Barnes & Noble offer over 60,000 large print books to serve an audience who may have trouble reading the smaller print found in a standard book.

Ask yourself, if you are someone who doesn’t require a large print book to read comfortably, are you hindered in any way if you are, in fact, presented with a large print version of a novel, rather than a standard print version?

No, absolutely not.

Your experience is absolutely the same. You are reading the same words in the same language. The only difference is the size of the font being used.

This is the balance we need to strike with web accessibility. Should you design your site with smaller font sizes which sit on backgrounds whose contrast points are extremely low for the sole purpose of achieving a certain look or aesthetic? Or, could you take a few extra moments in the beginning of your design process to ensure that what you are designing is going to be large enough and displayed with enough color contrast to be easily read by all of your potential users?

In one of the above scenarios, you are limiting the number of users who can comfortably use your site. In the other, you aren’t placing limits on who can use your site. Or, at least, you are trying to ensure your site is presented without limitations to all users.

For me, beginning the journey into learning more about accessibility has been an interesting one, and one which is changing the way I look at, interpret, and develop. Accessibility does not, and should not, mean presenting a lower-quality or different experience to users due to a disability or condition. Instead, it should be that all users, regardless of their backgrounds or abilities, are able to experience the same content on the same web inclusively.

Evolution of CSS: Becoming a CSS Composer

I have been coding CSS almost daily for over 10 years. I don’t say that to try and establish supremacy, but merely to give some context to the subsequent observations. There are quite a few days I still feel more like a CSS poser.

Keeping with the Non-Traditional Traditions

I received my degree from a private liberal arts college, but only after a large and intentional vacation from formal education after high school. The college had a non-traditional, experimental program that was typically advertised toward “returning adults,” and this is where I chose to finally continue my formal education. It allowed me to not necessarily have a major, but a “focus” in communications, and specifically, an “interdisciplinary program with courses in multimedia theory and design.” So I was able to dabble a little in graphic design, 3D animation, music theory, and multimedia computer programming. This is where I was introduced to HTML, CSS, and Flash.

(Note: I did not take any computer science classes, which would have probably pointed me in a different trajectory career-wise. Instead, I was more fascinated with the visual, as opposed to the computational disciplines.)

It can be easy (although probably no easier than any other excuse) to have Imposter Syndrome when your formal education is founded on a multi-disciplinary degree, i.e. Jack of all trades, master of none. However, as some have pointed out…

“Learning isn’t a zero-sum activity.”

The Myth of the Myth of the Unicorn Designer” by Thomas Cole

Code Is Poetry

My first few jobs heavily involved HTML, CSS, and Flash, of course, as well as dabbling in many other languages and systems. However, I quickly gravitated toward WordPress when I was tasked to research alternative content management systems (CMS) for a state college. I started to become familiar with all the concepts that made up a good and bad CMS and was able to research where each private and open source solution lie on the feature vs cost spectrum. I became passionate about the idea of open source software, and WordPress was, and still is, at the forefront.

Code is poetry.

Today, the WordPress tagline “code is poetry” has become a mantra in my everyday work. So much of what we, as Front-End Developers, write relies on syntax, logic, and structure. Also, good code (as there is plenty of bad code and poetry) requires elegance and simplicity. The meaning with code and poetry can be both on the surface and simultaneously abstract.

Enough About ME!

So why am I giving you my entire bio? Because again, I think it is important to providing context to why I’m fascinated and passionate about composing CSS. In the upcoming posts, I’ll cover some key points along the history of CSS to try and demonstrate where I see CSS evolving. Remember, writing code is a multi-disciplinary venture, and one should never stop learning.

Stay tuned for the next post in this series:

  • Evolution of CSS – Part II: CSS Class Naming Conventions
  • Evolution of CSS – Part III: Overview of Tachyons