A photo album with CSS controls for previous and next

A client who owns a salon wanted a change to her web site.

She used to have pictures of stylists and styles. So on Amanda’s page there was a picture of Amanda, and 1-3 pictures of hairstyles that she had created.

The new site would add another dimension. There would be a picture of Amanda, 1-3 styles she had created, and now, for each style, 1-3 pictures of the same style. Instead of Amanda getting 1-3 pictures, she’d get 1-3 photo albums.

There are many carousel and slide-show libraries available, but I didn’t want to be tied to someone else’s library. I wanted something simple:

  • Albums should be the same size as a regular picture.
  • Affordances for “previous” and “next should be unambiguous

Both requirements helped to rule out thumbnail pictures of other pictures in the album. Thumbnails that were big enough to be clear would take up space, and if two pictures of the same style were similar, it might not be clear that a thumbnail was actually a different picture.

Left- and right-pointing triangles seemed like a good indicator. I didn’t want to put them adjacent to the picture because that increased the size. Overlaying them on the photo could be confusing, depending on the size and color of the triangles. Plus, depending on the crop of a photo, they could be embarrassingly placed (horns? nipples? shoulder pads?). So what I wanted was:

  • left- and right-pointing triangles
  • against a solid background to form a “control” clearly separate from the photo
  • controls that broke the boundary of the photograph to show they were separate
  • opacity to be slightly less distracting to the photos

Circles were less obnoxious than squares for the previous/next controls. Also, a double border — light then dark — helped set the shape off from any photos that were primarily black or white at the bottom. What I wanted is this:

Photo showing unambiguous controls for previous and next

Unambiguous controls for previous and next

I knew I could make semi-transparent PNGs if I had to, but I wanted to try CSS first — and had great success.

First the triangle. I know that most modern browsers (back to at least IE7), including mobile devices and tables, handle UTF-8 very well. The right- and left-pointing triangles, ◄ and ►, are & #9658; and & #9658; respectively, blown up large so that they become finger-sized elements on a tablet.

Next the circle. A border-radius of 100% makes a nice circle. Some absolute positioning nudges the shape outside of the boundaries of the photo. A box-shadow outside of the white border makes a double border and creates some 3D separation. Opacity keeps the control muted until you hover over it.

IE8 and IE7 can’t handle the border-radius, the opacity, nor the shadow. I might have added some proprietary IE filters to achieve the same effect, but luckily, I didn’t have to worry about IE8 or below. (And in fact, in IE7 and IE8, you can still see the controls, they still hang outside of the picture, and they are still unambiguous — they’re just not as classy).

You can see the album controls in action on the live site. The code in use is below. Note that I’m using Nicole Sullivan’s OOCSS to build the page. The “album” is an OOCSS module, which requires a certain HTML structure. The JavaScript is trivial; it simply shows and hides images that are already on the page, so the responsiveness is fast at the expense of a slightly slower page load time.

HTML

 <div>
    <b><b></b><b></b></b>
    <div>
        <div>
            <div>
                <img src="/uploads/DSC_0955_2.jpg" >
                <img src="/uploads/DSC_0959_2.jpg" >
                <img src="/uploads/DSC_0978_2.jpg" >
                <span>◄</span> 
                <span>►</span>
            </div>
        </div>
    </div>
    <b><b></b><b></b></b> 
</div>

CSS

.album .bd {overflow: visible;}
.album {overflow: visible; font-size: 230%; line-height: 100%; 
    color: #ffffff; text-shadow: 2px 2px 2px #000000; }
.album .next,
.album .previous {position: absolute; bottom: -6px; opacity: 1; 
    cursor: pointer;
    display: none; font-family: Arial, Helvetica, sans-serif; 
    font-size: 26px;}
.album .next {background-color: #000000;
    border: 2px solid #FFFFFF;
    border-radius: 100% 100% 100% 100%;
    box-shadow: 0 0 3px #000000;
    cursor: pointer;
    opacity: 0.5;
    right: -6px;
    padding: 3px 2px 1px 8px;
    }
.album .previous {background-color: #000000;
    border: 2px solid #FFFFFF;
    border-radius: 100% 100% 100% 100%;
    box-shadow: 0 0 3px #000000;
    cursor: pointer;
    opacity: 0.5;
    left: -6px; 
    padding: 3px 8px 1px 2px;}
.album .next:hover,
.album .previous:hover {opacity: 1;}
Posted in CSS, Design, Mobile | Leave a comment

Make a proper favicon for your web site

Sunday is my website cleanup day. My error logs looked clean, so I decided to finally make a proper favicon for my primary web site.

I remember being surprised to learn that the .ico format allows you to store multiple sizes of the same image. That allows your operating system to show you a larger version of the file, rather than stretching a 16 x 16 blob of mud.

OS doesn't have to stretch a tiny blob of mud

How did I do it? I followed the tutorial at egressive.

http://egressive.com/tutorial/creating-a-multi-resolution-favicon-including-transparency-with-the-gimp

Posted in Images, Webmastering | Leave a comment

Git is Beautiful

Git is beautiful. Especially with Tower, a Git client only available on a Mac.

Repository interfaces

Several years ago, software developers generally decided that Git (or Mercurial) were better repositories than Subversion, in part because branching was cheaper and easier.

I have stuck with Subversion for a very long time because Tortoise gave me a graphical interface on Windows. In contrast, Git practically insists that you to use a command line. I have read comments openly hostile to Windows users who didn’t want to memorize git commands and were looking for a better interface. I have now installed something called Git GUI and I like it better than the command line, but it still feels pretty chintzy.

I have seen the future, and its name is Tower.

I’m currently working at a company that uses Mac computers, and they all use Tower, which is a beautiful, intuitive interface to Git. When I open Tower, I see a list of all the most recent snapshots, along with a beautiful timeline showing the Tree Graph of how we got to the most current top-level snapshot.

Tree graph art, a digression

The tree graph of our workflow fascinates me. The one to the left begins at the bottom when there was a single trunk, and ends at the top when we had all committed our changes back into a single trunk. And in-between are four parallel lines (meaning four colleagues were working simultaneously). There is a riot of branching (when a new colored line splits off), reintegrating (when a spur jumps to a different-colored line, usually left-to-right), and merging (when a colored line ends by joining another, usually right-to-left).

It looks like chaos, but at every point, everyone’s copy of the code worked, and so did the trunk. They just worked differently from each other.

Singing Tower’s praises

I can get a tree graph using “gitk” on my Windows computer, but it’s not nearly as beautiful as the one provided by Tower.

Further, Tower lets me control the repository using right-clicks (creating branches) or drag-and-drop (merging and reintegrating). Fetches, pulls, and pushes are the push of a button on the menu bar.

Of the various other interfaces to Git that I’ve tried, none have been written in an O.S.-native language, which means the interface feels unpolished. Buttons, windows, or scrollbars feel unnatural and somehow untrustworthy. Tower is built as a native OSX app, and it feels solid.

Yes, I have memorized many of the Git commands. I can and do use Git on my Windows computer for some clients, although I prefer SVN simply because Tortoise makes it easy to use.

But if there were a Tower for Windows, I’d convert all of my repositories today. Tower is so good, in fact, that it’s almost worth considering switching from Windows to a Mac.

(And no, I haven’t been paid by Tower to say these nice things. But one can hope!)

Posted in Information Architecture, Repositories, Web programming | 2 Comments

Use repositories to protect your work

Software developers use repositories to protect their work. If you work with many text files, you should too.

Repositories are snapshots of your work, stored on a timeline. You can use a repository for any collection of text files. My work happens to be web programming, but you could set up a repository to track legal documents, book chapters, or spreadsheets. (Note: you can also store binary files such as photos, music, or videos in a repository, but you don’t get the benefits of merging discrete changes (see below).)

Repositories protect your work and give access to its history of changes. Repositories allow you to boldly forge ahead with changes because you can always get back to a stable point in history if you need to.

Working in branches

When using a repository, the best practice is to create a new branch (a new snapshot of your work) any time you have more than just a few minutes’ work to do. (If you are working on a “branch,” then the “trunk” is that snapshot you took before you started making changes.)

As you complete tasks, or when you break for lunch or at the end of the day, you check in new snapshots. You keep working until you reach a stable point where you’re ready to share your work with others. Once your current task is complete, you merge your branch back into the trunk.

The neat thing about working in a branch is that, if at any time your colleagues need to see a good, clean copy of your work, you can give them a snapshot of the trunk, and it won’t have all the half-finished work that you have been saving in your branch.

A new dimension

If a repository were only a string of snapshots, it would be very low-tech. You could create your own “repository” just by storing copies of your work in folders marked with the date. It’s a one-dimensional timeline of your work.

What makes repository software like Subversion or Git so high-tech is that they know how to detect just the differences between one version and the next, which makes it possible to merge changes. Subversion and Git therefore allow you to work simultaneously with any number of colleagues.

Repositories are two-dimensional, allowing any number of parallel timelines, one for each colleague on your team.

Collaborating using a repository

Here’s how.

In the beginning, there was the trunk. “The beginning” is the day you decide to adopt a repository. The trunk is the baseline from which all work will flow and back into which all worthy work will return.

As each member of the team is assigned a task, he or she creates their own branch, starting from the trunk. Any number of people can be working on an individual branch, and still, there is a stable trunk for use by clients, colleagues, and bosses.

When you finish your work and it is ready to share, you merge your changes into the trunk. And because repository software knows about changes and merging, each of your colleagues can  perform the same merge of your changes into their work.

Occasionally, you will have changed the same exact line in the same exact file in a way that conflicts with one of your colleagues’ work. But repositories will show you these conflicts and ask you to resolve them the old-fashioned way…

… by talking to your colleagues and settling on the solution.

Posted in Information Architecture, Repositories, Web programming | 1 Comment

A CodeIgniter view does not run in the global scope

In a regular PHP file, you can grab the value of a variable from the global scope using the keyword GLOBAL. So for example if you want to use a variable inside your function, you can do something like this…

<?php
$TODAY = date('Y-m-d');
function getEvents()
{
    GLOBAL $TODAY;
    if ($TODAY > '2012-02-14')
    {
        //...
    }    
}
?>

I’m not saying you SHOULD write code this way, but there are times when this sort of option is cleaner than passing another parameter to your function, or faster than rewriting the existing code.

I tried to do this in a CodeIgniter view, which looks and behaves very much like a regular PHP file. But it wasn’t working. My variables (such as $TODAY, above) weren’t available inside my function, even after I used the GLOBAL keyword to grab them from the outer scope.

My mistake was thinking “… from the outer scope.” GLOBAL doesn’t pull variables from “outer” scopes, it only pulls variables from the top-level, global scope.

As it turns out, a CodeIgniter view doesn’t run in the global scope. It gets swallowed by the CodeIgniter engine. It is evaluated and run from within a CodeIgniter scope, which in turn runs within the global scope. (I haven’t actually traced how many layers there are between a view and the global scope — there could be more.)

The only option in this case is to pass the variable to the function as a parameter.

The scope of a CodeIgniter view file is not obvious, nor could I find it mentioned in the documentation. Hopefully this post will save someone else the trouble of tracing why the GLOBAL keyword doesn’t seem to be working in CodeIgniter.

And if you have dug even deeper than me and can draw a scope diagram for CodeIgniter, let me know!

Posted in Web programming | Tagged , , , , | 2 Comments

A sensible naming scheme for backup files

It’s important to back up a database regularly. But how do balance being thorough with being reasonable? If you save a full backup, every day, indefinitely, you will need more and more storage space. And really, do you care if you have to go back to the Tuesday backup from a year and a half ago, rather than the Thursday backup? No.

What you want is a lot of recent backups, and a few older backups, saved regularly.

My strategy is this:

  1. Make a backup every day
  2. Make a copy.
  3. Give the two copies the following names: “Wednesday.sql” and “February.sql” (or whatever the current day and month are). Always overwrite any file with the same name.

What results is a manageable list of only 19 backup files. I have 7 backups that are less than a week old, and I have a backup every month going back one year.

So far, the only backup I’ve ever needed was the most recent one. But I feel good that I’m making backups and keeping some history, without bloating my server with near-duplicates of files I will never read.

Posted in Uncategorized | Leave a comment

UTF-8 not working? Look for htmlentities.

I converted all my sites to UTF-8 and it was relatively painless. However, on one of my sites, I kept seeing legal UTF-8 characters turning into gibberish. It happened after entering UTF-8, submitting a form and then redisplaying the values in an edit box.

I know that all my pages are using UTF-8, and also that my database stores the text as UTF-8.

The thing that I overlooked is that, because I’m writing text to an input box, I’m using PHP’s htmlentities function to handle special characters, and the default character set used by that function is ISO-8859-1. I had to change my PHP command from

echo htmlentities($field);

to

echo htmlentities($field, ENT_COMPAT, 'UTF-8');

Once I verified that worked, I searched my whole codebase for htmlentities and made sure they were all using ‘UTF-8′

Posted in Character encoding, Debugging, Web programming | Leave a comment