Justin Paul Silva

Aug 23

CSS-only Placeholder Text

I ran into a little problem with contenteditable elements: if the user deletes all the content, the element becomes invisible and really hard to find and click on. I didn’t want to add any extra styling to the span, so I decided to add a placeholder instead. The HTML5 placeholder attribute doesn’t work on contenteditables, and I preferred not to use Javascript if possible, so after some digging, I came up with this:


#post-text:empty:before {
content: "Enter some text";
}
#post-text:focus:empty:before {
content: "";
}

This works in IE9 and Chrome. IE7 doesn’t support :before and IE8 doesn’t seem to support :empty. I haven’t tried other browsers yet.

Jan 10

Styling the HTML Tag

Apparently, it’s possible to apply a CSS background both the body tag AND the html tag in order to create some interesting layering effects. And it works in Firefox, Chrome and IE 6-8. Probably more, but that’s All I’ve tested it in. Why would you want to do this? I’ll show you three examples where this can come in handy.

  1. Use the html tag for a repeating page background and the body tag for a top-only background, such as a gradient
  2. Use it with the body-width technique to create page margins
  3. Use it along with the 3D Javascript Effect to create another moving background image without an extra tag

1. Gradient Plus Repeating Background

Demo

This could also be done with CSS3’s multiple backgrounds, but this method is cross-browser (even works in IE6).

html { background:url(html-bg.jpg); } body { margin:0; background:url(body-bg.png) repeat-x; }

2. With Body Width

Demo

html { background:url(html-bg.jpg) top left fixed; } body { width:960px; margin:auto; padding:10px; background:#fff; }

3. With 3D Javascript Effect

Demo

html { background:url(html-bg.jpg) top left fixed; } body { margin:0; background:url(body-bg.png) top left; }

This technique can be used almost any time you would normally add an extra wrapper element around the page simply for styling purposes.

Nov 07

A Graveyard Song

Musician Tristan Omand selected my “Capo Vendetto” piece for the cover of his new EP “A Graveyard Song.” The album will be available on iTunes on November 19th. Until then, you can listen to and download the title track for free.

Sep 10

CSS Scrolling Animation

While redesigning this site, I tried implementing many different background effects to grab users’ attention. Although I decided against using the following effect, perhaps you can make better use of it. This is a demonstration of how to use two images and some simple CSS to animate the background of your site while the user scrolls up and down the page.

Here is a demonstration of the effect using three mask possibilities.

This technique follows Rufus Butler Seder’s Scanimation technique he invented for use in greeting cards and children’s books. Here’s an explaination of how it works:

The animation consists of two images: the base layer that contains segments from each frame of animation in the form of single pixel, horizontal scan lines, and a mask that will only allow one frame at a time. The animation in this demo consists of 4 frames, so every 4th horizontal line in the base layer will belong to the same frame.

The mask layer consists of 3 opaque horizontal lines, followed by 1 transparent line. In total, the mask layer really only needs to be 4 pixels high (or 3, or 5, or however many frames you are using) and one across, but I have larger masks here for demonstration. The mask works best if it’s the same color as the foreground of the base layer, but that’s not the only option. Try dragging each of the masks slowly over the base layer to see the effect in action.

The base layer Foreground color mask
Background color mask Different color mask

Let’s take a closer look at the base layer, frame by frame. Our base layer image contains 4 frames of animation, each one showing a spiral at a different stage of rotation. Even though each frame only shows part of the image, your brain will successfully fill in the rest. Drag and drog these frames onto each other to see how they are merged together to create the base layer image above.

Frame 1 Frame 2
Frame 3 Frame 4

Once you’ve created the images in your favorite image editor, the simple code below will allow you to tile the base layer in the background to scroll with the page, while the mask stays above it (but below the content), unmoved.

The HTML

<body> <div id='mask'></div> <h1>Header</h1> <div>Content</div> </body>

The CSS

body { background:url('img/spiral.png'); } #mask { position:fixed; top:0; left:0; width:100%; height:100%; background:url('img/mask.png'); z-index:-10; }

Aug 23

Specifying Tab Stop Width

I recently scoured the internet, looking for a way to specify the width of a tab stop (\t) in CSS. It turns out that CSS doesn’t offer any sort of solution. You may be asking, “Why would you even want to do that? After all, browsers ignore whitespace in HTML.” That’s true, unless of course you’re using a pre tag or any other tag with the whitespace set to pre in CSS, like the code examples on this site.

What we’ll do is use Javascript to search the element for tab stops and wrap each one in a stylable tab element. You could do this in PHP, but using Javascript is more plug-n-play because you only have to call the function once for the entire document, not each time you want a pre block. Also, when I tried to use PHP, JUSH (which I use to highlight the syntax in my code examples) would just seem to remove my new elements. That’s not cool, man.

The Javascript

This code requires jQuery. Call this after the page has loaded.

if (navigator.appName != "Microsoft Internet Explorer") { $("code, pre").each(function(){ $(this).html($(this).html().replace(/\t/g, "<span class='code-tab'>\t</span>")); }); }

First, we check to see if the broser is Internet Explorer. For some reason, $(this).html() removes all carriage returns when called in IE, which will certainly mess up your formatting. If the browser is IE, we’ll just ignore it and IE users will see the standard formatting, no big deal.

You can replace code, pre with whatever elements you want to affect. The /g in the RegEx tells the function to replace all matches, not just the first one (g stands for global). We’re going to leave \t in the span so the the original tab stops will be retained when users copy & paste the text or when it’s printed.

The CSS

.code-tab { display:inline-block; width:3ex; }

If the browser doesn’t support inline-block, then the tabs should show up as inline elements, which will look the same as if we did nothing. Again, that’s no problem at all.

Aug 22

Clean URLs Part 2

My previous article, Clean URLs with htaccess shows a very basic way of going about cleaning up your URLs. Now, let’s assume that not all of your pages are meant to look or act the same.

clean.php

This is what a typical PHP file will look like. We will store the title, keywords, etc. as variables to use in the index.php, and the content will be in plain HTML or HTML and PHP.

<?php $title = 'Clean URLs Part II'; $keywords = 'web design,web development,html,xhtml,html5,css,php,htaccess'; $description = 'How to use .htaccess and basic PHP to create clean web addresses'; $js = array('jquery', 'effects'); $header = "<ol> <li><a href='#clean_php'>Go to clean.php code</a></li> <li><a href='#htaccess'>Go to .htaccess code</a></li> <li><a href='#index_php'>Go to index.php code</a></li> </ol>"; ?> <h2>Clean URLs Part II</h2> <div id='clean_php'>Content...</div> <div id='htaccess'>Content...</div> <div id='index_php'>Content...</div>

.htaccess

<IfModule mod_rewrite.c> RewriteEngine on RewriteRule ^/?$ index.php?section=home&%{QUERY_STRING} [L] RewriteRule ^([^/\.]+)?$ index.php?section=$1&%{QUERY_STRING} [L] RewriteRule ^([^/\.]+)?/([^/\.]+)?$ index.php?section=$1&page=$2&%{QUERY_STRING} [L] RewriteRule ^([^/\.]+)?/([^/\.]+)?/([^/\.]+)?$ index.php?section=$1&page=$2&title=$3&%{QUERY_STRING} [L] </IfModule>

There’s a bit of PHP you will need to put above your HTML in your index.php. This code will actually execute the PHP script clean.php and store the output in a variable called $page_contents to be used later. This will give us access to $title, $keyword, and whatever other variables are set in code.php.

index.php:

<?php include("lib/const.php"); if (isset($_GET['page'])) $page = $_GET['page']; if (isset($page)) { if (!file_exists("{$page}.php")) $page = '404'; ob_start(); include("{$page}.php"); $page_contents = ob_get_contents(); ob_end_clean(); } if (isset($layout) && $layout === false) : echo $page_contents; else : ?> <!DOCTYPE html> <html dir="ltr" lang="en-US"> <head> <title><?php if (isset($title)) echo "{$title} - " ?>My Site</title> <meta name="keywords" content="<?= isset($keywords) ? $keywords : "web design,photography,art" ?>" /> <meta name="description" content="<?= isset($description) ? $description : "Justin Silva's Blog" ?>" /> <?php if (isset($css)) { foreach ($css as $style) { echo "<link rel="stylesheet" type="text/css" href="/css/{$style}.css" />"; } } ?> <?php if (isset($js)) { foreach ($js as $script) { echo "<script type='text/javascript' src='/js/{$script}.js'></script>"; } } ?> </head> <body> <header> <h1>My Site</h1> <?php if (isset($header)) echo $header ?> </header> <section> <?= $page_contents ?> </section> <footer> &copy;Justin Paul Silva </footer> </body> </html>

You can customize this to add an id attribute to the body tag for styling, add something to the footer, etc.

HTML Result

This is what the browser should see when you go to mysite.com/clean:

<!DOCTYPE html> <html dir="ltr" lang="en-US"> <head> <title>Clean URLs Part II - My Site</title> <meta name="keywords" content="web design,web development,html,xhtml,html5,css,php,htaccess" /> <meta name="description" content="How to use .htaccess and basic PHP to create clean web addresses" /> <script type='text/javascript' src='/js/jquery.js'></script> <script type='text/javascript' src='/js/effects.js'></script> </head> <body> <header> <h1>My Site</h1> <ol> <li><a href='#clean_php'>Go to clean.php code</a></li> <li><a href='#htaccess'>Go to .htaccess code</a></li> <li><a href='#index_php'>Go to index.php code</a></li> </ol> </header> <section> <h2>Clean URLs Part II</h2> <div id='clean_php'>Content...</div> <div id='htaccess'>Content...</div> <div id='index_php'>Content...</div> </section> <footer> &copy;Justin Paul Silva </footer> </body> </html>

There’s a lot of code here. Let me know if it doesn’t all work as expected.

Aug 20

Clean URLs with htaccess

Here’s a bit of code I use on most of my smaller sites, including this one, to clean up the URLs. This is the simplest way I know how to do it. A few benefits of clean URLs:

.htaccess

<IfModule mod_rewrite.c> RewriteEngine on RewriteRule ^/?$ index.php?page=home&%{QUERY_STRING} [L] RewriteRule ^([^/\.]+)?$ index.php?page=$1&%{QUERY_STRING} [L] </IfModule>

index.php:

<!DOCTYPE html> <html dir="ltr" lang="en-US"> <head> <title>My Site - <?= $_GET['page'] ?></title> </head> <body> <header> <h1>My Site</h1> <nav>Navigation goes here</nav> </header> <section> <?php include($_GET['page']) ?> </section> <footer> &copy;Justin Paul Silva </footer> </body> </html>

With this, you can go to mysite.com/portfolio, and you will see mysite.com/portfolio.php wrapped in index.php’s header and footer.

This way, the header and footer will be added to every page without having to use include or require on each one. Remember the DRY principle.

Jun 20

3D Javascript Effect

Here’s a little Javascript effect that will give your site a subtle 3D look by simulating a parallax between the content of your site and the background. Try out the effect now by scrolling up and down on my site. CSS only gives us two choices for background-attachment: scroll (default) and fixed. This script is sort of halfway between the two by making the background scroll half as fast as the content.

$(function(){ $("body").css("backgroundAttachment", "fixed"); $(window).scroll(function () { $("body").css("backgroundPosition", '50% '+(0-$(window).scrollTop()/2)+'px'); }); });

The second line, $("body").css("backgroundAttachment", "fixed");, is optional. You could set the background to fixed in CSS, but I prefer to do it this way so that if Javascript is disabled, the background will default to scroll.

This script also assumes the background is centered. If it’s left aligned, change the 50% to 0 px.

I’ve tested this in Firefox, IE and Chrome. It works in all three, but staggers a bit in Firefox.

Jun 04

Calculating Business Days in PHP

For one of my client’s projects, The Superdups Self-Service Quoter, I had to write an algorithm to estimate due date of each order based on a selected turn around time in business days. This would probably be a simply task in Ruby on Rails, but unfortunately, that wasn’t an option.

The Code

class DateHelper { // Holidays must be in order var $holidays = array("2010-07-04", "2010-09-06", "2010-09-23", "2010-10-11", "2010-11-01", "2010-11-11", "2010-11-25", "2010-12-25"); const oneday = 86400; // 86400 seconds = 1 Day const weekend = 172800; // 172800 seconds = 2 Days function addBusinessDays($start_date, $business_days) { // If $start_date is on the weekend, start on following Monday if (date('N', $start_date) == 6) { // If start date is on Saturday $new_start_date = $start_date + self::weekend; } elseif (date('N', $start_date) == 7) { // If start date is on Sunday $new_start_date = $start_date + self::oneday; } else { $new_start_date = $start_date; } // Add business days to the start date $due_date = $new_start_date + $business_days * self::oneday; // For every 5 business days, add 2 more for the weekend $due_date += floor($business_days / 5) * self::weekend; // If remainder of business days causes due date to land on or after the weekend if (($business_days % 5) + date('N', $new_start_date) >= 6) { $due_date += self::weekend; // Add 2 days to compensate for the weekend } foreach($this->holidays as $holiday){ $time_stamp = strtotime($holiday); // If the holiday falls between the start date and end date // and is on a weekday // Or if $new_start_date is on a holiday if (($start_date <= $time_stamp && $time_stamp <= $due_date && date("N", $time_stamp) < 6) || date("Y-m-d", $new_start_date) == $holiday) { $due_date += self::oneday; if (date('N', $due_date) >= 6) { // If due date on Saturday or Sunday $due_date += self::weekend; } } } return $due_date; } }

Usage

addBusinessDays ( int $start_date , int $business_days )

$date = new DateHelper; $start = time(); echo date("l, M d, Y", $start); echo "\n+ 0 Days = " . date("l, M d, Y", $date->addBusinessDays($start, 0)); echo "\n+ 1 Day = " . date("l, M d, Y", $date->addBusinessDays($start, 1)); echo "\n+ 2 Days = " . date("l, M d, Y", $date->addBusinessDays($start, 2)); echo "\n+ 3 Days = " . date("l, M d, Y", $date->addBusinessDays($start, 3)); echo "\n+ 4 Days = " . date("l, M d, Y", $date->addBusinessDays($start, 4)); echo "\n+ 5 Days = " . date("l, M d, Y", $date->addBusinessDays($start, 5)); echo "\n+ 6 Days = " . date("l, M d, Y", $date->addBusinessDays($start, 6)); echo "\n+ 7 Days = " . date("l, M d, Y", $date->addBusinessDays($start, 7)); echo "\n+ 8 Days = " . date("l, M d, Y", $date->addBusinessDays($start, 8)); echo "\n+ 9 Days = " . date("l, M d, Y", $date->addBusinessDays($start, 9)); echo "\n+ 10 Days = " . date("l, M d, Y", $date->addBusinessDays($start, 10));

Result

Friday, Jun 04, 2010 + 0 Days = Friday, Jun 04, 2010 + 1 Day = Monday, Jun 07, 2010 + 2 Days = Tuesday, Jun 08, 2010 + 3 Days = Wednesday, Jun 09, 2010 + 4 Days = Thursday, Jun 10, 2010 + 5 Days = Friday, Jun 11, 2010 + 6 Days = Monday, Jun 14, 2010 + 7 Days = Tuesday, Jun 15, 2010 + 8 Days = Wednesday, Jun 16, 2010 + 9 Days = Thursday, Jun 17, 2010 + 10 Days = Friday, Jun 18, 2010

Usage Notes

May 29

Syntax Highlighting for Your Blog

One of the greatest things about code editors is syntax highlighting. It makes any kind of code or markup language easier to read and understand. So why not use the same highlighting in your <code> blocks on your blog or website? When I created this site (just this week), syntax highlighting was one thing I knew I needed to have. So I did some searching, and it turns out to be incredibly easy to set up.

I decided on JavaScript Syntax Highlighter (or JUSH). It’s available as a stand-along script, a jQuery plugin, and a WordPress plugin. I’ll explain how to use it with jQuery, since that’s how I’m using it and they don’t cover it on their website.

First, download the Javascript and CSS files from the JUSH homepage. Then, include the files in your webpage:

<link rel="stylesheet" type="text/css" href="jush.css" /> <script type="text/javascript" src="jush.js"></script>

I differentiate between different coding languages by using the class attribute of the <code> element:

<code class="html"> <div id="content">Some HTML content</div> </code> <code class="html"> <div id="more_content">Some more HTML content</div> </code> <code class="css"> #content { color:#cc0000; } </code> <code class="js"> $('#content').html('Some Javascript content'); </code>

Then, I style it with:

// Syntax Highlighting $("code.html").each(function(){ $(this).jush('htm'); }); $("code.js").each(function(){ $(this).jush('js'); }); $("code.css").each(function(){ $(this).jush('css'); });

It seems you should be able to do…

$("code.html").jush('htm'); $("code.js").jush('js'); $("code.css").jush('css');

… but for some reason, it will take the content from all “html” code blocks on the page and combine them, so that both in the above code would output…

<div id="content">Some HTML content</div><div id="more_content">Some more HTML content</div>

… which clearly is not what we want.

So that’s it. Easy, wasn’t it? The only styling left for your <code> blocks is to use proper white space, either by wrapping your code blocks with <pre> tags, or using white-space:pre; in your stylesheet.