I’ve typed out a lot of CSS that’s focused on using a background image to replace text. I’ve been using a cross-browser CSS trick that’s SEO-friendly, I’m not sure if it’s documented anywhere. I came upon the solution myself when I was searching for a clever way to do this years ago and it’s become the standard method for me. However, I dislike the tedious task of typing out the CSS and referencing the image pixels and at work, I don’t want my developers wasting that time either.
I figured it’d be best to come up with a simple solution, so I started coding something out in bash and it worked:
#!/bin/bash
# css.sh - generate common css and html
# Tyler Mulligan (z@interwebninja.com)
# Last Update: 02/16/2011
# MIT License
create_block_image() {
feh -lr ${1:-.} | awk '{ print $3" "$4" "$8 }' | sed '1d' | while read l; do N=$((N+1));
cbi_css $l
done
feh -lr ${1:-.} | awk '{ print $3" "$4" "$8 }' | sed '1d' | while read l; do N=$((N+1));
cbi_html_a $l
done
feh -lr ${1:-.} | awk '{ print $3" "$4" "$8 }' | sed '1d' | while read l; do N=$((N+1));
cbi_html_div $l
done
}
cbi_css() {
f=${3##*/}
echo "#${f%.*} {
display: block;
background: url('$3') no-repeat 0 0;
width: 0;
height: $2px;
padding-left: $1px;
overflow: hidden;
}"
}
cbi_html_a() {
f=${3##*/}
echo "${f%.*}"
}
cbi_html_div() {
f=${3##*/}
echo ""
}
s=$1; shift; case $s in
--image-block|--cbi|-i) create_block_image $@;;
*) help help;;
esac
Which ouputs something like:
z@zygon:~/scripts/css$ ./css.sh -i img/
#dumbtubes-fav {
display: block;
background: url('img/dumbtubes-fav.png') no-repeat 0 0;
width: 0;
height: 14px;
padding-left: 16px;
overflow: hidden;
}
#submit_new {
display: block;
background: url('img/submit_new.png') no-repeat 0 0;
width: 0;
height: 106px;
padding-left: 244px;
overflow: hidden;
}
#dumbtubes-logo {
display: block;
background: url('img/dumbtubes-logo.png') no-repeat 0 0;
width: 0;
height: 70px;
padding-left: 274px;
overflow: hidden;
}
dumbtubes-fav
submit_new
dumbtubes-logo
To explain the way this CSS works, it uses the padding-left as the actual width, setting the width 0 and then pushes whatever content you have out of view using overflow:hidden to hit it from view. This makes it easy for search engines, keeping your HTML clean and CSS simple.
The bash script relies of “feh” a lightweight image viewer for linux that outputs a list of images and their dimensions. It also generates some sample HTML to quickly drop in and modify.
This is not an elegant solution and I’m not happy with the fact that it relies on feh. I’ve been slowly getting into python and I was amazed at how fast I was able to recreate this script in Python.
#!/usr/bin/python
# css.py - generate common css and html
# Tyler Mulligan (z@interwebninja.com)
# Last Update: 02/17/2011
# MIT License
from PIL import Image
import sys
import os.path
CSS_FORMAT = """#%s {\n\
display: block;\n\
background: url('%s') no-repeat 0 0;\n\
height: %spx;\n\
width: 0;\n\
padding: %spx;\n\
overflow: hidden;\n\
}\n"""
HTML_A_FORMAT = """%s\n"""
HTML_DIV_FORMAT = """%s\n"""
css=""
html_a=""
html_div=""
for tf in os.listdir(sys.argv[1]):
f = os.path.join(sys.argv[1],tf)
if os.path.isfile(f) == True :
img = Image.open(f)
fid = os.path.splitext(tf)[0]
(width, height) = img.size[0:2]
css += CSS_FORMAT % (fid,f,height,width)
html_a += HTML_A_FORMAT % (fid,f,fid,fid)
html_div += HTML_DIV_FORMAT % (fid,fid)
print css
print html_a
print html_div
This is just the basic idea, I didn’t spend more than 15 minutes on this rewrite, it does what I need it to do so far. It was suggested by friends if I make it any bigger, to look into a templating engine, such as mako. I hope this script can be useful to someone :). PS, HTML_DIV_FORMAT should be on one line, not sure why my syntax highlighter is trying to put it on 3.












