AIAIO: Our Blog

AIAIO: Our Blog

The pulse and reviews of Alexander Interactive

Archive for February, 2009

OmniGraffle tutorials, Part IV: Actions

Welcome back to our OmniGraffle tutorials, run by Mike Piastro, Ai’s senior information architect. This is the fourth in a series of short videos designed to help users get the most out of OmniGraffle with the least amount of confusion.

Today’s video is about actions. Watch the tutorial here.

Previous tutorials:
Part I–template setup and variables
Part II–shared layers
Part III–stencils

UX

Tip: Reloading ActiveRecord Instances

When writing unit tests in Rails, I’ll often make a change to an ActiveRecord instance, requiring a reload for the next assertion to pass (oversimplified):

Technology

What is a single process?

This morning our intern sent the company-wide email announcing that the hair salon across the hall was offering a free single process for a hair model volunteer.
People didn’t seem to be replying to his email because no one knew what the heck a single process was. Do I have to be single to get this? Do people get their hair processed these days? Can I get a haircut?
Curious, I went to the hair salon and asked if I could get highlights. They explained a single process is a one color process, so I’d have to get my hair tinted red, black or some other color. In the design world, highlights would be equivalent to a CMYK print process, while a single process could be a one Pantone color print…!
Then a few guys here were offered $75 to get their hair bleached blond. Another one said he’d do it for $50, but he needed “approval from his superior” to do that. Meanwhile, I asked if I tinted my hair red I’d get double points on our company’s blog post contest. They said only if I had it hot pink! Ouch! That was a little too hard… Guys can go blond and make $75, and I only get 2 points and a pink hair… Guess not!
Offers keep coming… $10 if I go bald… $100 for the one who tints it “poo green”… Let’s see how this is gonna end. All I know it that by 6 p.m. today someone is going though a transformation, for better or worse!

Uncategorized

Process innovation at Moe’s

As a user-centric strategist, I’m always on the lookout for business practices that improve on a standard experience. So I took note the last time I went to Uncle Moe’s, a Mexican restaurant near the Ai office.
Uncle Moe’s has a typical sandwich-shop production line, like Subway for Tex-Mex food. I ordered my sandwich and answered the requisite questions down the line: guacamole, please; no sour cream, etc. My sandwich passed from the welcome guy to the component guy to the cashier, who announced, “Seven thirty-two.”
All normal–except none of the employees said anything to each other. No calling down the burrito’s name, no questioning from the cashier to the team. My meal was wrapped in foil without any notes attached to it.
moes.jpgConfused, I asked the cashier how the heck he knew what I had ordered. He smiled and showed me this card.
Uncle Moe’s has a code and a visual for each of its sandwiches. The greeter uses a China Pencil to mark each order that comes in, and the card moves down the production line with the sandwich. The cashier can ring up an order at a glance. The card is then erased and used again.
This system is subtle and ingenious. Uncle Moe’s is small, and the card reduces unnecessary noise. With a rapid-fire production system, the card ensures orders are filled and charged properly. And the dry-erase card eliminates the need for paper, reducing waste.
UX folks in Manhattan would enjoy checking out Uncle Moe’s. I recommend the Watsonville, hold the sour cream.

Ai

Dissecting the Green Key Marquee

The recent redesign of professional recruiter and temporary staffing firm features an interactive marquee that combines a slideshow, areas of expertise menu kick-out, and zoomable touts highlighting the site’s three key areas: available positions, resume submission and employers portal. This is a dissection of the component’s front-end HTML and CSS architecture, giving a more in-depth look at what’s actually happening under the hood.

The Marquee Frame

The marquee’s frame consists of the following divs:

  • #marquee – main parent container
  • #marquee_head – transparent png set as the background for the top curve
  • #marquee_foot – transparent png set as the background for the bottom curve
  • #marquee_content – content with a repeating vertical shadow background image
  • #marquee_overflow – wrapping container with overflow set to hidden to clip excess content from appears outisde the curves and sides

Each of the background images have a white outset to allow for the clipping to display correctly.

Zoomable Touts

gk_zoom.jpg

Keepin’ it cross-browser

The challenge here was keeping the tout’s markup within the actual marquee parent container to maintain a nice markup flow. Since IE disallows childen to stack over its parent elements who have an overflow set to hidden, this presented a problem for the hover states on each tout. As seen in the image, the touts overlay the actual marquee frame when hovered over with a cursor.

The solution?

Gotta swallow the geek pride on this one. We have to break the markup’s natural flow a bit and place the hover states, #marquee_touts_active, outside the #marquee div. Fortunately the placement is immediately after the #marquee div so the markup’s “roadmap” is still intact.

Transparency

No png’s necessary. The tout’s transparency setting is fully CSS-controlled. To cover all bases a few separate browser-specific CSS statements are necessary (see below).

Areas of Expertise Menu

gk_menu.2jpg

This menu is an overlay kick-out that appears when you hover over its call to action underneath the marquee’s main blurb that lists areas of expertise which are specific to the current division you are viewing.

See for Yourself

Below are stripped down versions of the actual HTML and CSS. You can view the marquee live in action at any of Green Key’s divisional sites such as Accounting & Finance.

HTML


<!-- #marquee-->
<div id="marquee">
<!-- #marquee_head -->
<div id="marquee_head">Beginning of Marquee</div>
<!-- /#marquee_head -->
<!-- #marquee_content -->
<div id="marquee_content">
<!-- #marquee_overflow -->
<div id="marquee_overflow">
<!--.slide -->
<div class="slide">
<!-- slide content -->
</div>
<!-- /.slide -->
<!-- #marquee_touts -->
<div class="clear" id="marquee_touts">
<div class="tout">
<!-- tout content -->
</div>
</div>
<!-- /#marquee_touts -->
<!-- #menu_areas -->
<div id="menu_areas">
<!-- areas of expertise content -->
</div>
<!-- /#menu_areas -->
</div>
<!-- /#marquee_overflow -->
</div>
<!-- /#marquee_content -->
<!-- #marquee_foot -->
<div id="marquee_foot">End of Marquee</div>
<!-- /#marquee_foot -->
</div>
<!-- /#marquee -->
<!-- #marquee_touts_active-->
<div class="clear" id="marquee_touts_active">
<div class="tout"><!-- tout content --></div>
</div>
<!-- /#marquee_touts_active -->

CSS:


/* #marquee
---------------------------------------------------------------*/
#marquee {
margin:0 0 0 -10px;
width:961px;
}
#marquee #marquee_head {
background: url(/img/bg/bg_marquee_head.png)
no-repeat scroll 0 0;
_filter:progid:DXImageTransform.Microsoft.
AlphaImageLoader(
src='/img/bg/bg_marquee_head.png',
sizingMethod='image'
);
_background: none;
height:43px;
position:relative;
text-indent:-1000em;
width:961px;
z-index:2;
}
#marquee #marquee_foot {
background: url(/img/bg/bg_marquee_foot.png) no-repeat;
_filter:progid:DXImageTransform.Microsoft.
AlphaImageLoader(
src='/img/bg/bg_marquee_foot.png',
sizingMethod='image'
);
_background: none;
height: 60px;
width: 961px;
position: relative;
z-index: 5;
text-indent: -1000em;
}
#marquee #marquee_content {
background: url(/img/bg/bg_marquee_content.png)
repeat-y scroll 0 0;
height:391px;
position:relative;
}
#marquee #marquee_content #marquee_overflow {
height:446px;
margin:-25px 0 0 10px;
overflow:hidden;
position:absolute;
width:940px;
}
/* #marquee_touts
---------------------------------------------------------------*/
#marquee_touts {
position: absolute;
top: 450px;
z-index: 1;
background: #236336;
filter:alpha(opacity=85);
-moz-opacity:0.85;
-khtml-opacity: 0.85;
opacity: 0.85;
}
#marquee_touts .tout {
float: left;
width: 311px;
padding: 23px 0 45px 0;
border-right: 1px solid #77917e;
cursor: default;
height: 50px;
}
/* #marquee_touts_active
---------------------------------------------------------------*/
#marquee_touts_active {
position: absolute;
z-index: 100;
margin: -165px 0 0 0;
}
#marquee_touts_active .tout {
height: 153px;
position: absolute;
}
#marquee_touts_active .tout .tout_content {
height: 153px;
}
/* extra div for ie hasLayout */
#marquee_touts_active .tout .tout_content {
padding: 30px 0 0 0;
background-position: left top;
background-repeat: no-repeat;
}
/* #menu_areas
---------------------------------------------------------------*/
#menu_areas {
position: absolute;
z-index: 2;
top: 235px;
left: 34px;
padding: 33px 0 0 0;
width: 578px;
}
#menu_areas.active {
background: url(/img/bg/bg_menu_areas_head.png)
no-repeat left top;
_filter:progid:DXImageTransform.Microsoft.
AlphaImageLoader(
src='/img/bg/bg_menu_areas_head.png',
sizingMethod='crop'
);
_background: none;
}
#menu_areas.active .menu_content { display: block; }

Technology

Mortimer: A Rails Password Manager

Today we release mortimer, our Rails-based password management application. The goal was to produce a secure, multi-user password vault providing basic user permissions and a simple interface. Here’s a screenshot from the current app:

mortimer.png

Public-key Cryptography

mortimer secures password using public-key cryptography. Each user on the system has a unique key pair. When you create a password entry, mortimer stores a uniquely-encrypted version of that password entry for each user with access to that password. This ensures that any time a password changes, all users have access to the change, with no compromise in security. And since all private keys are symmetrically encrypted with the user’s password, even a compromised database is fairly useless.

Precautions

Many would still argue that “web application” and “password manager” are mutually exclusive terms. It depends. We recommend, at minimum the following:

  • Do not expose mortimer to the public internet.
  • Run it over SSL (this is, in fact, required).
  • Use strong passwords, and limit access to the production environment.

A work in progress

mortimer should be considered alpha as it will remain under active development. Expect improvement to the UI, along with security tweaks and cross-browser compatibility. Let us know if you find it useful.

Contributions are welcome. Clone or fork us on GitHub.

Technology

Stand behind your work

At Ai we offer a warranty on every site and web system we build. A common gripe with purveyors of websites is that companies do not stand behind their work. Since Ai was formed, we have worked hard to overcome this characterization, not only contractually warrantying our product, but going above and beyond in our website delivery to launch sites and programs that function as specified. Most of our clients trust us to be caretakers of their primary revenue source–their websites–and we take this responsibility seriously.
A business offers a warranty for many customer-serving but also self-serving reasons. We find most of our new business through referrals from existing, satisfied clients. We love when our clients sing our praises and share the successes of our relationship with others.
Rabbit-silver.jpgI wanted to share an incredible customer service experience with New York-based Metrokane, the manufacturer of the popular Rabbit Corkscrew. Last year I received a Rabbit as a holiday gift and it has been an almost daily workhorse for over 12 months.
The Rabbit recently began to stick and was difficult to operate. Loving the product so much, my first inclination was to pop up on Amazon, find it, and purchase another one, which I did. Only after the replacement arrived (2-day shipping with Amazon Prime) did I notice the hard-to-believe warranty plastered right on the box:

If your Rabit Corkscrew fails in normal use within 10 years, return it with proof of purchase and $10.00 for shipping and handling.

Lacking the original proof of purchase for my broken Rabbit, I still decided to test it out. I called Metrokane, and the customer service rep not only offered to replace the malfunctioning Rabbit without the original proof of purchase (“You see, sir, we haven’t been around for 10 years yet, so we know you purchased this within our warranty period”), she was so intent on saving me the $10 S&H fee that she suggested I just drop into their office in midtown Manhattan to pick up a replacement. A few hours later (with the gracious help of Leslie and Robert @ Ai), I was the happy recipient of a brand new Rabbit Corkscrew.
What impresses me most about this experience is not only that this company stands behind its products or services; we all have to do that. But the grace and ease with which they allowed me to replace my faulty device and offered to save me the $10 replacement fee has turned me from a loyal product user into a proselytizer. Everyone wins. Thank you Metrokane.

UX

Validify, Semantify, Accessify

Tom is Ai’s front-end tech lead.

The following is a developmental check-list I religiously adhere to and find extremely essential in ensuring semantic-rich, accessible and valid (x)HTML.

Cool Dood Holding Checklist

Da Basics

  1. Specify a DOCTYPE and namespace
  2. Specify the document’s language
  3. Write your markup before writing any CSS to ensure your HTML is semantic and well-formed
  4. Document your HTML with start and end comments for clear separation of layout blocks within your markup
  5. Make sure the page validates (x)HTML

    1. 1.0 Strict for all new development
    2. Transitional for legacy applications using HTML flavors from the past
  6. Make sure the page title is set
  7. Include all necessary meta tags
  8. Use block and inline elements appropriately
  9. X-browser/X-Platform the page
  10. Separate blocks of content with a div
  11. KEEP ALL ATTRIBUTES AND THEIR VALUES LOWERCASE…KICKIN’ IT OLD SKOOL IS COOL, BUT NOT THIS WAY

Presentation and Content — Keep ‘em Separate

  1. Make sure your markup is semantic in that proper elements are used in which their purpose was intended

    1. Layout => div
    2. Headings => h1 through h6
    3. Paragraphs => p
    4. List of items => ul, ol
    5. Content emphasis => em, strong
    6. Tabular/grid data => table
  2. The presentation of content should be consistently applied regardless of CSS

Name Your Children With Some Structure

  1. Name your ID’s and classes based upon the structure of its content, not presentation

    1. content_head
    2. content_main
    3. sidebar
    4. navigation_main
    5. navigation_secondary
    6. logo
    7. header
    8. footer
  2. This will prevent renaming if the content’s look and feel changes

Headings Schmedings

  1. One h1 per page
  2. Maintain the hierarchy, h1 -> h2 -> h3h6 regardless of how cosmetically they may appear in design

Pretty Pictures

  1. Every image must contain a non-empty alt tag
  2. Dimensions on every image
  3. Keep images used for photographical purposes inline, not as background images

I Call ‘em Links, Anchors are for Boats

  1. Include title attributes on important links and/or graphical links containing no text in the image itself that describes the destination of the link
  2. Make sure there is always text present within the anchor even if it is a graphic
  3. The text should be informative, ie – use ‘close’ rather than just ‘x’ for a close button

Fontography

  1. Try to avoid all caps within markup and allow CSS or emphasizing elements to properly transform text so you have the option of reverting if needed
  2. Don’t abuse the br tag, using multiple consecutively isn’t necessary, just begin a new block level element

Set the Table, Anthony, and Don’t Forget the…

  1. caption element to let users know what your table is about (look at it as short headline)
  2. summary attribute to further describe your table’s contents in more detail
  3. colgroup‘s for multi-column tables
  4. th‘s for column headings
  5. thead for table heading content, tfoot for table’s footer content and tbody for the main body of the table’s grid content
  6. tfoot comes before the tbody in the markup…don’t ask me why
  7. And for pete’s sake, don’t use tables for layout, that’s so 1999

Forms (Don’t Have Anything Cute for this One, Sorry)

  1. Don’t forget the action and method attributes (leave em blank if you don’t know, leave that mush to the back-end dude)
  2. Have a legend to set the title of the form
  3. Use fieldset‘s to group related fields
  4. Use div‘s for further content separation within fieldset‘s
  5. tabindex on each input for easy keyboard accessibility
  6. The corresponding text for each input should be a label with the for attribute set to the input‘s ID
  7. maxchar set on inputs where necessary to assist with validation
Technology

Vendor Lock-In

One of our designers recently used her new Sony digital camera to take some office photos. As she did not have the USB connector with her, she looked for a device to pop the Memory Stick into, so she could upload her photos onto a computer. Unfortunately, as we found out, the technology of her camera was too new for anything else in this office.
Sony, it seems, is playing hard to get with its devices. This brings up the issue of vendor lock-in, where a consumer must incur the setup costs to adopt a new product that a vendor is offering.
The Sony Memory Stick in our designer’s camera, a proprietary design, is completely different from the one in my own Sony camera. Further investigation shed some light on the matter, in that Sony had created a new kind of Memory Stick, dubbed, “Memory Stick Pro Duo.” Wow.
This is a completely new technology–the new cards can hold a larger amount of data and have more functionality to work with video capturing and file-transfer rates. Awesome! I am at least glad that Sony is keeping up on their game to push advancements in technology. But they are forgetting about many of their loyal consumers, not to mention other electronics manufacturers who have built-in Sony Memory Stick Pro slots in their products.
What Sony has done is separate its consumer base. Older media will still function but are not compatible with their newer ones. Even the USB cable that comes with a newer model of Sony camera is no longer compatible. I can make a reasonable assumption that a year from now, if I needed to purchase an older model Memory Stick Pro card for my personal camera, I would have to buy it used or refurbished, or I’d simply have to buy in to Sony’s new technology.
This is where vendor lock-in comes into play. If I become dependent on a technology, but said technology advances, I am left with little choice but to upgrade if I want to continue using the product. I could switch to another brand, but in the end I would still be spending money to transition to a new product, whether with the same vendor or a new one.
I have seen similar issues arise over time. Technology changes, which I both understand and accept. Advancements must be made to improve the quality and functionality of a growing technological industry. As a result, consumers are almost forced to upgrade their devices and technology in order to keep up with the revisions that electronics developers and manufacturers come up with.

Business

Dramatically Reduce Form Submission Spam With A Hidden Field

You’ve set up your site and its contact form and you have started getting traffic. Then one day the person getting the contact requests forwards you a spam submission:
“We are getting tons of these. Is there a fix our web guy can implement?”
Your immediate response may be to install a captcha. That will work, although it is a bit much for a simple contact form.
An alternative solution is to simply include a hidden field.
hidden-field.pngIn your css file add:
#email2 { display: none; }
In your contact form add:
<input class="text" type="text" name="email2" id="email2" />
Finally, in your server side processing script add logic to the effect of:
if request.POST.get('email2','')=='':
    #process form

And that is it. This will trick the spam bot to think that there is an extra email field in your form that needs to be filled out. It will automatically fill it out and submit the form. By filtering any form submissions that have this extra field entered, you can exclude the non-human submissions.

Technology