Error Handling and HTTP Redirects

Default Apache Error Page

There are few things I dislike more than seeing a website handle basic errors with a default error page. There are a few UI/X considerations to think about when handling redirects to tell the user they’ve encountered an error. The case I think about most often includes a user being linked to a page that no longer exists. A default page will tell them only that the page doesn’t exist. It won’t tell the user if (a) the site also no longer exists, (b) if the page exists elsewhere, or (c) how to find what they’re looking for. Additionally, the default error page gives no easy way to navigate to the rest of the site. It doesn’t include a search form to look for the content they tried to access, nor does it provide a way to find out if the link they were given just had a typo.

How I Fix This

There are a lot of ways to deal with HTTP redirects. The way I do it is with Apache – your server’s configuration may be a little different if you’re on a different platform.(*) Basically, I tell my server that if there is an HTTP error, to redirect to a certain page, called error.php, in the root directory of my site.

...
ErrorDocument 400 /error.php
ErrorDocument 403 /error.php
ErrorDocument 404 /error.php
ErrorDocument 405 /error.php
ErrorDocument 408 /error.php
ErrorDocument 500 /error.php
ErrorDocument 502 /error.php
ErrorDocument 504 /error.php
...

This custom page has two main components: a variable to store the redirect type (from $_SERVER['REDIRECT_STATUS']) and a keyed array with the codes set as the key and values being an array with one value for the name of the code and another value with the description.

$status = $_SERVER['REDIRECT_STATUS'];
$codes = array(
  400 => array('400 Bad Request', 'The request cannot be fulfilled due to bad syntax.'),
  403 => array('403 Forbidden', 'The server has refused to fulfill your request.'),
  404 => array('404 Not Found', 'The page you requested was not found on this server'),
  405 => array('405 Method Not Allowed', 'The method specified in the request is not allowed for the specified resource.'),
  408 => array('408 Request Timeout', 'Your browser failed to send a request in the time allowed by the server.'),
  500 => array('500 Internal Server Error', 'The request was unsuccessful due to an unexpected condition encountered by the server.'),
  502 => array('502 Bad Gateway', 'The server received an invalid response while trying to carry out the request.'),
  504 => array('504 Gateway Timeout', 'The upstream server failed to send a request in the time allowed by the server.'),
);

I use the template of my site’s index.html file to import the necessary styles and code, then hit the user with a full page message, explaining, in detail, the code and nature of the error. I add in a few actions they can take, too: go back to where they came from or search for what they were looking for. I use jQuery to get the last URL (if there is one), and set the link on the page to it. I also change the link text depending on if it was a referred link or not.

  if (document.referrer && $("#btn").length) {
    $("#btn").attr("href", document.referrer);
    $("#btn").text("Go Back");
  } else {
    $("#btn").attr("href", "index.html");
    $("#btn").text("Go Home");
  }

The HTML is really simple. I’ll omit the <head> and just leave you with the main section

<div class='error' id='redirect'>
    <h1>Error: <?php echo $codes[$status][0]; ?></h1>
    <p class='lead'>
      <?php echo $codes[$status][1]; ?>
    </p>
    <a class='dg-close' href='' id='btn'></a>
    <div class='row center-align'>
        <form role='search' method='get' id='searchform' class='searchform' action='searchform.php'>
            <h3>Try A Search</h3>
            <div class='input-field'>
                <label class='screen-reader-test' for='s'>Search For:</label>
                <input type='text' name='s' id='s' />
                <input type='submit' name='submit' value='Search' class='dg-close' />
            </div>
        </form>
    </div>
</div>

There are different (and arguably better) ways to do this, but this is how I handle HTTP redirects to provide a consistent UI and give the user more information than just “There was an error”. This solution solves 2/3 problems presented: it tells the user the site exists (just by being a non-default page), and it shows the user how to find what they’re looking for. (The functionality to suggest pages will be in another post.)
A little extra thing that can be done: in ‘error.php’, a short bit can be added to email yourself a an error report, including the URL that triggered it, the redirect status and code, and any other relevant information.

Want to see this in action? Click here to throw an error.


* If you’d like to provide different language samples, I’d love to include them! Just shoot me an email!

Development Software and Tools

Tools

I’ve been building websites for the better part of 3 years now. In that time, I’ve switched operating systems three times, I’ve used dozens of text-editors, hundreds of tools, and many, many browsers and devices. I don’t think I’ve ever written down what I’ve used, aside from the brief mention on Twitter every once in awhile. So, I’m gonna start doing just that.
I’m gonna break down my development tools and software here, then when something changes, whether I add to or remove something from the pile, I’ll update this article (without removing what was replaced, if anything was). So, let’s go!

Text Editor

I think the text editor is the heart of every developer’s tool kit. It’s where in most of the work of development is done, and can lend a huge hand in speeding up (or slowing down) your website development game. When I first started looking for editors, I wanted something that was free, good looking, open-source, and had good documentation. I still want all those things, but I want more than just that short list. I also want something I can customize, with a nice set of default features but can also be built on, and a good community behind it.
For those reasons, I hang with Atom.io, ‘the hackable text editor’.
I like Atom because of all the things I mentioned above: it’s free, good looking, open-source, has good documentation, it’s customizable (read: hackable), has nice default features, is expandable, and has a pretty good community behind it.
I run Atom with a few (non-default) packages:

  • Remote-sync by yongkangchen: FTP in the editor. Works from a single JSON config file. The only thing I don’t like about this is that there isn’t a default keybinding.
  • Atom-minify by armin-pfaeffle: Minification of CSS and JS files, with an option to minify on save. Minify in file or directly to another file
  • Autoprefixer by sindresorhus: Adds browser prefixes to CSS properties/attributes. No need to find and manually update prefixes. Comes with lots of options
  • HTML-Head-Snippets by joshbuchea: Josh Buchea’s HEAD is a really good resource for solid SEO and general <head> content. This package lets the developer add snippets into their file right from Atom, eliminating a Copy/Paste step.
  • Linter by atom-community: A base linter. You do need to install specific packages for your language, but it does really well and all of the packages are robust and work like a charm.

The other thing I like about Atom is that it just looks really damn good. The dark theme is what I went to right away and the syntax highlighting and colors, oh man, everything just feels like the exact thing I want to look at when coding.


Browsers

Among other important tools in a web developer’s kit lie the browsers they use. I’m not going to break down everything, but I will break down what browsers I use and for what purposes:

  • Chrome: Chrome is my daily driver. I use it for all my normal browsing, in addition to some testing. I do most of my layout testing in Chrome and a lot of the initial design in Chrome as well. I always disable plug-ins while first testing, but once I’ve got things going how I like, I re-enable plug-ins that are known to disrupt UI (post coming about that soon, I swear!).
  • Safari: I rarely use desktop Safari for normal browsing, but I use it daily for testing. I usually open up Safari when I’m done with initial layout/design elements in Chrome. I’m constantly testing on my iPhone for mobile Safari, from first layout to final touches.
  • Firefox: I don’t use Firefox for anything other than testing. I don’t like it. That being said, it can bring up a lot of issues that aren’t found in other browsers, so it’s important to test in. I usually don’t open it until I’ve gotten to putting on final touches.
  • Mobile Chrome: I really dislike Android, not for the design or UI, but because of the inconsistencies across hardware platforms. For that reason, I’ve never intentionally bought an Android device. Until I realized I needed to, about a month ago. So I started using mobile Chrome and the Android browser to test alongside the rest of my flow. The tablet I have is always sitting on my desk, ready to look at whatever. It also serves a double purpose as my media device, so music is always streaming from it. Helps with the mood.
  • Anything else: Unless there is a real use case, I don’t test in other browsers. I use a Mac so testing in IE and Edge are annoying, at the least, and difficult, at the worst. But I do run a Windows VM and once I’ve started staging the site I do a quality check in IE (back to 12) and Edge. I do, also, quality check on Firefox and Chrome on Windows.

Virtual Server

For all of my local testing (pre-staging), I use MAMP (Mac Apache MySQL PHP). It’s really easy to set up, requires VERY little maintenance, and comes with everything that I need: Apache, MySQL, and PHP. It also comes with the ability to connect different devices on my local network, and when I have it set up correctly, I can remote into my network from a client’s office (or the coffee shop) to see what’s being worked on at home. This makes pre-staging testing a breeze and makes local development kinda fun!
I don’t know what else is out there, to be honest. As far as virtual server software goes, my understanding is that MAMP is the cream of the crop, baby. If there is anything else and you’d like to see me try it, shoot me a message at nate@natenorthway.com.


Sass

I use the Sass preprocessor to make writing CSS a lot easier and a bit more programmatic. Atom plays nicely with it and it’s really easy to learn how to use.


I think that just about wraps up everything that is worthy of a breakdown. I use a lot more tools, but not all of them are worthy of a full breakdown. I’m happy to list them, but why I use them should be evident if you visit the link I’ll provide

Software

Most of this software is free, but if it’s not, it’s really cheap or worth the price


Services

Most of these services are free to some extent, but most of it has a paid option that is vastly superior to the free option. I really suggest that with the free stuff you strongly consider their paid alternatives. Google Suite, CodePen, and Browser Stack are the services I’m happy to pay for because the functionality they provide is unmatched. Look into what’s right for you, though.


Hardware

I was motivated to list my hardware. I think it’s important to note that hardware is pretty interchangeable. What I have is not the best setup. It’s the best setup for me. Some software is very necessary. Like, a text editor, a virtual server, and an FTP client, I would say are necessary parts. Which ones you use may not be so much. The same goes for hardware. A computer is absolutely necessary, but multiple testing devices probably aren’t, though they’re nice to have. That being said, here’s what I’ve got.

MacBook Pro (Retina, 13 inch, Early 2015)

I’ve got a 13″ 2015 rMBP with 128gb flash storage, 8GB RAM, and the 2.7GHz Intel Core i5. I run El Capitan. I love this computer. It’s powerful enough for what I do, the battery lasts all day through meetings, it looks great, the keyboard and trackpad feel great, and it’s pretty durable, too.
I don’t like two things about it. First off, it doesn’t like to read my hard drive. I’ve been told this is an OS level issue, but I’m hesitant to upgrade to Sierra. Secondly, when I stress it, it tells me. I’ve never had a laptop that heats up or gets as loud as this one. But those two compromises are much smaller than the compromises I’ve had to make with most of the previous laptops I’ve owned.

Accessories

  • Acer 23.5″ Monitor
  • WD 1TB MyPassport for Mac (entertainment, backups)
  • Logitech Wireless Mouse
  • Kingston 16GB Flash Drive (jump drive?)
  • PS3 Controller for gaming

Other Hardware

There is other hardware I use nearly daily, mostly for research, communication, or testing purposes.

  • iPhone 7
  • NeuTab N7 Pro (cheap Android Powered tablet for testing, reading/comms on-the-go)
  • Samsung 19″ Monitor (more testing)

In addition to all that crap, I also always carry a notebook and a couple nice pens. Nothing beats jotting down ideas. Don’t throw that paper away. On slow days, I look through these notebooks (I have 7 on my bookshelf now) for inspiration and add lost ideas to my Trello ‘ideas’ board (after deliberation).
I also use these notebooks for initial meetings with clients. Unless absolutely necessary, when meeting clients, I keep my laptop in my bag and engage with the client, writing down specifics in the notebook and translating that to a Google Document later.

This list is incomplete. I use more software and services, but I don’t use them every single day. As I come across pieces that I’ve missed, I’ll add more to this article.

Accessibility

Accessibility is absolutely necessary in today’s day and age. It provides a chance for everyone, without bias, to interact with a website and obtain the information they need or want in that moment. Lack of accessibility can lead to higher bounce rates, users being unable to obtain information, and a negative effect on your bottom line. There are many cases to be made in support of accessible design.
Recently, I had to field a call from my mother, a 50 year old with almost total vision loss, who needed help filling out an online form, which was necessary for her to complete a task related to money management. The form wasn’t compatible with her screen reader, so she needed my help to finish it. Though I have no problem navigating screens with my mom, people with disabilities (or other needs for accessible information) who don’t have a person to assist them face some problems. The need for accessibility is higher than ever, with more than 2 billion internet ready devices existing as of 2013[1]; a number that only grows.

Case 1: Everybody Uses Smartphones

Nearly 2/3 of adult americans use smartphones[2]. That number is higher in youth, meaning that as the years go on, more and more adults are using smartphones. If literally every person were to try to use a non-accessible website, imagine how quickly that website will die when 2/3 of them can’t access it. The fact that so much of the population’s access to the internet is through their cellphone should speak enough to the reason implement accessibility in web design.

Case 2: Disabled Users

Much like my mother, disabled people need to use the internet to complete necessary tasks that they otherwise may not be able to complete. Some things like banking forms, job applications, applications for assistance, communicating with other people, and aligning transportation can not be completed without the internet. The nature of the internet provides a unique opportunity to remove certain dependencies for people. For example, a person who has a speech impediment can now clearly communicate with a health care provider through a web chat session to clearly state symptoms they are experiencing. These advantages do not come without responsibility, though.

Case 3: Limited Access To Technology

Take into consideration the fact that some people have limited access to technology. Folks in impoverished communities, people with limited access to decent education, and people dependent on public facilities to access the internet may be using older technologies to accomplish what they need to do. It’s important to keep these people in mind when designing your site, not only because it’s necessary to your business, but also because these users are just as important as any other user. Designing your website to work on these devices/in these softwares is necessary to the continuation of your product/service.

Case 4: Money

Yep. There, I said it. Making your thing accessible brings you more money than not. Consider this: Nearly 1 in 5 people have a disability in the US[3]. 20% of the population. That means that 1 in 5 people accessing any given website have a disability (on average). If it costs $1 to join your site, 100 people access your site, and it isn’t accessible, you’ll soon be refunding $19, and be preparing to either refund more in the future and to not get that money from your users who require your website be accessible.

But it’s not all about money

If money is your only motivator, web design probably isn’t for you. However, I’m not here to judge. If you’re reading this, you care enough, I guess. Either way, money shouldn’t be your only motivator to creating accessible sites. Keep in mind that real people are on the internet. The fact that bits represent people on a computer screen may obscure personal interactions on the internet, but I promise you, real people are having real problems created by a lack of accessible websites. I want the whole world to be happy with the internet because my experience with the internet has been mostly positive and I want everybody to benefit from it’s existence. My way of giving back is through accessible design. I hope you take these things into consideration and feel the same way, or at least see the need for accessible design.

The Differences Between IDs and Classes

To style HTML with CSS, there are a myriad of selectors that can be used. The
first, and most basic, of these selectors is the element selector, which
selects all elements of that type. To be more specific with selectors, IDs and
classes can be used, and are probably the most commonly used CSS selectors.
Though you can achieve similar things with both, Classes and IDs are way
different.

Starting Simply

The first course or tutorial you read about CSS probably introduced the element
selector. This selector targets all elements of that type. So, when you plug this
into your CSS:

p {
  font-size: 16px;
}

All the <p></p> elements on your page will have a font-size of 16px. The
element selector has a low level of specificity. That is, usually, there are
multiple elements of a type on every page. Element selectors are useful when
there are only a few elements on a page, or in tools like resets or (in some
cases) layout tools. When more specificity is needed, classes and IDs help
target specific elements or types of elements.

Classes

Say, for example, you want some <p></p> elements to have differently colored
text. You might add a class attribute to the HTML with the value blue-text,
which would be targeted in CSS with the class selector, like so:

.blue-text {
  color: blue;
}

That targets all elements with the class attribute of blue-text. Classes are
useful for reusable code. Utility classes, like align-left or button, are
good candidates for class names. They are also useful for grid systems. Class
selectors have a higher degree of specificity than element selectors.

IDs

IDs are used in more than just CSS. They can be targeted in URLs, for example.
Appending an element’s ID to the end of the URL will bring that element to the
top of the browsing context. You can give that a shot now by clicking this
link, which appends #bottom to the URL. There is a <div></div> at the bottom
of this post with the ID of bottom. That should now be at (or near) the top of
your window.

IDs are also used in JavaScript and jQuery (and a lot of other front end
technologies). They are used to watch specific elements for events, provide an
easy way to target an element, and make it easier to know what you’re doing as a
developer. Take the following HTML into consideration:

<button id='btn-1' class='btn'>Action 1</button>
<button id='btn-2' class='btn'>Action 2</button>
<button id='btn-3' class='btn'>Action 3</button>

In CSS, these buttons could all be targeted with the same class selector. However,
since they each serve their own purpose, in jQuery, we’ll be targeting each
individually. There are a few ways to go about this, though. The first is a
roundabout way:

$("body:nth-child(1)").on('click', function() {
  alert("Action 1");
})

$("body:nth-child(2)").on('click', function() {
  alert("Action 2");
})

$("body:nth-child(3)").on('click', function() {
  alert("Action 3");
})

This is all well and good, but it requires (a little) thinking, creates (a little)
bloat, and could be done easier with IDs:

$("#btn-1").on('click', function() {
  alert("Action 1");
})

$("#btn-2").on('click', function() {
  alert("Action 2");
})

$("#btn-3").on('click', function() {
  alert("Action 3");
})

This makes our code much leaner and cleaner and easier to understand. We could
whittle it down more (even to just 3 lines of code), but that’s for another time.
In CSS, IDs are the most specific selector that is not a pseudo-class (like
:nth-child or :not(selector)). They are meant to target non-generic elements,
so you should never have two elements on your page with the same ID.

The Differences

The differences between classes and IDs are similar to vehicle Make and Model.
Every vehicle Ford makes has a few of the same attributes: they all have the
‘Ford’ badge on the front, they all have the same rims, they all have the same
FOB, and they all have the same airbags inside. The make is just like a class:
it defines a set of attributes for a number of different items/elements.

IDs are like models, each model of Ford cars have different attributes, like the
Mustang may have a monster V8 engine, but the Focus has a 4-banger with an
electric motor. The Focus also has 4 doors, but the Mustang has two (and it’s a
convertible!).

The Similarities

Whether an element is targeted by it’s class or ID name in CSS doesn’t change
how the element is styled. Both IDs and Classes can be used to style your page.

The Takeaway

IDs and Classes are extremely useful. Element selectors are the most vague selectors,
and class and ID selectors help target elements more specifically. IDs are the most
specific type of selector. IDs are used in other contexts, too, like linking to
specific elements in a page and being used in jQuery, JavaScript, and other
front-end technologies.

Bottom div!

Content Security Policy

As a full-stack dev, I try my best to keep up on front and back end technologies,
methods, and techniques. One of the many ways I do this is by utilizing my time
through reading, watching, and listening. I have, at any time, 3-5 books I’m reading,
a slew of videos on my watch list, and a myriad of podcasts that I listen to which
help me stay aware of the numerous things that are relevant to me as a web dev.

One of the podcasts I listen to is Shop Talk Show. Aside from the various tips,
tricks, and information that I’ve absorbed from the podcast, I’ve also learned
how to talk about what I do through Chris and Dave. They constantly get
interesting questions and go down rabbit holes. In the http://shoptalkshow.com/episodes/237-rapidfire-73/” target=’_blank’>Last episode (#273), they get
into Content Security Policies. It’s something that I don’t hear people talk about
often and though it’s something I’ve always used and been aware of, I don’t think
I’ve ever written or posted about it. So I wanted to offer up a blog post.

The goal of a Content Security Policy (CSP) is to prevent Cross-Site Scripting
(XSS).
There are a lot of ways it does this, which we’ll get into. How it works
is by directing the browser to enforce the policies set forth through HTTP directives.
The CSP sets a whitelist of content sources which the browser understands will be
the endpoint of requests made from the page. The browser uses this whitelist to
block requests made to content sources outside of the whitelist. Keep in mind that
CSP is not meant to be the only defense against XSS, just another tool in the
box. You should utilize other tools (like input sanitization) in addition to a
CSP to prevent XSS
.

How It works

When a browser makes a request to your website, the CSP should be provided with
the HTML as an http-header. It’s part of the header because it’s hard to forge.
The policy itself is a set of directives which instructs the browser to only
render or execute content from the whitelisted sources.

What A CSP Contains

CSPs contain source directives, or, a list of sources for specific content types.
Here’s the list of those:

  • default-src: the default source of all content types. This is used when a source
    type is not defined. When a more specific source type is defined, it overrides the
    default source.
  • base-uri: sets the URLs that can appear in the <base> element.
  • child-src: sets the URLs for workers and embedded frame contents. For example:
    child-src https://youtube.com would allow embedding videos from YouTube but
    not from other origins. This should be used instead of the deprecated
    frame-src directive.
  • connect-src: sets the endpoints to which the page can connect via XHR, WebSockets,
    and EventSource.
  • font-src: sets the origins that can serve fonts.
  • form-action: sets the endpoints for <form> submissions.
  • frame-ancestors: sets the sources that can embed the current page. This applies
    to <iframe>, <frame>, <embed>, and <applet> tags. It can’t be used in
    <meta> tags and applies only to non-HTML resources.
  • img-src: sets the origins from which images can be loaded.
  • media-src: sets the origins from which video and audio can be loaded.
  • object-src: sets control over Flash and other plug-ins.
  • plugin-types: sets the types of plug-ins pages may invoke.
  • report-uri: specifies a URL where a browser will send reports when a security
    policy is violated. This can’t be used in <meta> tags.
  • style-src: sets the origins from which stylesheets can be loaded.
  • script-src: sets the origins from which scripts can be loaded.
  • upgrade-insecure-requests: instructs browsers to rewrite URL schemes, changing
    HTTP to HTTPS. This is for websites with large amounts of old URLS that need to
    be rewritten.

Why It’s Needed

By default, directives are open, meaning that all sources and endpoints are
allowed. It’s important to restrict the sources and endpoints because attackers
can use unknown sources to perform XSS.

How To Implement

To specify sources, there are a few valid values:

  • *: All origins/endpoints are valid
  • data:: Allows data: URIs to be used as a content source. This is insecure.
    An attacker can inject arbitrary data: URIs. This should be used sparingly and definitely not
    for scripts.
  • http://example.com: All domains of example.com using the http:// OR https://
    schemas are valid.
  • https://example.com: All domains of example.com using ONLY the https://
    schema are valid.
  • http://*.example.com: All subdomains of example.com using the http://
    OR https:// schema are valid.
  • https://*.exmple.com: All subdomains of example.com using ONLY the https://
    schema are valid.
  • mail.example.com:433: All attempts to access port 433 on mail.example.com are valid.

Keywords are also used. When using keywords, single quotes are required.

  • 'none': An empty set. No URLs are allowed.
  • 'self': The origin from which the originating document is served, including the
    same URL scheme and port number.
  • 'unsafe-inline': Allows the use of inline resources (i.e. <script> elements or javascript: URLs)
  • 'unsafe-eval': Allows the use of eval() and similar methods for creating
    code from strings.

Notes on the Above:
http:// can redirect to https://, but https:// will not redirect to http://.
If a port number isn’t specified, the default port will be used. If no schema is
specified, the same on used to access the originating document is assumed. Allowing
a domain does not include it’s subdomains, but does allow extensions (i.e. https://example.com will
allow https://example.com/test to be used but not https://test.example.com).

Setting the CSP HTTP Header

The CSP’s best delivery method is through HTTP headers. Here are some examples how:

Apache config

Header set Content-Security-Policy "default-src 'self';"

# IIS Web.config
<system.webServer>
  <httpProtocol>
    <customHeaders>
      <add name="Content-Security-Policy" value="default-src 'self;'" />
    </customHeaders>
  </httpProtocol>
</system.webServer>
# nginx conf file
add_header Content-Security-Policy "default-src 'self';"

A lot of languages and frameworks support adding the headers programmatically, such
as PHP or Node.js.

header("Content-Security-Policy", "default-src 'self'");
# node-js
request.setHeader("Content-Security-Policy", "default-src 'self'");

CSP <meta> tag

There is also an HTML5 <meta> tag.

<meta name='Content-Security-Policy' content="default-src 'self'; script-src https://google.com 'self'; ...; ...;" />

This tag goes in the <head> of the page.

Syntax

When setting directives, you should always include multiple URLs in one directive
(if multiple URLs are necessary). For example, if you want to allow images from
fbcdn.com AND images.google.com, setting it across two directives would render
whichever came first useless because the latter would override the former.

img-src https://fbcdn.com;
img-src https://images.google.com;

The second directive overrides the first directive.

Instead, multiple URLs should be declared in one directive, i.e.

img-src https://fbcdn.com https://images.google.com;

Specific directories are not allowed, i.e. https://fbcdn.com/images. If you want
to use a specific directory, just use the web root (i.e. https://fbcdn.com)

Other Resources

I use a lot of resources to write my articles and make sure everything is up to snuff.
Here are some great articles/documentation:
Level 2 Spec on W3C
SitePoint article
Mozilla Dev Article
HTML5Rocks Article

In Conclusion

We reviewed Content Security Policies, what they are, why they’re needed, what
they do, how to implement them, and the syntax.

Disappearing Nav

Disappearing navbars are found all over the web. This feature may seem like an
advanced technique, but it’s actually really easy to implement.

With just a little bit of JavaScript, you can have a disappearing navbar.

The logic

When the user scrolls down, the navbar fades out. When the user scrolls up, the navbar fades in. Easy, right? We need to take into account the page position
when the user starts to scroll. This helps determine if the direction of the
scroll is up or down. So, when the user starts to scroll, we need to
save the pageYOffset, or, the distance from the top the page is scrolled. Then,
we need to figure out if the user has scrolled up or down. To figure that out,
we check if the current position is greater than the last saved position. If
the current position is greater, that means that the user has scrolled down. If
the position is less, the user has scrolled up. Let’s code this out:

var lastPosition = 0;
window.onscroll = function() {
  var position = window.pageYOffset;

  if (position > lastPosition) {
    //the user has scrolled down
  } else {
    //the user has scrolled up
  }
}

That’s the bulk of our code. Now, we just need to hide and show the header. There
are a few different ways to do this. I’m using CSS classes, hidden and active,
with different opacities. Here is that code:

.hidden {
  transition: opacity .4s ease;
  opacity: 0;
  pointer-events: none;
}
.active {
  transition: opacity .4s ease;
  opacity: 1;
}

This adds a little bit of a transition and makes whatever is in the header
non-interactive while it’s hidden. Putting it all together is simple: when the
user scrolls down, the header’s class should be hidden, and when the user scrolls
up, the header’s class should be active. Here’s the code:

var lastPosition = 0;
window.onscroll = function() {
  var position = window.pageYOffset;

  if (position > lastPosition) {
    //the user has scrolled down
    document.getElementById("header").className = "hidden";
  } else {
    //the user has scrolled up
    document.getElementById("header").className = "active";
  }
}

Of course, this snippet only works with navbars that are fixed to some side of
the screen. I think this effect looks great on mobile and really frees up a lot
of screen real estate. Here’s your demo:

See the Pen Disappearing Navbar by Nate Northway (@the_Northway) on CodePen.

Add jQuery

You can get a little more into this with jQuery. The first thing I did was
replace the <header>‘s hidden and active class names with the jQuery fadeIn()
and fadeOut() effects. This handily also takes care of disabling interaction
in the header. The jQuery code is not that different. We should also adjust the
threshold so that a small amount of scrolling up does not trigger the menu –
this is important when thinking of more sensitive input devices like a touch screen
or a track pad. That’s just a little bit of logic. If the difference between the
last position and current position is greater than 20, we know that the user has
scrolled up a lot and quickly, so we should show the navigation.
Here is that demo, with the relevant
jQuery below:

$(document).ready(function() {
  var lastPosition = 0;
  $(window).on('scroll', function() {
    var position = $(window).scrollTop();

    if (position > lastPosition) {
      $("#header").fadeOut();
    } else if (lastPosition - position > 20) {
      $("#header").fadeIn();
    }

    lastPosition = position;
  })
})

Really Get Into It

The next thing you can do to bring this effect to being fully fleshed out is
changing the opacity based on the amount that the user has scrolled. To do this,
we have to take into account the <header>‘s opacity before scrolling,
decrement it, and set the new opacity to that decremented amount. If the new
opacity is 0 (or less), we should also disable pointer-events. Here is that
code:

...
  if (position > lastPosition) {
    opacity = getOpacity($("#header").css("opacity"));
    $("#header").css({"opacity": opacity});
    if (opacity <= 0) {
      $("#header").css({
        "opacity": 0,
        "pointer-events": "none"
        });
    }
  }
...

function getOpacity(x) {
  var rate = .25;
  return x - rate;
}

This decrements the opacity by .25 every time the user scrolls. Remember to
set pointer-events to auto on scroll up, otherwise, your users will not be able
to interact with your navbar after scrolling down or refreshing. Here is that demo:

See the Pen Disappearing Navbar (with jQuery) by Nate Northway (@the_Northway) on CodePen.

I had fun building this set of demos. Hopefully it can come in handy on your site!

Edit:

I posted this on Reddit
and got a good reply from /u/alejalapeno:

All iterations of this need a debounce/threshold put on them because a 1px scroll-up on a trackpad should not re-summon the menu. It needs a threshold like 10-20 pixels scrolled-up at least.

I added that in as a condition to the if statement in the JS. It checks if the
difference between lastPosition and position is greater than 20px before
showing the navbar. I’ve already updated all the sample code above and on in the
CodePen demos, but here’s a closer look at it:

if (position > lastPosition) {
  document.getElementById("header").className = "hidden";
} else if (lastPosition - position > 20) {
  document.getElementById("header").className = "active";
}

Browser Defaults

Browser defaults are generally rather sensible and malleable, but there are a
few things I strongly urge you not to mess with.

Chrome, Firefox, Safari, Opera –
all of these browsers have their own way of rendering HTML elements. From margins
to padding to font-sizes, they determine how a page will render without CSS
telling it what to do. Though each might do it differently, all browsers employ
some styling for native UI components.

Ubiquity

Though each vendor slightly differs in default stylings, there are a few
ubiquitous native UI components that stick around – not just in browsers, but in desktop
and application environments, too. A good example of what I’m talking about is
the focus ring on input fields, especially those that are text based.

Examples of Focus Rings in Chrome, Firefox, and Safari

See? Ubiquitous. There is a reason for that.

For Reasons

Not only do focus rings appear in web browsers, but in a lot of applications, too.
Keyboard users depend on them to determine where they are on the page. Mobile
users also find the focus rings helpful when navigating forms. Knowing which of
the multiple input boxes is the selected one makes sure they know what to enter
on their keyboard. And before you say ‘but they clicked it, they should know’,
most mobile browsers have a ‘next’ button that works just like ‘tab’ on a
keyboard. People with vision impairment also utilize the focus ring to help them
navigate the page.

It’s important to keep some of these native UI components around in
your website/app/tool/thing because users may be lost without them. Restyling is
OK, but removing is a big step to take to inconvenience your users.

…if an alternative focusing style isn’t made available, the page will be significantly less usable for people who primarily navigate pages using a keyboard, or those with reduced vision who use focus outlines to help them navigate the page.
HTML Living Standard, section 6.4.6

The HTML Living Standard
really has a lot to say about the focus property. And that’s just one property. There
are dozens (if not more) of more ubiquitous default styles out there. Sara Cope
compiled a great list
of CSS properties that are a part of native UI components (there are a lot more than 12).

Restyling

Restyling defaults is a different story. I understand that the mediocre grays that
Chrome and Firefox offer may not match your color palette, and that’s fine, go
ahead and restyle. In fact, I encourage it. But please, don’t remove native UI
components.

I like to write after reading some stuff:
TJ VanToll wrote a great article on the focus outline.
Baymard Institute wrote an interesting article on restyling Native UI components.
The Government dabbles in writing about UI Design Basics.

Box-Shadow

I’m seeing some debate on prefixing box-shadow (and other properties). This is
my solution to figuring out browser prefixes.
This
recent article
by appendTo discusses the CSS Box-Shadow property. It
does a decent job explaining the values and what they do, but they superfluously
suggest prepending browser prefixes to the box-shadow property.
In my last post, I discuss
browser-prefixing as a general topic, and suggest a few tools to help determine
if you need prefixes, namely, Autoprefixer. It’s a great tool with lots of
different possible applications, including plug-ins for Atom
(the text editor I use) and Sublime Text.

CSS Bloat

The problem I have with unnecessary prefixing is bloat. CSS bloat can be a huge
problem for mobile users, and for anyone on slower connections. Browser
prefixing can increase a property’s weight by a lot. In this case, the unprefixed
box-shadow property is 51 bytes unminified, 43 minified. The prefixed version
(what appendTo suggests) is 134 bytes unminified and 118 bytes minified. The
difference is not negligible. 83 unminified bytes and 75 minified bytes is a
lot.

I understand the need to cater to your users, I really do, because I have to do
it, too. But unnecessarily using browser prefixes is a disservice, and that’s why
I very strongly suggest using the tools I mentioned in my last post (and above).
Not only will they save you time but they will also save your users bytes.

Browser Prefixes

Responsive design makes your design work across screen sizes. But what about working across browsers? Responsive design is only part of the solution to making your site accessible to all platforms. Another part (among many) is using browser prefixes and testing your solutions.

What Is A Browser Prefix?

A browser prefix is a string of text that targets specific browsers at the beginning of a CSS property. They are surrounded by hyphens (-) and help vendors use no-yet-standard or working-draft versions of CSS properties. Some browsers implement different versions of properties and their prefixes help developers implement similar behavior across platforms. Browser prefixes look like this:

.item {
  -webkit-transition: all .5s ease;
  -moz-transition: all .5s ease;
  -o-transition: all .5s ease;
  transition: all .5s ease;
}

Why Are Prefixes Needed? What About Standards?

Standards sometimes take a while to implement, and, are often tested over long periods of time. So, until a standard is declared, prefixes help the testing/development process and allow developers to use new properties.

How Do I Know What Properties Need Prefixing?

After a while, you start to remember, but there are a lot of ways to check if a property needs prefixing. ShouldIPrefix is a go to, as well as CanIUse. If a property discussed on CSS-Tricks needs prefixing, it’s mentioned in the article. Another tool to help you prefix is Autoprefixer

Testing

Yeah, don’t forget to test. After you’ve designed your site, loaded in your browser prefixes, compressed your images, css, js, whatever, pull your smartphone out and navigate to wherever that site lives. I’d be surprised if it looks as good as it did on desktop right from the get go. Chances are, you’ll need to do some adjusting. During the design process, I’m constantly resizing my browser window, moving to different platforms and browsing contexts, and testing my local sites with BrowserStack. This helps me make sure that not only is my site going to work on different screen sizes, but also in different browsing contexts.

Borders, Pseudo Elements, and Folds

I’ve recently fielded a lot of questions about Ribbons and Folds done with pure CSS. It’s a lot more than just a few lines of CSS, though.
A lot more. Understanding how borders and pseudo-elements work is not only a good nugget of knowledge to have, but also necessary to understanding CSS folds. To kick off this article, I’m going to walk you through how borders work in CSS. Then we’ll talk about pseudo elements. Finally, I’ll talk about how to use borders and pseudo elements to create stunning effects like folds!

Borders

To understand folds, you should first understand how borders work in CSS. Basically,
where each border meets, there is a diagonal line. I’ve built a pen to exemplify that.

See the Pen CSS Borders by Nate Northway (@the_Northway) on CodePen.

As you can see in the demo, each border is just a triangle. This is how CSS triangles are made. An element with
3 transparent (or white) borders, and one colored border. Now, we can take this a step further.

Pseudo Elements

Pseudo Elements are very cool. They can do all sorts of cool, useful, entertaining, and handy stuff.
One really useful example is tooltips. A pseudo-class is basically a phantom state or specific characteristic of an HTML element that can be targeted with CSS. Common pseudo classes include :link, :visited, :hover, and :nth-child. But there are a lot more.



A few things to note: pseudo-classes are always preceded by a colon (:). After the colon is the pseudo-class’
name, then, perhaps, a value in parentheses, like in :nth-child(1).

Pseudo-elements are like bonus elements for every HTML element on the page. Though they can be manipulated with CSS, they aren’t a part of the document tree, nor the DOM. So, they are only accessible with CSS.

Single Colon vs. Double Colon

I’ve seen a little debate over single vs. double colon. I use both, just to be safe, but some people who are more
careful about their byte usage might bite my head off for suggesting that. But, a more honest answer might be: it doesn’t matter.

The double colon is a part of CSS3. It differentiates pseudo-elements like ::before and ::after from pseudo-classes like :hover and :active. All browsers support the double colon syntax except IE8 and below. But
it is good to know that some, like ::backdrop, only accept the double colon syntax.

Personally, I use both, like this:

button:active,
button::active {
  -webkit-outline: none;
  -moz-outline: none;
  outline: none;
}

I think this keeps me honest.

CSS Generated Content

Content can be generated through CSS by using the content: ""; property with a pseudo-element. The content
might be plain text or it might be a glyph, but usually, it it just a container, used to create a nice looking ‘thing’ (like a ribbon or page fold).

Keep a few things in mind when using CSS generated content, though. CSS generated content will not be accessible to screen readers, and, it will not be selectable. CSS Generated content should only be used for non-vital stuff, like a ribbon or page fold.

What we’ll be using CSS pseudo-elements and classes for

Since we can manipulate the boxes created by pseudo-elements, we can use them to create ribbons, tooltips, and page folds. Basically, it’s another div we get to work with without adding to the HTML markup. We’re going to be working with ::before and ::after for this snippet.

Using :before

I really like this snippet. Having documentation, a blog, or a page about coding means that you’ll have
a lot of code samples on your pages. It’d be really nice to be able to label the languages being used, wouldn’t it? With :before, you can! Here’s the HTML markup.

<code rel='html'>
  <h1>Hello, World!</h1>
</code>

And the CSS:

code {
  display: block;
  background: #efefef;
  color: #292929;
  padding: 10px;
  font-family: monospace;
}
code:before {
  content: attr(rel);
  display: block;
  width: 100%;
  height: 20px;
  font-family: 'Sans-serif';
  background: #292929;
  color: #efefef;
}

Put it all together in a demo:

See the Pen Styling Code Blocks by Nate Northway (@the_Northway) on CodePen.

Cool! So now, you can see pseudo-elements taking up space in the real world. Groovy!

Creating A Page Fold

Creating a page fold, ribbon, and a myriad of other effects comes naturally, now. What we have to do is combine
our knowledge of borders and psuedo-elements to create the fold. So, imagine you have an element that needs a page fold. You know the its width, its height, and background color of its parent element. Groovy! You can create a fold.

What we have to think of is the anatomy of a fold. Two triangles of different colors, pushed into a corner of an element. The triangle furthest from the center of the parent element has the color of it’s parent element’s parent element – probably white, but maybe not. The triangle closest to the center of the parent element has a darker (or lighter) shade of its parent element’s background color.

We’ll use borders to create the triangles. Remember earlier, when we discussed how borders meet at angles and how two colored borders form a triangle? Well we’re going to use that property to create our ‘fold’. We’ll start by defining our parent element, then, the borders and position of our pseudo-element.

div {
    background: green;
    width: 100px;
    height: 100px;
    margin: 0 auto;
    position: relative;
    top: 20px;
}

div:after,
div::after {
    width: 0px;
    height: 0px;
    position: absolute;
    margin-top: 80px; //parent container height - pseudo-element border width
    margin-left: 80px; //parent container width - pseudo-element border width
    content: "";
    border: 10px solid white;
    border-top-color: #004d00;
    border-left-color: #004d00;
}

Depending on where you want your fold (top left, top right, bottom right, bottom left), you may need to change up the border declarations and positioning a bit. Here’s the code for that:

//top right fold
div:after,
div::after {
    width: 0px;
    height: 0px;
    position: absolute;
    margin-top: 0;
    margin-left: 80px; //parent container width - pseudo-element border width
    content: "";
    border: 10px solid white;
    border-left-color: #004d00;
    border-bottom-color: #004d00;
}

//top left fold
div:after,
div::after {
    width: 0px;
    height: 0px;
    position: absolute;
    margin-top: 0;
    margin-left: 0;
    content: "";
    border: 10px solid white;
    border-right-color: #004d00;
    border-bottom-color: #004d00;
}

//bottom left fold
div:after,
div::after {
    width: 0px;
    height: 0px;
    position: absolute;
    margin-top: 80px; //parent container width - pseudo-element border width
    margin-left: 0;
    content: "";
    border: 10px solid white;
    border-top-color: #004d00;
    border-right-color: #004d00;
}

And here is the result of that.

See the Pen zKRbJj by Nate Northway (@the_Northway) on CodePen.

I got inspiration to write this post from this Reddit thread.
I used a lot of resources to supplement my lack of word-juggling capabilities, mostly
this CSS-Tricks article and a wonderful article
on Smashing Mag. I also
look at this other CSS-Tricks article a lot, just because it’s good inspiration juice.