Telerik blogs

You have probably seen all these nifty Twitter Bootstrap style applications popping up. You know, the ones with the black header menus and blue buttons? If you haven't seen or heard of Twitter Bootstrap, it's a base CSS / UI framework that makes laying out your application quick and easy.

Why is layout so hard?

If you have ever built a web application, you know that the web has winformsbeen somewhat limited up until recently when it comes to laying out an application as opposed to text. This is because the web and web standards were originally designed for displaying documents, not applications.

As a result, laying out columns, fixing headers in a specific location and causing content to expand and collapse with the page has been a combination of creativity and downright brutal hack. Go ahead and do a search for "2 column CSS layout". There is an absolute bevy of different methods, war stories and survivor support groups. Some of the CSS out there gets really verbose and suddenly it all starts to feel like a bad idea.  WinForms starts looking pretty good again.

Enter CSS grids

To solve this problem, people started to create "grid" layouts for CSS.  This is just the concept of laying things out in rows and columns.  Of course, there is no "grid" HTML element and using tables has been deemed a crime against humanity. The new Flexbox HTML spec seeks to resolve some of this, but it's only available in the most modern of browsers.

The CSS Grid systems accomplish element layout in columns and rows by setting widths, margins and floats for div elements. The most famous of these grid systems has historically been the 960 Grid. So named because it is based on an application width of 960px.

More and more grid systems and base CSS packages began to emerge and there were a lot of them. Blueprint was quite popular for a while, and Skeleton earned quite a reputation as well. However none of these systems were widely embraced and most were limited in their function to just page layout.

Twitter Bootstrap

Twitter Bootstrap was introduced in August 2011 after a small group of developers at Twitter realized that the current state of affairs in grid systems had led to inconsistencies and high maintenance. As of the time of this writing, it is the most popular and forked project on GitHub - outpacing both jQuery and Node.

It is not just a CSS grid system, but an end-to-end framework for quickly getting an application up and running with a consistent look and feel. If you are like me and you are not really a designer, this is very good news.

Twitter Bootstrap with Kendo UI

One of the things that Kendo UI was not designed to address is application layout (with the exception of the mobile framework which does provide this).  This is where Twitter Bootstrap comes in. We like it so much that we created a new Bootstrap theme for Kendo UI so your widgets will look seamless when used with Twitter Bootstrap itself.

Getting started

Lets take a quick look at how to get your application running quickly with Kendo UI and Twitter Bootstrap. You are going to need Kendo UI and Twitter Bootstrap included in your page (of course).  After you download Kendo UI, you will want to download Twitter Bootstrap and include its JavaScript and CSS files. The minified CSS and JavaScript files are meant for production while the uncompressed files are intended for development.

Base markup for Kendo UI / Bootstrap application

<!DOCTYPE HTML>
<html lang="en-US">
<head>
  <meta charset="UTF-8">
  <title>Kendo Bootstrap</title>
  <link href="styles/kendo.common.min.css" rel="stylesheet">
  <link href="styles/kendo.default.min.css" rel="stylesheet">
  <link href="styles/bootstrap.min.css" rel="stylesheet">
</head>
<body>

  <script src="js/jquery-1.8.2.min.js"></script>
  <script src="js/kendo.all.min.js"></script>
  <script src="js/bootstrap.min.js"></script>

</body>
</html>

 

Fixed and Fluid layouts

Twitter Bootstrap has 2 main types of layouts - Fixed and Fluid.

Fixed Layout

The Fixed layout is based on an application width of 940px. It will be centered in the browser and will never be any smaller than 940px unless you include Bootstrap’s responsive CSS files. All of the CSS for the Fixed layout will be based on absolute pixel sizes. To create a Fixed layout, create a div with a class of container.

Fixed layout

<div class="container"></div>

 

Fluid layout

The Fluid layout will make your application as wide as the browser and will resize it as the browser is resized. In this layout, all the bootstrap elements are sized by percentage. A Fluid layout is created by adding a div with a class of container-fluid.

Fluid layout

<div class="container-fluid"></div>

 

Rows and columns

Once you have defined the container, the nuts and bolts of laying things out really boils down to rows and columns.

Rows

Rows are defined simply by adding a class of row to a div. This will create a row (surprise!) spanning the width of the container.

Columns

Columns are defined by adding a class of span[number] to a div, where [number] is an integer between 1 and 12 that defines how many columns you want to span. Bootstrap rows are broken up into 12 columns.

Sample Application

Lets create a sample application with our newfound Bootstrap skills. It's going to be a simple app that searches the Flixster movie database. We will use the Fixed layout, keeping in mind that this means our application will be 940px wide. In our case, we will create the "holy grail" 2-column layout. The left side will contain the search input and the right side will have the results which we will display in a Kendo UI ListView.

The first thing that we are going to need is one of those nifty Twitter Bootstrap headers.

The Header

You could use a Kendo UI Menu here if you wanted to, but using the Twitter Bootstrap Navbar is fine for most scenarios. Now we only have one page, but we could pretend we have a bunch more. For the sake of demonstration I'll include two links in the header. One that goes nowhere, and one that goes to the Rotten Tomatoes website.

This is where Twitter Bootstrap is going to immediately start to shine. We want to position the header at the top of our page. Using Bootstrap, this is trivial.

Basic bootstrap header

<div class="navbar navbar-static-top">
  <div class="navbar-inner">
    <div class="container">
      <a class="brand">
        <img class="logo" src="http://images.rottentomatoescdn.com/images/trademark/flixster-logo.png" /> 
        Search
      </a>
      <ul class="nav">
        <li class="active">
          <a href="#">Home</a>
        </li>
        <li>
          <a href="http://www.rottentomatoes.com">Rotten Tomatoes</a>
        </li>
      </ul>
    </div>
  </div>
</div>

 

You start with a div with a class of navbar and then create an inner container which will hold the items.  Notice also that I gave the top div a class of navbar-static-top.  This is because Navbar’s can appear anywhere.  That class fixes it at the top and scrolls with the content.  If you wanted a header that didn’t scroll with the content, you would use the class navbar-fixed-top.  All of the items are then wrapped in navbar-inner class and then  a container div which sets the width of the portion of the navbar that contains your items. The navbar itself will stretch the entire width of the screen in this scenario.

The brand anchor creates a nice slightly-larger area where your logo or site title would go. You usually make this a link as well that goes back to your home page.

Adding links/buttons to your Navbar is as easy as creating a unordered list with a class of navbar and then dropping some items and anchors in it. You will want to give the selected link a class of active which will make it appear "pressed".

Lets have a look at this app so far:

If you wanted to get that black header instead of the default white one, you can add a class of navbar-inverse to the top div with a class of navbar.

That gives us a really nice header with logo included per Flixster’s terms of use.

Laying out the body

Let's get down to laying out our 2-column masterpiece. Keep in mind that we are dealing with a 12 column system. This means that we need to figure out how many columns we want our left column to span and how many the right column should span. I think that 4 columns on the left is good, which means we can allocate the rest to the right-hand side.

2 Column layout

<div class="container">
  <div class="row">
    <div class="span4">
      <h3>Search</h3>
    </div>
    <div class="span8">
      <h3>Search Results</h3>
    </div>
  </div>
</div>

 

It's too big for me to embed in this page, so click here to see the results of that simple 2 column layout.

Bootstrap offers some really neat UI elements like rounded corners on TextBoxes and Buttons. We could just create a plain and boring input and button, but we can use some of the Bootstrap styling to make it look really nice.

Styled search box and button

<div class="form-search">
  <div class="input-prepend">
    <button data-bind="click: search" class="btn">Search</button>
    <input type="text" data-bind="value: term" class="span2 search-query" name="term">
  </div>
</div>

 

The form-search class will join our button and input together so it looks like one control. The input-prepend puts a flat edge on the end of the button and the front of the input. A class of input-append does the opposite, although you would need to move the button after the input for things to look right. You can see that I have a data-bind attribute for the input as I'm using a ViewModel to handle events and configuration.

The last step is to add our ListView. We'll add pagers at the top and bottom as well. We'll also need an item template, so I’ve added one in the code below.  We just need to display the movie poster, the title, the characters and the synopsis.

ListView And Pagers

<div class="span8">
  <h3 data-bind="html: title"></h3>
  <div id="results" data-bind="visible: hasResults">
    <div data-role="pager" data-bind="source: results" id="pager" data-auto-bind="false"></div>
    <div class="results row" data-selectable="true" data-pager="pager" data-auto-bind="false" data-scrolling="virtual" data-role="listview" data-bind="source: results" data-template="template"></div>
    <div data-role="pager" data-bind="source: results" id="pager" data-auto-bind="false"></div>  
  </div>
  <div id="empty" data-bind="invisible: hasResults">
    <p>No results...</p>
  </div>
</div>
<!— template for listview items –>
<script type="text/x-kendo-template" id="template">
  <div class="result">
    <div>
      <img class="poster" src="#: posters.original #" />
    </div>
    <div class="details row">
      <p class="title">#: title #</p>
      <p>
        # $.each(data.abridged_cast, function(index, item) { #
          # if (index < data.abridged_cast.length - 1) { #
            #:this.name#,
          # } else { #
            #:this.name#
          # } #
        # }); #
      </p>
      # if (data.synopsis.length > 0) { #
        <p class="synopsis"><b>Synopsis: </b>#: synopsis #
      # } #
    </div>
  </div>
</script>

 

You can see I've done some additional MVVM binding to make sure that the Search Results title stays updated with the term we are searching for. Also, I am hiding the entire search result set and displaying some empty data based on a boolean value in the ViewModel. MVVM really helps you maintain the UI by only having to worry about values in your code. Otherwise we would be wiring up a bunch of jQuery selectors and methods that would make our code start to smell bad.

JavaScript code

(function ($) {

  // define the flixster API url so we can use it later
  var flixster = "http://api.rottentomatoes.com/api/public/v1.0/movies.jsonp?apikey=2w6rma75ygrbrnubvu7g5asc";

  var viewModel = kendo.observable({
    title: "Search Results",
    term: null,
    results: new kendo.data.DataSource({
      transport: {
        read: {
          url: flixster,
          dataType: "jsonp"
        },
        parameterMap: function(options, operation) {
          // add the appropriate paramters the query string for flixster
          if (operation === "read") {
            return {
              q: viewModel.get("term"),
              page_limit: 10,
              page: options.page
            }
          }
        }
      },
      schema: {
        data: "movies",
        total: "total"
      },
      change: function() {
        // set the title and hasChanges property
        viewModel.set("title", "Search Results For '" + viewModel.get("term") + "'");
        viewModel.set("hasResults", this.view().length > 0);
      },
      serverPaging: true,
      pageSize: 10
    }),
    search: function(e) {
      // populate the listview when the search button is clicked
      this.get("results").read();
    },
    hasResults: false       
  });

  // bind the viewmodel to the body and create all widgets
  kendo.bind(document.body, viewModel);

}(jQuery));

 

And this is our finished product. JSFiddle puts some white space around the iFrame so that's why there is that bit of a buffer at the top.

I added a few styles for the ListView, but nothing dramatic. Mostly just spacing and removing the border because I don't like it for this application.

Work smarter not harder

Twitter Bootstrap is a great way to get really good cross-browser layouts in your application without much work required on your part in terms of CSS. I have never been a huge fan of CSS and I was always annoyed by the amount of CSS tom foolery it took to get some simple things done. Twitter Bootstrap wraps that nonsense up in a nice package and lets you concentrate on building your application.

Kendo UI works great with Twitter Bootstrap with the new Bootstrap theme. Grab a copy of Kendo UI And Twitter Bootstrap and take the pain out of the parts of application development that should be easy, but just aren’t.

Next week I'll take this same application and make it responsive so that it works on mobile devices. I'll show you how to use responsive design with Kendo UI and Bootstrap so that your application look amazing at any size.


Burke Holland is the Director of Developer Relations at Telerik
About the Author

Burke Holland

Burke Holland is a web developer living in Nashville, TN and was the Director of Developer Relations at Progress. He enjoys working with and meeting developers who are building mobile apps with jQuery / HTML5 and loves to hack on social API's. Burke worked for Progress as a Developer Advocate focusing on Kendo UI.

Comments

Comments are disabled in preview mode.