Thursday, October 16, 2008

Ellipsis in all modern browsers (updated x4)

When you want to avoid that text in a web page wraps, you can use:
   overflow:hidden
However, it's nice to show to users that some content is actually missing. This is typically done with an ellipsis character, that is displayed as three dots:
   ...
Getting this working across all modern browsers has always been a pain in the neck, but there is an easy solution a hack that works around the issue, to a certain extent.

First, make sure you have a small ellipsis-xbl.xml file on your web server that is served with the content type text/xml, with the following contents:
<?xml version="1.0" encoding="UTF-8"?>
<bindings xmlns="http://www.mozilla.org/xbl" xmlns:xbl="http://www.mozilla.org/xbl" xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="ellipsis">
<content>
<xul:window>
<xul:description crop="end" xbl:inherits="value=xbl:text"><children/></xul:description>
</xul:window>
</content>
</binding>
</bindings>
Then mark all HTML elements you would like to show the ellipsis character on overflow with the class Ellipsis, e.g.:
   <div id="BreadCrumbs" class="ShyText Ellipsis">
Then add the following to your CSS:
   .Ellipsis {
text-overflow:ellipsis;
-o-text-overflow:ellipsis;
-ms-text-overflow:ellipsis;
-moz-binding:url(/ellipsis-xbl.xml#ellipsis)
}
Elaboration:
text-overflow
for WebKit-based browsers (Safari, Chrome, etc.) and for Internet Explorer 7 and before;
-o-text-overflow
for Opera;
-ms-text-overflow
for Internet Explorer 8;
-moz-binding
for Gecko-based browsers (Firefox, Camino, etc.)
Note that the text-overflow will be standardized as of the CSS 3 standard, which is currently still in draft.

Credit for the Gecko solution go to Rikkert Koppes and William Khoe, see the article text-overflow: ellipsis for firefox.

Update (Oct. 22, 2008): The solution for Gecko-based browsers (Firefox, etc.) is far from perfect. The solution has at least the following issues:
  1. applying the .Ellipsis class to an inline element causes the element to disappear;
  2. in Firefox 3.0 (not in Firefox 2.0), soft hyphens inside .Ellipsis elements always show as dashes;
  3. text inside a .Ellipsis element can no longer be selected.
Update (August 11, 2009): Mozilla (in the person of Simon Montagu) is working on a solution, which may or may not go into Firefox 3.6/Gecko 1.9.2. Vote for bug 312156 if you think it's important.

Update (August 13, 2009): Don't expect the solution to go into Firefox 3.6/Gecko 1.9.2 (scheduled for release fall 2009), the bug has been tagged as "-wanted1.9.2" (starting with a minus-sign) meaning it's not planned for the upcoming release. It may still go into Firefox 3.7, which is tentatively scheduled for release in 2010, see the Mozilla Project Meeting Minutes of July 20, 2009.

Update (August 24, 2009): Devon Govett provides a nice jQuery-based solution that at least allows you to resolve the issue when JavaScript is enabled. It works like a charm, at least on Firefox 3.5.2.

Friday, October 10, 2008

Mac OS X, fonts and headless Java

If on Mac OS X your custom font is not available in headless Java, try installing it in /System/Library/Fonts/ instead of /Library/Fonts/.

Don't ask me why, but this solved the issue I'd been struggling with for days. Below is the background.

Font installed
I purchased a font called "standard 07_55" from the miniml.com site and installed it via the font catalog program, which copied the .otf (OpenType) file to /Library/Fonts/:
  $ ls -lae /Library/Fonts/standard*otf
-rw-r--r--@ 1 ernst admin 11996 Oct 8 15:39 /Library/Fonts/standard 07_55.otf
It was accessible from the user account on the Mac, which is confirmed by running a text editor program.

Java program to list all available fonts
The following Java program lists all available fonts:
  public class ListFonts {
public static void main(String[] args) {
String[] fonts = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
for(int i=0; i<fonts.length; i++) System.out.println(fonts[i]);
}
}
Running the program from the graphical environment
When I ran this program is from Aqua, it worked well and displayed all fonts, including the installed "standard 07_55" font:
  $ java -version
java version "1.5.0_13"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_13-b05-237)
Java HotSpot(TM) Client VM (build 1.5.0_13-119, mixed mode, sharing)
$ javac ListFonts.java
$ java -cp . ListFonts | grep tand
KufiStandardGK
standard 07_55
Even when I added -Djava.awt.headless=true it still worked fine:
  $ java -Djava.awt.headless=true -cp . ListFonts | grep tand
KufiStandardGK
standard 07_55
Running the program via a remote connection
However, when that same program was run via a remote connection (SSH), then the program would not start up like this:
  $ java -cp . ListFonts | grep tand
Exception in thread "main" java.lang.InternalError: Can't connect to window server - not enough permissions.
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1822)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1723)
at java.lang.Runtime.loadLibrary0(Runtime.java:822)
at java.lang.System.loadLibrary(System.java:993)
at sun.security.action.LoadLibraryAction.run(LoadLibraryAction.java:50)
at java.security.AccessController.doPrivileged(Native Method)
at apple.awt.CGraphicsEnvironment.(CGraphicsEnvironment.java:23)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:164)
at java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:68)
at ListFonts.main(ListFonts.java:3)
This is understandable, since this is a remote connection, it cannot access the window server. So I started the Java program in headless AWT mode, and then it did run. However, now it does not show the font anymore:
  $ java -Djava.awt.headless=true -cp . ListFonts | grep tand
KufiStandardGK
Solving the issue
The fix? Simple: as root, move the font file to /System:
  # sudo mv /Library/Fonts/standard*otf /System/Library/Fonts/
I hope this helps someone else with a similar issue.

Tuesday, October 7, 2008

Use HTML 4 instead of XHTML

Here are some simple reasons for using HTML 4.01 with a strict doctype instead of using XHTML: