2009-06-28

CSS inheritance and selector specificity for max-width

While finding it easier to read text using narrower columns using my custom CSS definition, I noticed that it didn't work on pages that use table rows for grouping sections, such as the following structure:

table
  tbody
    tr
      td
        <headings>
        p …

Here's the CSS definition I was using:


@namespace url(http://www.w3.org/1999/xhtml);

@-moz-document domain(java.sun.com)
{
  body {
    max-width : 35em;
  }
}

It appears that the max-width property defined in the <body> element property isn't inherited by the <p> elements within the <table>. My first fix was to select all the elements in the path between <body> and <p> and make them inherit the max-width property:


…
  table, tbody, tr, td {
    max-width : inherit;
  }

This isn't a nice solution because I would have to specify all the possible types (or elements) that could be in a table cell. It would be better the use the CSS universal selector, *, instead:


…
  * {
    max-width : inherit;
  }

Now the definition is even applied to some elements that we don't really want to limit in size. Elements that are naturally wider than max-width, such as images in <img> tags, are now squashed, while preformatted text in <pre> elements are displayed in boxes with horizontal scrollbars.

If the max-width property is set to none, then the width of an element is not limited. The solution is to have two rules, a universal selector and a type selector, and we have a CSS definition that limits the width of all elements except for <div>, <img> and <pre>:


@namespace url(http://www.w3.org/1999/xhtml);

@-moz-document domain(java.sun.com)
{
  body {
    max-width : 35em;
  }
  * {
    max-width : inherit;
  }
  div, img, pre {
    max-width : none;
  }
}

This definition works because the universal selector is a less specific than a type selector, so the rules for <div>, <img> and <pre> override the universal selector's rule.

As usual when hacking code, I now realise that there's no longer any need to use inherit and I can simplify my CSS definition by specifying the max-width of every type using the universal selector.


@namespace url(http://www.w3.org/1999/xhtml);

@-moz-document domain(java.sun.com)
{
  * {
    max-width : 35em;
  }
  div, img, pre {
    max-width : none;
  }
}

To see the effects of the different definitions, add the style to your Stylish add-in, visit this Sun Java page and observe what happens to the width of the navigation bar on the top of the page and the sequence diagram images.

2009-06-24

CSS max-width versus width properties for text columns

It's easier to read on a web page if the columns aren't too wide. This presentation Ideal line length for content suggests setting the values of the min-width and max-width CSS properties around 30 em. Columns of 30 em sounds very narrow for a PC-based browser, but I expect it makes sense for browsers on handheld devices.

Using the Stylish Firefox add-in, here's my Narrow Paragraph rule for sites that I read:

@-moz-document domain(<domain 1>)
  , domain(<domain 2>) {
  body {
    min-width : 25em;
    max-width : 30em;
  }
}

Earlier, I used the width CSS property but when the browser window is made narrower than the width's value, the width of the text column doesn't change and you have to scroll left and right to read. Setting both min-width and max-width gives the designer and reader some flexibility in layout and viewing, respectively.

2009-06-21

Installing and configuring Subversion for personal use

I decided (finally!) to migrate my version control system from CVS to Subversion so that I could have atomic transactions when committing multiple files. There's plenty of tutorials on using and setting up Subversion on the net, so here's the simplest way to get started on Windows …

  1. Install and run Subversion on Windows
  2. Create a repository.
  3. Import a project into the repository.
  4. Check-out a project from the repository.

Install and run Subversion on Windows

  1. Install TortoiseSVN Subversion GUI client.
  2. Install CollabNet Subversion Server and Client:
    • I chose the svnserve option, otherwise by default the installer will also install the Apache web server and I already had Apache installed.
    • The installer will create a Windows service using svnserve. While it is possible to use the file protocol for personal development (since there's only one developer, yourself), it's likely that I'd use Subversion in a team, so I decided I might as well get used to the svn protocol and have a server manage my repository.

Create a repository.

  1. Open a command prompt and create a repository with this command: svnadmin create <repository path>.
    • Note that the installer should have added the Subversion bin folder to your PATH environment variable.
    • Note 2: I think I'm missing a step: How does svnserve map svn://localhost to the repository path?
  2. Edit <repository path>\conf\svnserve.conf and uncomment the following lines:
    • password-db = passwd
    • realm = My First Repository
    Note that passwd refers to the passwd file in the conf folder.
  3. Edit <repository path>\conf\passwd file and either uncomment one of the sample user and password pairs, or add a new pair. You could have anonymous read and write operations, but again, since I was likely to use it in a team, I might as well create a username-password pair.
  4. Open the Windows services console and start the CollabNet Subversion svnserve service if it is not already running.
  5. Check that TortoiseSVN can connect to your Subversion server.
    1. Open Windows Explorer
    2. Highlight an arbitrary file or folder and select the context menu item TortoiseSVN/repo-browser.
    3. When TortoiseSVN prompts you for a URL, enter svn://localhost (the address of your local Subversion server) and press the OK button.
    4. TortoiseSVN should display its Repository Browser window. If the svnserve service isn't running, you would get this message: Can't connect to host 'localhost': No connection could be made because the target machine actively refused it. If you get this message, check that the service is running in the Windows Services console.
    5. Leave the Repository Browser window open because you can use it to check that you have imported your projects successfully.

Import a project into the repository

  1. Copy or rename an existing project folder to something like <project>_import.
  2. In Explorer, select that folder and use the context menu item TortoiseSVN/Import....
  3. TortoiseSVN displays the Import dialog.
    1. In the URL of Repository field, enter svn://localhost/<project>.
    2. In the Import Message field, enter Importing <project>.
    3. Press the OK button.
  4. Since this is the first time you've used TortoiseSVN to import a project, you'll be prompted to enter a username and password. Optionally, select the Save authentication checkbox so that TortoiseSVN remembers your credentials. When you are satisfied, press the OK button to submit your credentials.
  5. Check that your project has been imported successfully using the TortoiseSVN's Repository Browser. You may have to press F5 to refresh the list of folders in the repository.

Check-out a project from the repository

  1. In Windows Explorer, highlight the folder to store your project and select the context menu item SVN Checkout....
  2. TortoiseSVN should display the Checkout dialog, with ...
    • URL of Repository = svn://localhost/<project>
    • Checkout directory = <path of project>
  3. Press the OK button and your project should be checked out to the target folder.
  4. Refresh the Windows Explorer window and you should see a green tick overlaid on the <project>'s folder icon. This shows that TortoiseSVN recognises this folder as a Subversion folder.

Final words

That's pretty much all the steps required to set up a basic Subversion system for personal development on Windows.

See Also

2009-06-17

Escaping special characters in Windows International Keyboard

The Windows International Keyboard allows you to enter letters with accent marks. For example, to type é, just type Apostrophe e. But what if you just want to enter (or escape) an apostrophe (for example, when entering a string literal while programming)? The trick is to type a space after the apostrophe, as per this bullet point in the support page: If you press the space bar, the symbol (apostrophe, quotation mark, accent grave, tilde, accent circumflex or caret) is displayed by itself.