Monthly Archives: April 2016

5 Flexbox Techniques You Need to Know About

By Danny Markov


Flexbox is a CSS standard optimized for designing user interfaces. Using the various flexbox properties we can construct our page out of small building blocks, which then are effortlessly positioned and resized any way we want. Websites and apps made this way are responsive and adapt well to all screen sizes.

In this article we’re going to take a look at five flexbox approaches to solving common CSS layout nightmares. We’ve also included practical examples to showcase real life scenarios in which these techniques are applied.

1. Creating Equal Height Columns

This may not seem like a difficult task at first, but making columns that have the same height can be really annoying. Simply setting min-height won’t work, because once the amount of content in the columns starts to differ, some of them will grow and others will remain shorter.

Fixing this issue using flexbox couldn’t be easier, as columns created this way have equal heights by default. All we have to do is initialize the flex model, then make sure the flex-direction and align-items properties have their default values.

.container {
        /* Initialize the flex model */
	display: flex;

        /* These are the default values but you can set them anyway */
	flex-direction: row;    /* Items inside the container will be positioned horizontally */
        align-items: stretch;   /* Items inside the container will take up it's entire height */
<div class="container">

	<!-- Equal height columns -->


To see a demo of this technique, you can head out to our Easiest Way To Create Equal Height Sidebars article, in which we create a responsive page with a sidebar and main content section.

Equal Height Sidebar with Flexbox

2. Reordering Elements

A while ago, if we had to dynamically change the order of some elements, we would probably try some CSS hack, quit in frustration, and go do it with JavaScript. With flexbox however, this task comes down to applying a single CSS property.

It’s called order and just like its name everything about it as straightforward as possible. It allows us to swap any number of flex items and change the sequence in which they appear on the screen. It’s only parameter is an integer determining the position of that element – lower numbers mean bigger priority.

	display: flex;

/* Reverse the order of elements */

	order: 3;

	order: 2;

	order: 1;
<div class="container">

	<!-- These items will appear in reverse order -->

	<div class="blue">...</div>
	<div class="red">...</div>
	<div class="green">...</div>


The order property has many practical uses. If you want to see some of them, you can check out this article, where we use it to build a responsive comment section.

Responsive Comment Section With Flexbox

Responsive Comment Section With Flexbox

3. Horizontal And Vertical Centering

Vertical centering in CSS is one of those problems that makes us ask ourselves: How is such a trivial thing still so complicated to do? And it really is. If you google vertical centering CSS, an infinite amount of different techniques will pop up, and most of them will involve tables or transforms – things that aren’t designed for making layouts.

Flexbox offers an easier solution to the problem. Every flex layout has two directions (X axis and Y axis) and two separate properties for their alignment. By centering both we can position any element right in the middle of its parent container.

	display: flex;

	/* Center according to the main axis */
	justify-content: center;

	/* Center according to the secondary axis */
        align-items: center;
<div class="container">

	<!-- Any element placed here will be centered
		 both horizonally and vertically -->



To see this tecnhique in action and read more about it, you can go to our quick-tip article on the same topic.

Horizontal And Vertical Centering With Flexbox

Horizontal And Vertical Centering With Flexbox

4. Creating Fully Responsive Grids

Most developers rely on a CSS frameworks when creating responsive grids. Bootstrap is the most popular one but there are hundreds of libraries that can help you with this task. They usually work well and have tons of options, but tend to be quite heavy. If you are a DIY person or don’t want to implement a whole framework just for the grid, flexbox has you covered!

A row in the flexbox grid is simply a container with display:flex. The horizontal columns inside it can be any amount of elements, setting the size of which is done via flex. The flex model adapts to the viewport size, so this setup should look fine on all devices. However, if we decide there isn’t enough space horizontally on the screen, we can easily turn the layout into a vertical one with a media-query.

	display: flex;

/* Classes for each column size. */

	flex: 1;

	flex: 2;

@media (max-width: 800px){
		/* Turn the horizontal layout into a vertical one. */
		flex-direction: column;		
<div class="container">

	<!-- This column will be 25% wide -->
	<div class="col-1">...</div>

	<!-- This column will be 50% wide -->
	<div class="col-2">...</div>

	<!-- This column will be 25% wide -->
	<div class="col-1">...</div>


You can check out a variation of this technique in our The Easiest Way To Make Responsive Headers Quick Tip.


Responsive Header With Flexbox

5. Creating The Perfect Sticky Footer

Flexbox has an easy solution to that problem as well. When building pages that include a sticky footer, by doing the whole thing in flex elements we can be sure that our footer will always stay at the bottom of the page.

Applying display: flex to the body tag allows us to construct our entire page layout using flex mode properties. Once that’s done the main content of the website can be one flex item and the footer another, which makes it really easy to manipulate their positioning and place them exactly where we want.

    height: 100%;

    display: flex;
    flex-direction: column;
    height: 100%;

   /* The main section will take up all the available free space
      on the page that is not taken up by the footer. */
   flex: 1 0 auto;

   /* The footer will take up as much vertical space as it needs and not a pixel more. */
   flex: 0 0 auto;
	<!-- All the page content goes here  -->

	<div class="main">...</div>

	<!-- Our sticky foooter -->



You can find more information about this technique in our article The Best Way To Make Sticky Footers.

Sticky Footers With Flexbox

Sticky Footers With Flexbox


All mainstream browsers (except IE 9) now support the flex layout mode, so unless you have a user base that prefers retro Microsoft browsers, it’s safe to say that flexbox is production ready. If you haven’t used it by now, we highly recommend that you try it!

We hope you found our CSS tips useful and that they will help you build better and more robust responsive layouts. Enjoy!


Freebie: 4 Great Looking Pricing Tables

By Danny Markov


In this post we present to you four templates for pricing tables. They are ready to use and absolutely free, so you can implement them in your projects right away. Just like the rest of your freebies, these tables have no external dependencies and are made up entirely out of vanilla HTML and CSS.

The Pricing Tables

The idea behind these tables is to quickly sum up and present the different pricing options or subscription plans available for your services. They need to showcase all the important info customers have to be familiar with, in order to choose and purchase a product.

You can get the zip archive containing all our templates from the Download button near the top of the page. With their help you can effortlessly add good looking pricing tables to your website without making almost any changes to your code. Just grab the HTML, add the corresponding CSS from the assets folder, and substitute our dummy content with your own. That’s it!

Our pricing tables don’t require any libraries and their CSS is self-contained, so they are guaranteed to work without causing anything in your page to break.

Pricing Table Clean

Free for Commercial Use

You have all rights to customize and use these templates. They are 100% free and can be implemented in both personal and commercial projects, no attribution required (our license page). Enjoy!


5 Practical Examples For Learning Vue.js

By Danny Markov


We’ve already covered Angular.js and React in previous articles but there is a new frontend library that we think is worth your time. It’s called Vue.js and it has gathered a large community of enthusiastic developers.

The philosophy behind Vue.js is to provide the simplest possible API for creating real-time, two-way data binding between the view (HTML) and the model (a JavaScript object). As you will see in the following examples, the library holds true to that idea and working with it is effortless and enjoyable, without compromising on any functionality.

Getting Started

The easiest way to install Vue.js is to simply include it with a tag at the end of your HTML’s body. The entire library is located in a single JavaScript file which you can download from the official website or import directly via CDN:

<script src=""></script>

If you want to use the library in a Node.js project, vue is available as an npm module. There is also an official CLI, which allows users to quickly setup their whole project based on premade template builds.

Below are five editors containing example apps we’ve built for you. The code has lots of comments and is separated in tabs for each file, making it really easy to follow. The editors have Vue.js built-in so don’t be afraid to experiment. Also, you can download an archive containing all the examples from the Download button near the top of this article.

1. Navigation Menu

To kick things off we’re going to build a simple navigation bar. There are a few basic components almost every Vue.js app need to have. They are:

  • The model, or in other words our app’s data. In Vue.js this is simply a JavaScript object containing variables and their initial values.
  • An HTML template, the correct terminology for which is view. Here we chose what to display, add event listeners, and handle different usages for the model.
  • ViewModel – a Vue instance that binds the model and view together, enabling them to communicate with each other.

The idea behind these fancy words is that the model and the view will always stay in sync. Changing the model will instantly update the view, and vice versa. In our first example this is shown with the active variable, representing which menu item is currently selected.

(Play with our code editor on

As you can see working with the library is pretty straightforward. Vue.js does a lot of the work for us and provides familiar, easy to remember syntax:

  • simple JavaScript object for all the options
  • {{double brackets}} for templating
  • v-something inline attributes for adding functionality directly in the HTML.

2. Inline Editor

In the previous example our model had only a couple of predefined values. If we want to give the users the ability to set any data, we can do two-way binding and link together an input field with a model property. When text is entered, it is automatically saved in the text_content model, which then causes the view to update.

(Play with our code editor on

Another thing to note in the above code is the v-if attribute . It show or hides a whole element depending on the truthfulness of a variable. You can read more about it here.

3. Order Form

This example illustrates multiple services and their total cost. Since our services are stored in an array, we can take advantage of the v-for directive to loop through all of the entries and display them. If a new element is added to the array or any of the old ones is changed, Vue.js will automatically update and show the new data.

(Play with our code editor on

To display the prices in a correct format we use one of the available filters that come built-in with Vue.js. They allow us to lazily modify the model data – in this case the currency filter is perfect, as it adds a dollar sign and proper number decimals. Just like in Angular filters are applied using the | syntax – {{ some_data | filter }}.

4. Instant Search

Here we will create an app, that exhibits some of the articles on our website. The app will also have a search field allowing us to filter which articles are displayed. There is a filterBy filter available, but it doesn’t do exactly what we need it to, so instead we will be creating our own custom filter.

(Play with our code editor on

The input field is bind to the searchString model. When text is entered the model is instantly updated and passed on to the searchFor filter. This way we can create a real-time search without having to worry about rendering or setting up event listeners – Vue.js handles all that!

5. Switchable Grid

In our last example we will demonstrate a common scenario where a page has different layout modes. Just like in the previous app we will be showing a list of articles from stored in an array.

By pressing one of the buttons in the top bar you can switch between a grid layout containing large images, and a list layout with smaller images and text.

(Play with our code editor on


There is a lot more to Vue.js than what we’ve showcased in these examples. The library also offers animations, custom components and all sorts of other features. We recommend you check out the excellent official documentation which is full of information and helpful snippets.

Having troubles deciding whether Vue.js is the right library for your project? The following links will be of great help to you:

  • An official, detailed comparison with other frameworks – here.
  • TodoMVC – a website where the same app is recreated with many different frameworks.
  • Our articles where we’ve done similar examples using React and Angular.js.

Thanks for reading!


The need for multi-platform npm packages

By Axel Rauschmayer

In this blog post, I argue that it should be possible to have multiple implementations of the same npm package (same name, same version).

The problem

At the moment, when you write an npm package, you can specify on what platforms it works, via the package.json property engines. For example:

    { "engines" : { "node" : ">=0.10.3 <0.12" } }
    { "engines" : { "npm" : "~1.0.20" } }

That means that you can only have a single implementation per package. However, there are use cases for multiple implementations of the same package:

  • For Node.js you can already use many ES6 features. For browsers, you should stay 100% ES5.
  • There are Node.js-specific polyfills of Browser APIs. For example, node-fetch polyfills the fetch API.
  • The module bundler Rollup needs the ES6 module format to achieve its superior file size savings. But that format doesn’t work anywhere else, yet.

An idea for a solution

I see two possible solutions:

  • Allow the same package (same name, same version) to exist multiple times, targeting different platforms via property engines.
  • Allow packages with multiple versions of the properties main and bin.

The latter solution could lead to package.json files that look like this:

    "engines": [
            "node": ">=0.10.3 <0.12",
            "main": "./es5/index.js",
            "bin": { "foo": "./es5/bin/foo.js" }
            "ecmascript": ">=2015",
            "main": "./es2015/index.js",
            "bin": { "foo": "./es2015/bin/foo.js" }

Mixing selection criteria (meta-data) and data is not ideal. This is an alternative:

    "engines": {
        "node >= 0.10.3, node < 0.12": {
            "main": "./es5/index.js",
            "bin": { "foo": "./es5/bin/foo.js" }
        "ecmascript >= 2015": {
            "main": "./es2015/index.js",
            "bin": { "foo": "./es2015/bin/foo.js" }

The selection criteria should include:

  • Browsers vs. Node.js
  • Supported ECMAScript version
  • Module format: native (ES6) vs. CommonJS vs. AMD

Other solutions


I have only seen a brief mention of npm ecosystems, so far. I’m not sure how exactly they would work, but it sounds like they could solve the problem I’ve described here.


jsnext:main is a custom property that Rollup uses to point to an ES6 module version of the main file. The problem with this approach (apart from the less-than-ideal property name) is that it can only handle a single alternate implementation with a fixed format.

More information on jsnext:main:


The package manager jspm extends package.json with, among others, the property format whose value can be esm (for ECMAScript module), amd, cjs or global.

Additionally, you have the option to nest jspm-specific properties via the custom property jspm. For example:

        "name": "my-package",
        "jspm": {
            "main": "jspm-main"

More information: “Configuring Packages for jspm”.


Feedback welcome! Did I miss anything? Are other (better?) solutions out there?

Source:: 2ality

Quick Tip: Get to Know the CSS Object Fit and Position Properties

By Danny Markov


In this post we are going to talk about two CSS properties that not a lot of web developers know about. They are called object-fit and object-position and both have to do with styling images and video.

First, we’ll show you how to use them and go into detail covering all the important specs. After that, we’ve prepared for you a tiny demo app, in which you can play around with the properties and see them in action. Let’s begin!


With object-fit we can address how an image (or video) stretches or squeezes itself to fill it’s content box. This is needed when a photo we have has a different size or aspect ratio from the place we’ve designated for it in a layout.

Traditionally, to solve this problem one would create a div and set background-image and background-size. Modern CSS, however, allows us to simply add an image tag, set it’s source as usual, and then apply object-fit directly to the image selector:

img {
    width: 100%;
    object-fit: cover;

The possible values it receives are:

  • fill (default) – The width and height of the image match those of the box. Most of the times this will mess up the aspect ratio.
  • cover – The image keeps its aspect ratio and fills the whole box, parts of it are cropped and won’t be shown.
  • contain – The image keeps it aspect ratio and enlarges/shrinks to fit inside the box.
  • none – Original size and aspect ratio.
  • scale-down – Displays like one of the above, depending on which produces the smallest sized image.


This property defines where inside the container the image will be positioned. It takes two numerical values, one for the top-bottom axis and another for the left-right axis. These numbers can be in percentages, pixels or other measuring units, and can be negative. Some keywords such as center, top, right, etc. can be used as well.

By default an image is positioned in the center of a container, so the default value is:

img {
    object-position: center;
    /* which equals */
    object-position: 50% 50%;

Playground Demo

Reading about CSS properties is one thing, testing them out for yourself is a whole different story. Below is a demo page which will help you get the hang of object-fit and object-position in no time. In it you can test the properties and give them different values to see how they can transform a media object. Don’t be afraid to open up DevTools as well.

Browser Support

Following the tradition of all cool CSS features, the browser support for object-fit and object-position is rather inconsistent and in this case it’s IE and Edge that offer no support at all. While waiting for all Microsoft browsers to adopt the two properties you can use this polyfill which fixes the issue nicely. Also, it’s always a good idea to set a background color to all image containers as a fallback.


The object-fit and object-position properties can be of great help when building responsive web pages. They are easy to use and remember, and do their job perfectly. We are sure that once IE and Edge adopt them, they will quickly become a part of every web developer’s CSS toolbox.

Thanks for reading!


Trees of Promises in ES6

By Axel Rauschmayer

This blog post shows how to handle trees of ES6 Promises, via an example where the contents of a directory are listed asynchronously.

The challenge

We’d like to implement a Promise-based asynchronous function listFile(dir) whose result is an Array with the paths of the files in the directory dir.

As an example, consider the following invocation:

    .then(files => {

One possible output is:


The solution

For our solution, we create Promise-based versions of the two Node.js functions fs.readdir() and fs.stat():

    readdirAsync(dirpath) : Promise<Array<string>>
    statAsync(filepath) : Promise<Stats>

We do so via the library function denodify:

    import denodeify from 'denodeify';
    import {readdir,stat} from 'fs';
    const readdirAsync = denodeify(readdir);
    const statAsync = denodeify(stat);

Additionally, we need path.resolve(p0, p1, p2, ···) which starts with the path p0 and resolves p1 relatively to it to produce a new path. Then it continues with resolving p2 relatively to the new path. Et cetera.

    import {resolve} from 'path';

listFiles() is implemented as follows:

    function listFiles(filepath) {
        return statAsync(filepath) // (A)
        .then(stats => {
            if (stats.isDirectory()) { // (B)
                return readdirAsync(filepath) // (C)
                // Ensure result is deterministic:
                .then(childNames => childNames.sort())
                .then(sortedNames =>
                    Promise.all( // (D)
               => // (E)
                            listFiles(resolve(filepath, childName)) ) ) )
                .then(subtrees => {
                    // Concatenate the elements of `subtrees`
                    // into a single Array (explained later)
                    return flatten(subtrees); // (F)
            } else {
                return [ filepath ];

Two invocations of Promise-based functions are relatively straightforward:

  • statAsync() (line A) returns an instance of Stats
  • readdirAsync() (line C) returns an Array with filenames.

The interesting part is when listFiles() calls itself, recursively, leading to an actual tree of Promises. It does so in several steps:

  • First, it maps the names of the child files to Promises that fulfill with Arrays of grandchild paths (line E).

  • It uses Promise.all() to wait until all results are in (line D).

  • Once all results are in, it flattens the Array of Arrays of paths into an Array (line F). That Array fulfills the last Promise of the chain that starts in line C.

Note that synchronous programming constructs are used to compose Promises:

  • The if statement in line B decides how to continue the asynchronous computation.
  • The map() method in line E is used to make recursive calls.

Helper function flatten()

The tool function flatten(arr) concatenates all the elements of arr into a single Array (one-level flattening). For example:

    > flatten([[0], [], [1, [2]]])
    [ 0, 1, [ 2 ] ]

It can be implemented like this:

    function flatten(arr) {
        return [].concat(...arr);

Further reading

Source:: 2ality

15 Interesting JavaScript and CSS Libraries for April 2016

By Danny Markov


In this post we bring you our monthly collection of web dev libraries, frameworks and plugins that we’ve recently come across. Each one of them is handpicked and we’ve tried our best to select tools that are useful, reliable, and built with the latest trends in mind. Enjoy!

Office UI Fabric

An official Microsoft open-source project, this is a framework for building web apps that follow the look and feel of desktop MS Office programs. It works in a similar fashion to Bootstrap: HTML and CSS components, a responsive grid, and a lot of jQuery add-ons.



This library allows developers to add unique peel-off stickers to their web projects. Any element on the page can be transformed into a sticker and when somebody hovers on it a realistic animation is applied. This library has no external dependencies – only vanilla JavaScript and smooth CSS3 animations are used.



Cash is a lightweight alternative to jQuery. It provides the same syntax and many of the popular jQuery methods and features, rewritten using modern JavaScript, resulting in a library only 8kb in size (compared to the 32kb of jQuery). If you don’t need to support old IE and think jQuery has become too big through the years, give Cash a try.


Popper is a JavaScript library for adding tooltips and popovers to HTML elements. It offers a ton of customization options and is fully modular with separate plugins for every feature. Popper is fairly complicated compared to other tooltip libraries, while still being very easy to use and small in size.


Bootstrap Material Datepicker

A Material Design themed date and time picker built on top of jQuery and Momentjs. To use it you just have to bind it to an input field, set the options you need, and decide if you want a date picker, time picker or both. When a user clicks on the input, a modern looking dialog will pop up containing an Android inspired calendar or clock.


Material Kit

A free UI kit that combines the familiar syntax of Bootstrap with the modern looks of Google’s Material Design. There are other similar projects such as Material Design for Bootstrap and Bootswatch Paper Theme, but Material Kit, being the newest, has learned from the older frameworks and offers a polished product with neat styles and lots of components.



Skeleton is a responsive CSS library that will turn a bland HTML project into a stylish one with practically zero effort. Unlike Bootstrap and other UI frameworks where you have to add a ton of classes to the HTML, Skeleton requires just a handful of classes and automatically styles everything else. The library is extremely lightweight, featuring just a simple 12 column grid and the most basic components.



As most web developers know, the default HTML checkboxes and radio buttons look horrible and are a huge pain to customize correctly across all browsers. That’s why there are countless libraries that help you do this, and iCheck is probably the coolest of them all. It offers several unique themes, is heavily customizable, and even has IE6+ and mobile browser support.



Stylefmt is a PostCSS module that automatically formats CSS and SCSS stylesheets. You can write your own format rules or use the standard ones to make the CSS of your project look the same, no matter who wrote it. Stylefmt is available everywhere – as a CLI, a node.js module, and as a plugin for popular text editors or task runners.



Turn any text on your web page into a twitter share button. Just add a span with the right attributes and InlineTweet will automatically turn the selected text into a link. When someone clicks on it, it will generate a tweet, including hashtags and a URL going back to your page.



SmoothState is a brave project that turns your ordinary web sites into single page apps. The way this works is it prevents links from opening new pages and instead injects them into the current one using AJAX, while manipulating the browser history and URLs, as if the page has changed. Add a cool loading animation while the AJAX request finishes and you’ve got yourself a SPA.


In just 700 bytes gzipped, nanobars enables web developers to quickly create fully functional progress bars. The library has a very tiny pool of methods and options but gives you exactly what you need – a function to initialize a new bar, and another one to change it’s progress.


Image Blur

This is a jQuery plugin that allows deveopers to add a blur filter to images. Usually this can be done using the CSS filter property, but the browser support for it is still pretty bad. By using this plugin you can make sure that the blur effect will work equally well in all mainstream browsers.



With TypeIt you can create animation effects that will display a string as if it is being typed out. The library offers all the features you might think of such as looping animations, controlling the typing speed, replacing a string with a new one, and others.



CSS animations are way more memory efficient than their JavaScript counterparts, but can still slow down a web page if they are not done correctly. Applying transition effects to the width, height, top or left of an element causes a redraw of the DOM and occupies the GPU. Instead, the transform property should be applied and the guys behind Repaintless have used this to create the most buttery-smooth animation library possible.


Tracking unhandled rejected Promises

By Axel Rauschmayer

In Promise-based asynchronous code, rejections are used for error handling. One risk is that rejections may get lost, leading to silent failures. For example:

    function main() {
        .then(() => console.log('Done!'));

If asyncFunc() rejects the Promise it returns then that rejection will never be handled anywhere.

Let’s look at how you can track unhandled rejections in browsers and in Node.js.

Unhandled rejections in browsers

Some browsers (only Chrome at the moment) report unhandled rejections.


Before a rejection is reported, an event is dispatched that you can listen to:

    window.addEventListener('unhandledrejection', event => ···);

The event is an instance of PromiseRejectionEvent whose two most important properties are:

  • promise: the Promise that was rejected
  • reason: the value with which the Promise was rejected

The following example demonstrates how this event works:

    window.addEventListener('unhandledrejection', event => {
        // Prevent error output on the console:
        console.log('Reason: ' + event.reason);
    function foo() {

The output of this code is:

    Reason: abc


If a rejection is initially unhandled, but taken care of later then rejectionhandled is dispatched. You listen to it as follows:

    window.addEventListener('rejectionhandled', event => ···);

event is also an instance of PromiseRejectionEvent.

The following code demonstrates rejectionhandled:

    window.addEventListener('unhandledrejection', event => {
        // Prevent error output on the console:
        console.log('Reason: ' + event.reason);
    window.addEventListener('rejectionhandled', event => {
    function foo() {
        return Promise.reject('abc');
    var r = foo();
    setTimeout(() => {
        r.catch(e => {});
    }, 0);

This code outputs:

    Reason: abc

Further reading

The Chrome Platform Status site links to a “Promise Rejection Events Sample” that contains an explanation and code.

Unhandled rejections in Node.js

Node.js does not report unhandled rejections, but it emits events for them. You can register an event listener like this:

    process.on('unhandledRejection', (reason, promise) => ···);

The following code demonstrates how the event works:

    process.on('unhandledRejection', (reason) => {
        console.log('Reason: ' + reason);
    function foo() {

Further reading

The Node.js documentation has more information on the Event unhandledRejection.

Source:: 2ality

Freebie: 6 Excellent Paginations and Tabs

By Danny Markov


In this installment of our freebie series, we’ve prepared for you a collection of 6 templates for pagination menus and tab controls. We’ve built them without relying on any frameworks, so adding your own content or customization is as easy as editing a bit of HTML and CSS.


For paginations we’ve come up with two designs – one standard with page numbers and next/prev buttons, and the other with next/prev buttons and a dropdown. Both of them are simple and clean, so they should look great in almost any layout.

Basic Pagination Template


Here we give you the option to choose between four different designs. We know that creating working tabs from scratch can be a bit tedious, so we’ve also included a short jQuery snippet in them to enable switching between the tab pages.

Underlined Tabs Template

Underlined Tabs Template

How to use

To use any of the templates from the demo, follow these steps:

  1. Grab the zip archive from the Download button near the top of the page and extract it.
  2. Open the .html file for the template you want, copy the code inside the and paste it in your project.
  3. The styles are located in separate CSS files for each design. You can find them in the /assets/css folder. We’ve made sure our CSS is self contained and won’t break anything in your own styles.
  4. Replace our placeholder content with your own and add more buttons/tabs if you need to.

Free for Commercial Use

All of the templates are completely free and can be used in both personal and commercial projects. Don’t worry, you don’t have to include any form of attribution either! Enjoy 🙂