Developing a Digg-Style Input Form With CSS3 and jQuery

Digg is one of the most popular social news networks to date. They garner a massive audience in the millions of members. Recently the company has carved a new direction with the launch of Digg v4. The entire system has been replaced with new statistics and followers/following networking.

One of the most notable changes is in page aesthetics. With the launch of Digg v4 boasts a brand new design with a unique look and feel. In this tutorial I’ll be going over how you can create your own Digg v4 style input form using some basic CSS3 properties.

We’ll also be using jQuery to manipulate each of the key divisions for a nifty animation effect. We won’t be using any fancy Ajax calls here, although jQuery does support such functionality. The main form we’ll be using is based off Digg’s current submit page.

Live DemoDownload

Working with CSS3 and jQuery

As it may not be implied, there isn’t anything special required to work with CSS3. We don’t need to include any external files or libraries since most modern browsers will support a newer rendering engine. jQuery does have to be included into our file. Lucky for us Google Code hosts all versions of popular scripts online.

Using the Google APIs docs we can start working with jQuery 1.4.1. I’ve included the minified version to save bandwidth in the long run (always a good idea for production environments). Aside from this we’ll also need our core files. In order this will include a simple index.html, global.css for styles and script.js for our jQuery functionality.

Bare Structures

We can first start with our HTML code. It should be fairly straightforward but it doesn’t hurt to break things down into sections.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Digg-Style Input Forms</title>
<link rel="stylesheet" type="text/css" href="global.css" media="all" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
<Script type="text/javascript" src="script.js"></script>

This is the main heading portion of our HTML document. It contains all meta information along with an XHTML transitional doctype. The only file inclusions we’re working with are CSS and external JavaScript code. Both of these files are stored locally while our jQuery map is included via http://ajax.googleapis.com/.

Next we have some basic code for our core body layout. This will include the Digg heading and logo portion of the page. This also includes our small form with a few input buttons and div boxes.

<body>
<div class="header-wrapper">

	<div class="header group"><a href="#" class="sprite digg-logo" id="header-logo">Digg</a></div>

</div>

<div class="page-wrapper group">
	<div class="column full group">
    	<h1>Submit to Digg</h1>

        <div id="submission-form-container">

        <div class="flexible-input" id="submission-url-row">
            <input type="text" name="submission" placeholder="Submit a link" class="text-input" id="url-submit-url" value="" />
        </div>

        <div id="submission-editor-wrapper" style="display:block;">
    	<div id="submission-editor" class="group">

        <div class="submission-detail-field">
            <a class="edit-input" id="edit-title">Edit</a>
            <p id="submit-title">Destiny Islands Blog</p>
            <div class="flexible-input">
                <input type="text" name="submission-title" value="Destiny Islands Blog" class="text-input" id="user-title-text" />
            </div>
        </div>

      <div class="submission-detail-field">
            <a class="edit-input" id="edit-description">Edit</a>
            <p id="submit-description">Enter a description</p>
            <div class="flexible-input">
                <textarea class="text-input" rows="4" id="user-desc-text" placeholder="Enter a description">Enter a description</textarea>
            </div>
        </div>

  <div class="submission-buttons group">
            <div class="buttons-wrapper">
                <button type="submit" name="submit" class="btn btn-special has-tooltip" id="submit-create">Digg it <span class="sprite digg-it-large"></span></button>
                <a class="float-right" id="submit-cancel">Cancel</a>
            </div>
        </div>
    </div>
</div>
</body>
</html>

Next it should be simple to cover some of the common CSS queries. There are a few properties and IDs that should be understood well when editing a similar style script. Also we have used a few CSS3 properties new to modern browsers.

Next Generation CSS

Our file starts off simple with resetting margins and heading/body styles. There really isn’t much in the way of fonts, block areas, or other common elements. Since the purpose of our code is tutorial-driven I didn’t bother to create an extensive list of CSS properties.

* { margin: 0; padding: 0; }
body { font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; }

.header-wrapper{background:#1b5790;}
.header{height:45px;margin:0 auto;max-width:1000px;min-width:800px;padding:5px 20px 0 20px;}
.header.size-medium{min-width:800px;max-width:800px;}
.header.size-simple{max-width:680px;min-width:680px;padding:5px 0 0 0;width:680px;}
.header .digg-logo{float:left;margin:5px 20px 0 10px;}

.sprite{background:url('master.png') no-repeat 0 0; display:-moz-inline-stack; display:inline-block; *display:inline; vertical-align:top; zoom:1;}

.digg-logo{background-position:0 -109px;display:block;height:30px;text-indent:-999999px;width:62px;}

Notice how there is a small class called “sprite”. This uses a master.png file which holds all icons and graphics for Digg’s layout. This is a spriting technique used to save bandwidth and server calls for background graphics.

White MacBook with iPhone 3GS

Further down the page we have some newer blocks related to CSS3 queries. Many of the form’s input fields and buttons include effects generated in-browser through CSS. As one example all input text fields have -webkit-box-shadow set with an inset fall.

This produces a 3-D effect unlike many seen before. The new web standards generate beautiful tonality and with these CSS properties we can design amazing interfaces.

.text-input,.text-input-flat{background-color:#fff;border:1px solid #80a1c1;color:#80a1c1;font-size:1.16666666667em;padding:7px 9px 6px;margin-bottom:30px;}
.text-input:focus,.text-input-flat:focus{color:#666;}
.text-input{box-shadow:inset 0 1px 2px #d0d0d0;-moz-box-shadow:inset 0 1px 2px #d0d0d0;width:950px;-webkit-box-shadow:inset 0 1px 2px #d0d0d0;}
button{cursor:pointer;overflow:visible;padding:0;width:auto;}
button::-moz-focus-inner{border:0;padding:0;}
label{cursor:pointer;}
.block-label{color:#373529;display:block;font-size:1.16666666667em;font-weight:bold;margin-bottom:8px;}
.block-label .faded{font-weight:normal;}
.inline-label{color:#666;font-size:1.16666666667em;margin-right:10px;}

A bit lower we have a block of code catered to a few classes. submission-detail-field and now-editing contain some interesting properties that should be examined a bit further. Initially all content inside a now-editing class has no display. This is changed using jQuery to manipulate how we should our forms.

Submission forms are set by default to look like labels. Once you click to edit them we change the parent division class to now-editing and remove the display:none; clause. From here we can alternate between the two states with ease.

Digg.com Screenshot from a Mac OS X

These CSS styles can work with almost anything. You will notice a few bugs in the system right away. As a short example any buttons or links inside the div won’t show a mouse pointer on hover. Instead you’ll get the text bar used to highlight blocks of text – this can be changed through CSS’ cursor property.

.submission-detail-field{background:#fff;margin-bottom:10px;padding:10px 40px 10px 10px;position:relative;border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px;}
.submission-detail-field .flexible-input{display:none;}
.submission-detail-field.now-editing{background:transparent;padding:0;border-radius:0;-moz-border-radius:0;-webkit-border-radius:0;}
.now-editing p{display:none;}
.now-editing .edit-input{display:none;}
.now-editing .flexible-input{display:block;}
#submit-title{color:#356190;font-size:1.33333333333em;font-weight:bold;}
#submit-description{color:#80a1c1;font-size:1.16666666667em;line-height:1.33333333333em;}
.edit-input{color:#578cca;padding:5px;position:absolute;cursor:pointer;right:6px;top:6px;}
.edit-input:hover { text-decoration: underline; }

Building our Script

The JavaScript required is fairly straightforward to work with. Luckily jQuery helps by shaving off many lines of code required to target and manipulate DOM objects.

$(document).ready(function() {

We start with our standard ready event checking for our document to finish loading. This is a more precise way of targeting script development since all we really need is a fully loaded Document Object Model to get moving. Many smaller assets throughout the page will continue loading, but instead of waiting our script is executable instantly.

Inside our ready function parameters we pass a new function() designed to handle event listeners. These will check for a certain event to occur and when it does it’ll execute code set inside of a new function.

This will make more sense with an example, so let’s start with the first input field.

$('.edit-input').bind('click', function() {
    var dic = $(this.parentNode).attr('class');
    var curid = $(this).attr('id');

    if(dic == "submission-detail-field") {
        $(this.parentNode).removeClass('submission-detail-field');
        $(this.parentNode).addClass('now-editing');
    }

    if(curid == "edit-title") { $('#user-title-text').focus(); }
    else if(curid == "edit-description") { $('#user-desc-text').focus(); }

});

The first line is checking our document for any element(s) with the class “edit-input” and binding an event handler to it (or them). The event we’re looking for is a click event which means whenever the user clicks this element we call another function. In our HTML code .edit-input is a class applied to our edit links.

Once the function begins we are pulling the class name from our containing parent element. We are also grabbing the current ID of our edit link since we can determine if we’re editing the story title or description. Further down we have code to swap the two classes making our text field editable.

Afterwards there are a few lines of code needed to auto focus the text field and save any results. We could have used an Ajax call to save the data into a database with each click, however the details to do so range beyond this tutorial’s scope. We would also need support from a backend language such as PHP or Ruby.

$('#user-title-text').bind('blur', function() {
    var txt = this.value;

    $('#submit-title').text(txt);
    $(this.parentNode).parent().attr('class', 'submission-detail-field');
});

$('#user-desc-text').bind('blur', function() {
    var txt = this.value;

    $('#submit-description').text(txt);
    $(this.parentNode).parent().attr('class', 'submission-detail-field');
});

There is a similar bind event tied to our two form field divisions This will check for the text area containing our story description and works in a similar manner as above. Note that you are able to chain multiple event listeners in this manner to create dynamic form scripts in minutes.

Conclusion

This tutorial has given a strong overview of newer CSS3 techniques and classic jQuery functionality. Our final product looks very similar to the Digg submit form without pulling images from a URL which requires Ajax techniques.

All CSS styles and designs have been created in a very similar manner to Digg v4. Better yet, many of the code blocks have been made simple to copy and manipulate into your own page.

As stated previously I have updated both the live demo code and offered a .zip file for download. You can check out my Digg demo code here on DesignShack and also download the archive for your own works. If you have any questions/comments feel free to offer your ideas in the discussion area below.