Posts Tagged 'Html'

November 6, 2012

Tips and Tricks - Pure CSS Sticky Footers

By now, if you've seen my other blog posts, you know that I'm fascinated with how much JavaScript has evolved and how much you can do with jQuery these days. I'm an advocate of working smarter, not harder, and that maxim knows no coding language limits. In this post, I want to share a pure CSS solution that allows for "sticky" footers on a web page. In comparing several different techniques to present this functionality, I found that all of the other routes were overkill when it came to processing time and resource usage.

Our objective is simple: Make the footer of our web page stay at the bottom even if the page's content area is shorter than the user's browser window.

This, by far, is one of my *favorite* things to do. It makes the web layout so much more appealing and creates a very professional feel. I ended up kicking myself the very first time I tried to add this functionality to a project early in my career (ten years ago ... already!?) when I found out just how easy it was. I take solace in knowing that I'm not alone, though ... A quick search for "footer stick bottom" still yields quite a few results from fellow developers who are wrestling with the same frustrating experience I did. If you're in that boat, fear no more! We're going to your footers in shape in a snap.

Here's a diagram of the problem:

CSS Footer

Unfortunately, a lot of people try to handle it with setting a fixed height to the content which would push the footer down. This may work when YOU view it, but there are several different browser window heights, resolutions and variables that make this an *extremely* unreliable solution (notice the emphasis on the word "extremely" ... this basically means "don't do it").

We need a dynamic solution that is able to adapt on the fly to the height of a user's browser window regardless if the resize it, have Firebug open, use a unique resolution or just have a really, really weird browser!

Let's take a look at what the end results should look like:

CSS Footer

To make this happen, let's get our HTML structure in place first:

<div id="page">
 
      <div id="header"> </div>
 
      <div id="main"> </div>
 
      <div id="footer"> </div>
 
</div>

It's pretty simple so far ... Just a skeleton of a web page. The page div contains ALL elements and is immediately below the

tags in the page code hierarchy. The header div is going to be our top content, the main div will include all of our content, and the footer div is all of our copyrights and footer links.

Let's start by coding the CSS for the full page:

Html, body {
      Padding: 0;
      Margin: 0;
      Height: 100%;
}

Adding a 100% height allows us to set the height of the main div later. The height of a div can only be as tall as the parent element encasing it. Now let's see how the rest of our ids are styled:

#page {
      Min-height: 100%;
      position:relative;
}
 
#main {
      Padding-bottom: 75px;   /* This value is the height of your footer */
}
 
#footer {
      Position: absolute;
      Width: 100%;
      Bottom: 0;
      Height: 75px;  /* This value is the height of your footer */
}

These rules position the footer "absolutely" at the bottom of the page, and because we set #page to min-height: 100%, it ensures that #main is exactly the height of the browser's viewing space. One of the best things about this little trick is that it's compliant with all major current browsers — including Firefox, Chrome, Safari *AND* Internet Explorer (after a little tweak). For Internet Explorer to not throw a fit, we need concede that IE doesn't recognize min-height as a valid property, so we have to add Height: 100%; to #page:

#page {
      Min-height: 100%;  /* for all other browsers */
      height: 100%;  /* for IE */
      position:relative;
}

If the user does not have a modern, popular browser, it's still okay! Though their old browser won't detect the magic we've done here, it'll fail gracefully, and the footer will be positioned directly under the content, as it would have been without our little CSS trick.

I can't finish this blog without mentioning my FAVORITE perk of this trick: Should you not have a specially designed mobile version of your site, this trick even works on smart phones!

-Cassandra

September 6, 2012

Tips and Tricks - jQuery equalHeights Plugin

Last month, I posted a blog about dynamically resizing divs with jQuery, and we received a lot of positive feedback about it. My quest to avoid iframes proved to be helpful, so I thought I'd share a few more esoteric jQuery tips and tricks that may be of use to the developers and designers in the audience. As I thought back about other challenges I've faced as a coder, a great example came to mind: Making divs equal height, regardless of the amount of content inside.

I haven't seen many elegant div-based solutions for that relatively simple (and common) task, so I've noticed that many people struggle with it. Often, developers will turn back to the "Dark Side" of using tables to format the content since all columns would have the same height as the tallest column by default:

JQuery Tutorial

It was easy theme table columns and to achieve the coveted 100% height that many designers seek, but emulating that functionality with divs proves to be much more difficult. A div is like the Superman of HTML elements (faster-loading, more flexible, more dynamic, etc.), and while it has super powers, it also has its own Kryptonite-like weaknesses ... The one relevant to this blog post being that floating three div elements next to each other isn't going to give you the look of a table:

JQuery Tutorial

Each of the three divs has its own height, so if you're doing something as simple as applying background colors, you're going to wind up with an aesthetically unpleasing result: It's going to look funky.

You could get into some nifty HTML/CSS workarounds, but many frustrated theme creators and designers will tell you that if your parent elements don't have a height of a 100%, you're just wasting coding lines. Some complex solutions create the illusion of all three divs being the same height (which is arguably better than setting fixed heights), but that complexity can be difficult to scale and repeat if you need to perform similar tasks throughout your site or your application. The easiest way to get the functionality you want and the simplicity you need: The jQuery equalHeights plugin!

With a few class declarations in your existing HTML, you get the results you want, and with equalHeights, you can also specify the minimum and maximum parameters so it will create scrollable divs if the tallest element happens to be higher than your specified maximum.

How to Use jQuery equalHeights

First and foremost, include your JQuery lirbraries in the <HEAD> of your document:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script language="javascript" type="text/javascript" src="jquery.equalheights.js"></script>

The equalHeights plugin is not a hosted library, so you have to host the file on your server (here's the link again).

With the required libraries called in our document, it's time to make the magic happen in your HTML.

Create Your Divs

<div class="divHeight">This DIV is medium sized, not too big and not too small, but just right.</div>
<div class="divHeight">This DIV has a lot of useful content and media that the user can interact with, thus it's very tall.</div>
<div class="divHeight">This DIV is tiny. Period.</div>

To have them line up next to each other, you'd have them float:left; in your CSS, and now you need to apply the equalHeights function.

Call the equalHeights Plugin
In order for the script to recognize the height of the tallest element, you'd need to call $(document).ready just before the </body> tag on your page. This will ensure that the page loads before the function runs.

The call looks like this:

<script type="text/javascript">$(document).ready(function() {
$(".divHeight").equalHeights();
});</script>

If you want to specify a minimum and maximum (i.e. The div should be at least this tall and should be no taller than [adds scrollbar if the div size exceeds] the maximum), just add the parameters:

<script type="text/javascript">$(document).ready(function() {
$(".divHeight").equalHeights(300, 600);
});</script>

The initial call does not change the appearance of the divs, but the time it takes to do the resizing is so miniscule that users will never notice. After that call is made and the height is returned, each div with the class of divHeight will inherit the the same height, and your divs will be nice and pretty:

JQuery Tutorial

This trick saved me a lot of headache and frustration, so hopefully it will do the same for you too!

-Cassandra

August 8, 2012

No iFrames! Dynamically Resize Divs with jQuery.

It's no secret that iframes are one of the most hated methods of web page layouts in the web development world — they are horrible for SEO, user experience and (usually) design. I was recently charged with creating a page that needed functionality similar to what iframes would normally provide, and I thought I'd share the non-iframe way I went about completing that project.

Before I get into the nitty-gritty of the project, I should probably unpack a few of the reasons why iframes are shunned. When a search engine indexes a page with iframes, each iframe is accurately recorded as a separate page — iframes embed the content of one we page inside of another, so it makes sense. Because each of those "pages" is represented in a single layout, if a user wanted to bookmark your site, they'd probably have a frustrating experience when they try to return to your site, only to find that they are sent directly to the content in one of the frames instead of seeing the entire layout. Most often, I see when when someone has a navigation bar in one frame and the main content in the other ... The user will bookmark the content frame, and when they return to the site, they have no way to navigate the pages. So what's a developer to do?

The project I was tasked with required the ability to resize only certain sections of a page, while asynchronously shrinking another section so that the entire page would always stay the same size, with only the two sections inside changing size.

Let's look at an example with two divs, side by side on a web page:

iFrame Tutorial

One div will contain a navigation menu to jump to different pages of the website (#sidebar), and the second div will contain all the content for that page (#content). If some of the elements in #sidebar are too long to read with the default width of the div, we want to let the user freely resize the two divs without changing the width of the page.

Our task is straightforward: When #sidebar expands in width, also expand the navigation and shrink #content along with the main content inside #content. If #sidebar shrinks, the navigation, #content and main content would respond accordingly as well:

iFrame Tutorial

It's a relatively easy concept to do with iFrames ... But then you remember that iframes are no longer cool (yes, there was a time long ago when iframes were cool). I decided to turn to my favorite alternative — jQuery — and the fix was actually a lot easier than I expected, and it worked beautifully. Let's run through a step-by-step tutorial.

1. HTML

Lay out your two divs:

<div id="sidebar"> 
<div class="sidebar-menu">
<!-- all your sidebar/navigational items go here -->
</div>
</div>
<div id="content">
<!-- all your main content goes here -->
</div>

2. CSS

Style your divs:

#sidebar {
       width: 49%;
}
#content {
width: 49%;
        float: left;
}

3. jQuery

Now that we have our two divs side by side, let's apply some jQuery magic. To do that, Let's include our jQuery files in the <HEAD> of our document:

<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>

Now that we have the necessary scripts, we can write our function:

<script type="text/javascript">
  $(document).ready(function() {
    $( "#sidebar" ).resizable({      
    });
    $("#sidebar ").bind("resize", function (event, ui) {
            var setWidth = $("#sidebar").width();
            $('#content).width(1224-setWidth);
            $('.menu).width(setWidth-6);
        });
  });
</script>

I know that might seem like an intimidating amount of information, so let's break it down:

   $( "#sidebar" ).resizable({      
   });

This portion simply makes the div with the ID of "sidebar" resizable (which accomplishes 33% of what we want it to do).

   $("#sidebar ").bind("resize", function (event, ui) {

By using the .bind, we are able to trigger other events when #sidebar is called.

            var setWidth = $("#sidebar").width();
            $('#content).width(1224-setWidth);

This is where the magic happens. We're grabbing the current width of #sidebar and subtracting it from the width you want your site to be. This code is what keeps your page stays the same width with only the divs changing sizes.

            $('.menu).width(setWidth-6);

This part of the code that expands the contents in the navigation along with #sidebar.

You can see a working example of iframe-like functionality with jQuery here: http://jqueryui.com/demos/resizable/

The only part you won't find there is the trick to adjust a corresponding div's size to make it grow/shrink with the first ... I had a heck of a time searching that on the web, so hopefully this quick tutorial will help other developers who might be searching for this kind of functionality!

- Cassandra

August 2, 2012

Meet Memcached: A Developer's Best Friend

Whether you're new to software development or you've been a coder since the punchcard days, at some point, you've probably come across horrendous performance problems with your website or scripts. From the most advanced users — creating scripts so complex that their databases flooded with complex JOINs — to the novice users — putting SQL calls in loops — database queries can be your worst nightmare as a developer. I hate to admit it, but I've experienced some these nightmares first-hand as a result of some less-than-optimal coding practices when writing some of my own scripts. Luckily, I've learned how to use memcached to make life a little easier.

What is Memcached?

Memcached is a free and open source distributed memory object caching system that allows the developer to store any sort of data in a temporary cache for later use, so they don't have to re-query it. By using memcached, a tremendous performance load can be decreased to almost nil. One of the most noteworthy features of the system is that it doesn't cache EVERYTHING on your site/script; it only caches data that is sure to be queried often. Originally developed in 2003 by Brad Fitzpatrick to improve the site performance of LiveJournal.com, memcached has grown tremendously in popularity, with some of the worlds biggest sites — Wikipedia, Flickr, Twitter, YouTube and Craigslist — taking advantage of the functionality.

How Do I Use Memcache?

After installing the memcached library on your server (available at http://memcached.org/), it's relatively simple to get started:

<?php
  // Set up connection to Memcached
  $memcache = new Memcached();
  $memcache->connect('host', 11211) or die("Could not connect");
 
  // Connect to database here
 
  // Check the cache for your query
  $key = md5("SELECT * FROM memcached_test WHERE id=1");
  $results = $memcache->get($key);
 
  // if the data exists in the cache, get it!
  if ($results) {
      echo $results['id'];
      echo 'Got it from the cache!';
  } else {
    // data didn't exist in the cache
    $query = "SELECT * FROM memcached_test WHERE id=1");
  $results = mysql_query($query);
  $row = mysql_fetch_array($results);
  print_r($row);
 
  // though we didn't find the data this time, cache it for next time!
  $memcache->set($key, $row, TRUE, 30); 
  // Stores the result of the query for 30 seconds
  echo 'In the cache now!';
 
  }
 
?>

Querying the cache is very similar to querying any table in your database, and if that data isn't cached, you'll run a database query to get the information you're looking for, and you can add that information to the cache for the next query. If another query for the data doesn't come within 30 seconds (or whatever window you specify), memcached will clear it from the cache, and the data will be pulled from the database.

So come on developers! Support memcached and faster load times! What other tools and tricks do you use to make your applications run more efficiently?

-Cassandra

June 5, 2012

New SoftLayer.com Design: Build the Future

If you've been reading the SoftLayer Blog via an RSS feed or if you find yourself navigating directly to the portal to manage your SoftLayer account, you might not have noticed that the our main website has been updated again — and in dramatic fashion. Last fall we gave the site a slight refresh ... This time, we did a total rework.

We took the site in a new visual direction, with graphics and messaging to complement our mantra of customers using our platform to create their vision — to build the future.

SoftLayer Homepage

The new look — referred to as "SoftLayer at Night" by my fellow SoftLayer developer friend, Seth Thornberry — was designed to reflect our core identity, and it retires the faithful red, white and grey theme that has served us well for more than three years. The new style has received rave reviews from customers, partners and employees, and even if there has been some criticism — everyone has an opinion nowadays — we can generally chalk it up to people simply not liking change.

Highlights of the Redesign:

  • A dramatic new home page design, including visually rich "hero images" (where you see "The InnerLayer" heading if you're reading this on the SoftLayer Blog)
    SoftLayer Homepage Hero Image
  • Expanded main navigation menus at the top of each page
    SoftLayer Homepage Top Nav
  • A new lower-order navigation system on the left of all content pages
  • SoftLayer Homepage Side Nav

  • [For typographically inclined] The new design also leverages web fonts functionality to incorporate "Benton Sans," the corporate font used in print, interactive and other marketing communications.
    SoftLayer Homepage Side Nav

The new design was executed in-house, and our workflow was pretty traditional ... We like to roll up our sleeves. Page templates were created as PSD files and then hand-coded in HTML, PHP, JavaScript and CSS on top of the same framework we use for the SoftLayer Customer Portal.

During the development process, we used our new GIT code repository to facilitate the merging of all of our code onto our staging server. Since it was our first time to use GIT in a major way, there was a bit of a learning curve. The first few merges had to be reworked after finding a few errors in commit messages, but after we got a little practice, the subsequent merges went off without a hitch. The final staging merge was a breeze, and given the struggles we've had with SVN in past projects, this was a huge relief.

When it came time for the design's official launch, we ran into a hiccup related to our automatic regression testing system and problems with cached CSS files, but these issues were quickly resolved, and the new-look SoftLayer.com went live.

It took a lot of hard work from (and a lot of caffeine for) a number of people to get the new site out the door, so I'd like to make sure credit goes where it's due. Our lead designer Carlos ("Los") Ruiz did a majority of the design work, and the implementation of that design fell to Dennis Dolliver (Website Developer), Charles King (SEO Manager) and me. I should also send a shout-out to the entire marketing team who jumped in to help to proof content, test pages and keep everyone sane.

What do you think of the new design? Stay tuned for more website improvements and additions!

-Brad

May 23, 2012

Web Development - JavaScript - Creating a Sticky Menu

When designing websites, I like to focus on ease of use and accessibility for the end user. While creating your site to be friendly to screen readers and text-based browsers is a must, the accessibility I'm referring to is making it easy for your audience to navigate your site and perform certain common actions. By providing an easy interface for your users, you are immediately increasing your chances that they'll return for more of your site's goodness.

Thus far in our "Web Development" blog series, we've looked at JavaScript Optimization, HTML5 Custom Data Attributes, HTML5 Web Fonts and using CSS to style the Highlight Selection. In this post, we're going to create a "sticky" menu at the top of a page. As a user scrolls down, the menu will "stick" to the top and always be visible (think of Facebook's Timeline view), allowing the user quicker access to clicking common links. With some simple HTML, CSS and JavaScript, you can have a sticky menu in no time.

Let's start with our HTML. We're going to have a simple header, menu and content section that we'll throw in our <body> tag.

<header>
    <h1>My Header</h1>
</header>
<nav id="menu">
    <ul id="menu-list">
        <li>Items</li>
    </ul>
</nav>
<div id="content">
    Some content
</div>

For brevity, I've shortened the content I show here, but the working example will have all the information. Now we can throw in some CSS to style our elements. The important part here is how the <nav> is styled.

nav#menu {
    background: #FFF;
    clear: both;
    margin: 40px 0 80px 0;
    width: 99.8%;
    z-index: 2;
}
ul#menu-list li {
    border: solid 1px blue;
    list-style-type: none;
    display: inline-block;
    margin: 0 -3px;
    padding: 4px 10px;
    width: auto;
}

We have set the menu's background to white (#FFF) and given it a z-index of 2 so that when the user scrolls, the menu will stay on top and not be see-through. We've also set the list items to be styled inline-block, but you can style your items however you desire.

Now we get to the fun part – the JavaScript. I've created a class using Mootools, but similar functionality could be achieved using your favorite JavaScript framework. Let's examine our initialize method (our constructor) in our Stickit class.

var Stickit = this.Stickit = new Class({
    initialize: function(item, options) {
        // 'item' is our nav#menu in this case
        this.item = document.id(item);
 
        // The element we're scrolling will be the window
        this.scrollTarget = document.id(options.scrollTarget || document.window);
 
        // The 'anchor' is an empty element that will always keep the same location
        // when the user scrolls. This is needed because this.item will change and
        // we cannot rely on it for accurate calculations.
        this.anchor = new Element('div').inject(this.item, 'top');
 
        // The 'filler' is an empty element that we'll use as a space filler for when
        // the 'item' is being manipulated - this will prevent the content below from
        // jumping around when we scroll.
        this.filler = new Element('div').inject(this.item, 'after');
 
        // Set the styles of our 'filler' to match the styles of the 'item'
        this.setFillerStyles();
 
        // Initialize our scroll events – see the next code section for details
        this.initEvents();
    }
});

What we're doing here is grabbing our element to stick to the top – in this case, nav#menu – and initializing our other important elements. I'll review these in the next code section.

var Stickit = this.Stickit = new Class({
    ...
    initEvents: function() {
        var that = this,
            // Grab the position of the anchor to be used for comparison during vertical scroll
            anchorOffsetY = this.anchor.getPosition().y,
            // Grab our original styles of our 'item' so that we can reset them later
            originalStyles = this.item.getStyles('margin-top', 'position', 'top');
 
        // This is the function we'll provide as our scroll event handler
        var stickit = function(e) {
            // Determine if we have scrolled beyond our threshold - in this case, our
            // anchor which is located as the first element of our 'item'
            var targetScrollY = that.scrollTarget.getScroll().y,
                fixit = targetScrollY > anchorOffsetY;
 
            if (fixit &amp;&amp; that.cache != 'fixed') {
                // If we have scrolled beyond the threshold, fix the 'item' to the top
                // of the window with the following styles: margin-top, position and top
                that.item.setStyles({
                    'margin-top': 0,
                    position: 'fixed',
                    top: 0
                });
                // Show our (empty) filler so that the content below the 'item' does not
                // jump - this would otherwise be distracting to the user
                that.filler.setStyle('display', 'block');
                // Cache our value so that we only set the styles when we need to
                that.cache = 'fixed';
            }
            else if (!fixit &amp;&amp; that.cache != 'default') {
                // We have not scrolled beyond the threshold.
                // Hide our filler
                that.filler.setStyle('display', 'none');
                // Reset the styles to our 'item'
                that.item.setStyles(originalStyles);
                // Cache our values so we don't keep resetting the styles
                that.cache = 'default';
            }
        };
 
        // Add our scroll event to the target - the 'window' in this case
        this.scrollTarget.addEvent('scroll', stickit);
        // Fire our scroll event so that all the elements and styles are initialized
        this.scrollTarget.fireEvent('scroll');
    }
});

This method contains the meat of our functionality. The logic includes that we test how far the user has scrolled down on the page. If s/he scrolls past the threshold – in this case, the anchor which is located at the very top of the "stuck" item – then we set the menu to be fixed to the top of the page by setting the CSS values for margin-top, position and top. We also display a filler so that the content below the menu doesn't jump when we set the menu's position to fixed. When the user scrolls back to the top, the styles are reset to their original values and the filler is hidden.

To see a full working example, check out this fiddle. The Stickit class I created is flexible enough so that you can "stick" any element to the top of the page, and you can specify a different scrollTarget, which will allow you to scroll another element (besides the window) and allow the item to stick to the top of that element instead of the window. If you want to give that a try, you can specify different options in Stickit and modify your CSS as needed to get it working as you'd like.

Happy coding,

-Philip

April 12, 2012

HTML5 - Compatibility for All?

Many of us remember when Flash was the "only" way to enhance user experience and create rich media interactivity. It was a bittersweet integration, though ... Many users didn't have the browser compatibility to use it, so some portion of your visitors were left in the dark. Until recently, that user base was relatively small — the purists who didn't want Flash or the people whose hardware/software couldn't support it. When Apple decided it wouldn't enable Flash on the iPhone/iPad, web developers around the world groaned. A HUGE user base (that's growing exponentially) couldn't access the rich media and interactive content.

In the last year or so, Adobe released Flash Media Server to circumvent the Apple-imposed restrictions, but the larger web community has responded with a platform that will be both compatible and phenomenally functional: HTML5.

HTML5 allows us to do things we've never been able to do before (at least without the hassle of plugins, installations and frustration). Gone are the limitations that resigned HTML to serving as a simple framework for webpages ... Now developers can push the limits of what they thought possible. As the platform has matured, some developers have even taken it upon themselves to prototype exactly where this generation of scripting is heading by creating Flash-free browser games.

Yes, you read that right: Games you can actually play on your browser, WITHOUT plugins.

From simple Pong clones that use browser windows as the paddles and ball to adventure-based Zelda-like massively multiplayer online role playing games (MMORPGs) like BrowserQuest, it's pretty unbelievable to see the tip of the iceberg of possibilities enabled by HTML5 ... Though it does seem a bit ironic to say that a Pong clone is such a great example of the potential of the HTML5 platform. Click on the screenshot below to check out BrowserQuest and tell me it doesn't amaze you:

Browser Quest

With an ingenious combination of CSS, JavaScript and HTML5, developers of BrowserQuest have been able to accomplish something that no one has ever seen (nor would ever even have thought possible). Developers are now able to generate dynamic content by injecting JavaScript into their HTML5 canvasses:

<code>
function handleKeyDown(evt){
keys[evt.keyCode] = true;
}
 
function handleKeyUp(evt){
keys[evt.keyCode] = false;
}
 
// disable vertical scrolling from arrows :)
document.onkeydown=function(){return event.keyCode!=38 &amp;&amp; event.keyCode!=40}
</code>

Look familiar? The game-making process (not syntax!) appears eerily similar to that of any other popular language. The only difference: You don't need to install this game ... You just open your browser and enjoy.

Using a popular port of Box2D, a physics simulator, making pure browser-based games is as simple as "Make. Include. Create." Here's a snippit:

<code>
//Make your canvas
<canvas id="game" width="600" height="400"></canvas>  
 
//include your js physics files
 
// create your world
function createWorld() {
// here we create our world settings for collisions
var worldAABB = new b2AABB();
worldAABB.minVertex.Set(-1000, -1000);
worldAABB.maxVertex.Set(1000, 1000);
// set gravity vector
var gravity = new b2Vec2(0, 300);
var doSleep = true;
// init our world and return its value
var world = new b2World(worldAABB, gravity, doSleep);
return world;
}
</code>

We may be a few years away from building full-scale WoW-level MMORPGs with HTML5, but I think seeing this functionality in native HTML will be a sigh of relief to those that've missed out on so much Flash goodness. While developers are building out the next generation of games and apps that will use HTML5, you can keep yourself entertained (and waste hours of time) with the HTML5 port of Angry Birds!

Angry Birds

HTML5 is not immune to some browser compatibility issues with older versions, but as it matures and becomes the standard platform for web development, we're going to see what's to come in our technology's immediate future: Pure and simple compatibility for all.

-Cassandra

March 13, 2012

Web Development - CSS - Highlight Selection

I immediately fell in love with CSS when we were introduced in late 2000. The ability to style a whole site outside the HTML was a fantastic concept and probably my first true introduction to separation of style and content. Put your words over here, and put how you display those words over there. So simple! Since then I have always been an advocate of cascading style sheets. Today's tip will involve an effortless addition that will have your readers say, "Ooooh. That's a clever little change."

I find that when I read articles and blogs online, I not only read with my eyes, I scan the page with my mouse. Especially if it's a wordy article or not styled in smaller columns, I highlight the text by clicking and dragging to help me maintain my focus. Up until recently, whenever you selected text that way in your browser, your operating system would choose the color of the background highlight. For Windows, this is generally blue. For OS X, this is whatever you've set your preferences to (which is light blue by default).

For those of you that use a newer version of Webkit (Chrome or Safari) or Gecko (Firefox), the site designer can determine what color to highlight your selection of text, and CSS has made it easy.

/* Webkit */
::selection {
    background: #972F2C;
    color: #FFF;
}
/* Gecko/Mozilla */
::-moz-selection {
    background: #972F2C;
    color: #FFF;
}

As of today, Webkit browsers are the only ones that support ::selection without browser prefixing. Firefox requires the -moz- prefix. Here we have set the highlight background color to "SoftLayer Red" (#972F2C) and made the text color white (#FFF). It should be noted that earlier versions of Webkit and Gecko did not support anything but the background property. There is still limited support for which CSS properties are allowed during selection. You are unable to change font-style, font-size, text-decoration and many other properties, but we can hope support for most of the properties will be available in the future.

This is pretty cool so far, but we can take it one small step further. Just like other selectors, we can apply the ::selection selector to other elements and style each one differently.

h2::selection {
    background: #B72E33;
    color: #FFF;
}
p::selection {
    background: #ACEFB2;
}
div::selection {
    background: #E4DB80;
}
span::selection {
    background: #C780E4;
    color: #FFF;
}

This produces the following:

Highlighting Example

Surprise your readers and give them some highlight goodness.

Happy coding!

-Philip

October 26, 2011

MODX: Tech Partner Spotlight

This is a guest blog from the MODX team. MODX offers an intuitive, feature-rich, open source content management platform that can easily integrate with other applications as the heart of your Customer Experience Management solution.

Company Website: http://modx.com/
Tech Partners Marketplace: http://www.softlayer.com/marketplace/modx

Free your Website with MODX CMS

Just having a website or a blog is no longer a viable online strategy for smart businesses. Today's interconnected world requires engaging customers — from the first impression, to developing leads, educating, selling, empowering customer service and beyond. This key shift in online interaction is known as Customer Experience Management, or CXM.

For businesses to have success with CXM, they need an efficient way to connect all facets of their communications and information together with a modern and consistent look and feel, and without long learning curves or frustrating user experiences. You don't want a Content Management System (CMS) that restricts your ability to meet brand standards, that lives in isolation from your other systems and data, or that fails to fulfil your businesses needs.

MODX is a content management platform that gives you the creative freedom to build custom websites limited only by your imagination. It certainly can play the central role in managing your customer experience.

Freedom from Hassle & Frustration
The most productive tools are those that simply allow you get your work done. To make life easy for content editors MODX uses familiar concepts like a hierarchical tree – similar to the folders and files on your computer. This allows content editors to relate their content to the overall website structure. But, like everything else in MODX, you aren't limited to hierarchical content and can easily employ taxonomy-, list- or category-based structures.

Similarly, editing documents should be easy. With MODX, anyone who can open a web browser and send email has the skillset to create and edit content in MODX. Most tasks are a matter of filling out simple form fields into which content is placed and is accompanied by a sensible MS Word-like editor for your main content. Furthermore, site builders and developers are able to create custom fields for custom content types and custom data allowing non-technical employees to work in an intuitive, tailored environment.

Total Creative Freedom
Your website is one of the most visible parts of your brand and you certainly don't want it limited by your CMS. MODX makes it possible to do anything that's on the modern web now — you don't have to wait for a year or hack the core to launch an HTML5 or mobile optimized site. MODX can do it all now, and even what's coming next. It outputs exactly and only what you or your site builder dictate.

MODX uses a brilliantly simple template engine that allows web designers to work with what they already know, like HTML, CSS and any JavaScript library they chose. MODX can even output things not typically associated with most content management platforms like XML, JSON or even Comma Separated Value (CSV) files that automatically download to your desktop.

Freedom to Extend
MODX provides all the requisite tools for CMS, but it also functions as a fully capable web development platform upon which you can extend functionality, employ custom applications and do just about anything you can dream up. In fact, the "X" in MODX comes from the word "extensible". Whether you want to build a Member-only website, Client Extranet, Resort Booking and Reservations system or private Social Network, you can do it on MODX.

For developers the fully-documented Object Oriented API and xPDO, MODXs database layer, provide all you need to build almost anything with MODX, even extending or overriding its core functionality. Critically, you can do all this using the API and retain a painless upgrade path without hacking the core. The MODX API architecture provides all the flexibility you or your developer might need to make MODX your own without painting your self into a corner.

Freedom from Bottlenecks
Modern web pages are made up of many component parts – site-wide headers and footers, navigation menus, articles, products and more. At some point, all these pieces need to be put together and delivered to the visitor as a single page that users expect to load quickly or they'll leave your site.

To deliver pages fast, top-performing sites use server-side caching to take all those pieces and pre-process them for fast delivery to a browser. The problem with many CMS applications is that they manually rebuild pages every single time someone visits your site. That's fine if you only have a few visitors, but your site can bog down or even fail under moderate traffic. In these circumstances, it would be disastrous if your website is featured on an industry magazine or website, national media or on a popular TV show. Your site could literally grind to a halt, costing you customers, damaging your reputation and ultimately making a bad first impression.

MODX's native page caching delivers your site quickly by default. Additionally, MODX can use high-end caching like memcache to further improve performance under load. To handle millions of pageviews daily, you need robust servers and you need to optimize your environment ... That's where scaling across multiple servers and replication with SoftLayer works perfectly with MODX.

Free Your Legacy Systems
Keeping your data, content and business information in disconnected silos is ineffective and costly. Accessing existing systems, like an Active Directory or Enterprise Content repository, makes huge difference in getting your work done headache-free. You don't have to worry about data duplication across systems, significant extra work to make everything work or synchronization issues. A new website platform should increase your productivity and enable your employees, customers and everyone else surrounding your business to find what they need and to interact efficiently and effectively.

MODX works with the tools and technology that organizations already have in place. It can easily interact with external web services or data feeds and can drive other applications via RESTful web services.

Security and Freedom to Rest Easy
Website Security is a topic that rarely surfaces during the early stages of a web project and often never comes up until your site has been compromised.

A high-quality hosting environment like those from SoftLayer are the foundation of website security. Your web CMS and its add-ons, plugin-ins or modules should not be a liability. MODX is designed with security at its core to protect your valuable website from malicious attacks. Every input is filtered, and every database query using the API eliminates the possibility of SQL injection compromises. Most importantly, the development team rigorously and continuously audits MODX to make sure its up to date and patching any new issues that may arise.

Freedom in the Community
With MODX and the MODX Community you're not alone. There are hundreds of thousands of websites built on MODX and we have a friendly, active and growing community of raving fans over 37,000 strong to whom you can look for assistance, support, education and camaraderie.

In fact, the MODX Community is one of our greatest assets.

They provide mentorship, assistance and help make MODX software better through active reporting of issues and feature requests and contributing improvements for integration by the core team.

If you're not a site builder or developer, but you want your website powered by MODX, one of the best places to start is with a MODX Solution Partner. Our network of 90+ global Solution Partners enables you to get the right-fit expertise for your project and in many cases work locally. Solution Partners are experts at MODX and know how to do things right.

Get Free
There really is a cure for the all too often restrictive, unintuitive and frustrating experience of putting content on the web. Get on the road to content management freedom with MODX. It's easy to start since MODX Revolution itself is free to download and use.

Learn more at http://modx.com/.

-Jay Gilmore, MODX

This guest blog series highlights companies in SoftLayer's Technology Partners Marketplace.
These Partners have built their businesses on the SoftLayer Platform, and we're excited for them to tell their stories. New Partners will be added to the Marketplace each month, so stay tuned for many more come.
August 23, 2011

SOAP API Application Development 101

Simple Object Access Protocol (SOAP) is built on server-to-server remote procedure calls over HTTP. The data is formatted as XML; this means secure, well formatted data will be sent and received from SoftLayer's API. This may take a little more time to set up than the REST API but it can be more scalable as you programmatically interface with it. SOAP's ability to tunnel through existing protocols such as HTTP and innate ability to work in an object-oriented structure make it an excellent choice for interaction with the SoftLayer API.

This post gets pretty technical and detailed, so it might not appeal to our entire audience. If you've always wondered how to get started with SOAP API development, this post might be a good jumping-off point.

Authentication
Before you start playing with the SoftLayer SOAP API, you will need to find your API authentication token. Go into your portal account, and click the "Manage API Access" link from the API page under the Support tab. At the bottom of the page you'll see a drop down menu for you to "Generate a new API access key" for a user. After you select a user and click the "Generate API Key" button, you will see your username and your API key. Copy this API key, as you'll need it to send commands to SoftLayer's API.

PHP
In PHP 5.0+ there are built in classes to deal with SOAP calls. This allows us to quickly create an object oriented, server side application for handling SOAP requests to SoftLayer's API. This tutorial is going to focus on PHP 5.1+ as the server side language for making SOAP function calls. If you haven’t already, you will need to install the soap client for php, here is a link with directions.

Model View Controller

Model-View-Controller or MVC is a software architecture commonly used in web development. This architecture simply provides separation between a data abstraction layer (model), the business logic (controller), and the resulting output and user interface (view). Below, I will describe each part of our MVC "hello world" web application and dissect the code so that you can understand each line.

To keep this entry a little smaller, the code snippits I reference will be posted on their own page: SOAP API Code Examples. Protip: Open the code snippit page in another window so you can seamlessly jump between this page and the code it's referencing.

Model
The first entry on the API Code Examples page is "The Call Class," a custom class for making basic SOAP calls to SoftLayer's API. This class represents our model: The SOAP API Call. When building a model, you need to think about what properties that model has, for instance, a model of a person might have the properties: first name, height, weight, etc. Once you have properties, you need to create methods that use those properties.

Methods are verbs; they describe what a model can do. Our "person" model might have the methods: run, walk, stand, etc. Models need to be self-sustaining, that means we need to be able to set and get a property from multiple places without them getting jumbled up, so each model will have a "set" and "get" method for each of its properties. A model is a template for an object, and when you store a model in a variable you are instantiating an instance of that model, and the variable is the instantiated object.

  • Properties and Permissions
    Our model has these properties: username, password (apiKey), service, method, initialization parameters, the service's WSDL, SoftLayer's type namespace, the SOAP API client object, options for instantiating that client, and a response value. The SOAP API client object is built into php 5.1+ (take a look at the “PHP” section above), as such, our model will instantiate a SOAP API object and use it to communicate to SoftLayer's SOAP API.

    Each of our methods and properties are declared with certain permissions (protected, private, or public), these set whether or not outside functions or extended classes can have access to these properties or methods. I "set" things using the "$this" variable, $this represents the immediate class that the method belongs to. I also use the arrow operator (->), which accesses a property or method (to the right of the arrow) that belongs to $this (or anything to the left of the arrow). I gave as many of the properties default values as I could, this way when we instantiate our model we have a fully fleshed out object without much work, this comes in handy if you are instantiating many different objects at once.

  • Methods
    I like to separate my methods into 4 different groups: Constructors, Actions, Sets, and Gets:
    • Sets and Gets
      Sets and Gets simply provide a place within the model to set and get properties of that model. This is a standard of object oriented programing and provides the model with a good bit of scalability. Rather than accessing the property itself, always refer to the function that gets or sets the property. This can prevent you from accidentally changing value of the property when you are trying to access it. Lines 99 to the end of our call are where the sets and gets are located.

    • Constructors
      Constructors are methods dedicated to setting options in the model, lines 23-62 of the call model are our constructors. The beauty of these three functions is that they can be copied into any model to perform the same function, just make sure you keep to the Zend coding standards.

      First, let’s take a look at the __construct method on line 24. This is a special magic php method that always runs immediately when the model is instantiated. We don’t want to actually process anything in this method because if we want to use the default object we will not be passing any options to it, and unnecessary processing will slow response times. We pass the options in an array called Setup, notice that I am using type hinting and default parameters when declaring the function, this way I don’t have to pass anything to model when instantiating. If values were passed in the $Setup variable (which must be an array), then we will run the “setOptions” method.

      Now take a look at the setOptions method on line 31. This method will search the model for a set method which matches the option passed in the $setup variable using the built in get_class_methods function. It then passes the value and name of that option to another magic method, the __set method.

      Finally, let’s take a look at the __set and __get methods on lines 45 and 54. These methods are used to create a kind of shorthand access to properties within the model, this is called overloading. Overloading allows the controller to access properties quicker and more efficiently.

    • Actions
      Actions are the traditional verbs that I mentioned earlier; they are the “run”, “walk”, “jump”, and “climb” of our person model. We have 2 actions in our model, the response action and the createHeaders action.

      The createHeaders action creates the SOAP headers that we will pass to the SoftLayer API; this is the most complicated method in the model. Understanding how SOAP is formed and how to get the correct output from php is the key to access SoftLayer’s API. On line 77, you will see an array called Headers, this will store the headers that we are about to make so that we can easily pass them along to the API Client.

      First we will need to create the initial headers to communicate with SoftLayer’s API. This is what they should look like:

      <authenticate xsi:type="slt:authenticate" xmlns:slt="http://api.service.softlayer.com/soap/v3/SLTypes/">
          <username xsi:type="xsd:string">MY_USERNAME</username>
          <apiKey xsi:type="xsd:string">MY_API_ACCESS_KEY</apiKey>
      </authenticate>
      <SoftLayer_API_METHODInitParameters xsi:type="v3:SoftLayer_API_METHODInitParameters" >
          <id xsi:type="xsd:int">INIT_PERAMETER</id>
      </SoftLayer_API_METHODInitParameters>

      In order to build this we will need a few saved properties from our instantiated object: our api username, api key, the service, initialization parameters, and the SoftLayer API type namespace. The api username and key will need to be set by the controller, or you can add in yours to the model to use as a default. I will store mine in a separate file and include it in the controller, but on a production server you might want to store this info in a database and create a "user" model.

      First, we instantiate SoapVar objects for each authentication node that we need. Then we store the SoapVar objects in an array and create a new SoapVar object for the "authenticate" node. The data for the "authenticate" node is the array, and the encoding is type SOAP_ENC_OBJECT. Understanding how to nest SoapVar objects is the key to creating well formed SOAP in PHP. Finally, we instantiate a new SoapHeader object and append that to the Headers array. The second header we create and add to the Headers array is for initialization parameters. These are needed to run certain methods within SoftLayer’s API; they essentially identify objects within your account. The final command in this method (__setSoapHeaders) is the magical PHP method that saves the headers into our SoapClient object. Now take a look at how I access the method; because I have stored the SoapClient object as a property of the current class I can use the arrow operator to access methods of that class through the $_client property of our class, or the getClient() method of our class which returns the client.

      The Response method is the action which actually contacts SoftLayer’s API and sends our SOAP request. Take a look at how I tell PHP that the string stored in our $_method property is actually a method of our $_client property by adding parenthesis to the end of the $Method variable on line 71.

View
The view is what the user interprets, this is where we present our information and create a basic layout for the web page. Take a look at "The View" section on SOAP API Code Examples. Here I create a basic webpage layout, display output information from the controller, and create a form for sending requests to the controller. Notice that the View is a mixture of HTML and PHP, so make sure to name it view.php that way the server knows to process the php before sending it to the client.

Controller
The controller separates user interaction from business logic. It accepts information from the user and formats it for the model. It also receives information from the model and sends it to the view. Take a look at "The Controller" section on SOAP API Code Examples. I accept variables posted from the view and store them in an array to send to the model on lines 6-11. I then instantiate the $Call object with the parameters specified in the $Setup array, and store the response from the Response method as $Result in line 17 for use by the view.

Have Fun!
Although this tutorial seems to cover many different things, this just opens up the basic utilities of SoftLayer's API. You should now have a working View to enter information and see what kind of data you will receive. The first service and method you should try is the SoftLayer_Account service and the getObject method. This will return your account information. Then try the SoftLayer_Account service and the getHardware method; it will return all of the information for all of your servers. Take the IDs from those servers and try out the SoftLayer_Hardware_Server service and the getObject method with that id as the Init property.

More examples to try: SoftLayer Account, SoftLayer DNS Domain, SoftLayer Hardware Server. Once you get the hang of it, try adding Object Masks and Result Limits to your model.

Have Fun!

-Kevin

Subscribe to html