Archive for the ‘CSS’ category

CSSMin updated

2011-01-13 – 9:56am

I’ve updated my CSSMin project with a couple of new features and bugfixes. Download or fork it on GitHub!

What is it?

CSSMin takes your CSS file and strips out everything that’s not needed — spaces, extra semicolons, redundant units, and so on. That’s great, but there are loads of programs that do that. A shell script could do that! So what makes CSSMin different?

When you deliver content over the web, best practice is to deliver it gzipped. CSSMin takes your CSS file, and optimises it for gzip compression. This means that there’s a smaller payload delivered over the wire, which results in a faster experience for your users. It does this optimisation by ensuring that the properties inside your selectors are ordered consistently (alphabetically) and in lower case. That way, the gzip algorithm can work at its best.

What this means in practice is that your gzipped CSSMin-ed files are significantly smaller than plain gzipped CSS, and noticeably smaller than files that have been compressed by other means (say, YUI).

In this update:

Nested properties are now fully supported.

This means that the following CSS:

@-webkit-keyframes 'fadeUp' {
  from { opacity: 0; }
  to { opacity: 1; }
}

is compressed down to

@-webkit-keyframes 'fadeUp'{from{opacity:0}to{opacity:1}}

Your nested properties will have their contents compressed with all of the other tricks in system, but their order will be retained.

Thanks to bloveridge for reporting this bug and verifying the fix.

Font weights are replaced by their numeric counterparts.

.alpha {
  font-weight: bold;
}
.beta {
  font-weight: normal;
}

becomes

.alpha{font-weight:700}.beta{font-weight:400}

Values supported are “lighter”, “normal”, “bold”, and “bolder”.

Quotes are stripped where possible.

.alpha {
  background: url('ponies.png');
  font-family: 'Times New Roman', 'Arial';
}

becomes

.alpha{background:url(ponies.png);font-family:'Times New Roman',arial}

As much text as possible is changed to lower-case.

Only selectors, quoted strings (such as ‘Times New Roman’) and url() values are left intact.

Note that this means that if you mix the case of your selectors (for example, SPAN and span), your compression will be sub-optimal.

Thanks

Some of the ideas for this update were inspired by Lottery Post’s CSS Compressor.

Start using it!

Requirements

You will need a recent version of Java and the Java compiler.

Download

Download or fork it on GitHub.

Usage

  1. Compile the Java:
    # javac CSSMin.java
  2. Run your CSS through it:
    # java CSSMin [input] [output]

If you don’t specify an output file, the result will be dumped to stdout. Warnings and errors are written to stderr.

Results

These are the results of compressing the main CSS file for one of the webapps I develop at work. Note that many of these compressors only offer an online service, which means that they can’t easily be used as part of your general build process.

  Original size (bytes) Gzipped size (bytes)
Plain 81938 12291
YUI 64434 10198
LotteryPost 63609 10165
CSS Drive 69275 10795
CSSMin 63791 9896

Feedback

Let me know how you go with it — bug reports and feature requests are always welcome!

Theme update (again!)

2010-08-23 – 1:12pm

And so, for the third time this year, I’ve completely re-themed this site. Taking a very different tack from the last theme, I’ve tried to keep this one as simple as possible, with just a few subtle touches here and there to add interest. The palette is more subdued, which hopefully means that reading the text is a more pleasant experience. I’ve also done away with the multi-column body text in favour of a fixed-width design.

At the same time, though, I have endeavoured to use some of the new features available in modern web browsers — gradients, shadows, transitions, generated content, and so on. I’m fairly happy with the result — I think it’s a clean, unobtrusive theme that’s not too in your face. Feedback and criticism welcome! :D

The problem

When styling text <input> elements, it’s fairly common to run into a serious problem: they don’t behave like block-level elements.

Note: In all of the examples, the container element is filled with blue, and the <input> itself is filled with red and has an opacity of 50% so that you can see it under- or over-flowing the container.

<div  style="background: blue; width:200px;">
  <input  style="display:block; padding:4px; background: red; opacity:0.5; border:0;" type="text" value="text input"/>
</div>

You can see how the input doesn’t automatically flow to full width, as the “display: block” style suggests it should. The kneejerk response is to set the width to 100%:

<div  style="background: blue; width:200px;">
  <input  style="display:block; padding:4px; background: red; opacity:0.5; width:100%; border:0;" type="text" value="text input"/>
</div>

But notice now how the input overflows its container’s boundaries because of the left padding. At this point, people may resort to non-semantic markup (removing the padding on the <input> and putting it inside a padded <div>) or JavaScript solutions that set the pixel width whenever the container’s width changes (by the addition of scrollbars, for example).

The (semantic) solution

But wait! There is a way to achieve this effect without resorting to an extra <div> or JavaScript:

<div  style="background: blue; width:200px;">
  <input  style="display:block; padding:4px 0; background: red; opacity:0.5; width:100%; border:0; text-indent:4px;" type="text" value="text input"/>
</div>

Do you see what I did there? I removed the horizontal padding on the <input>, so the 100% width now works correctly, and replaced it with “text-indent”. To the user, this looks no different, and it has the advantage of requiring no extraneous markup or tedious scripting.

Drawbacks

  1. Should the user enter a long string, their text will bump up against the right edge. But I think that that’s a boundary condition that I can live with.
  2. Any vertical borders on the <input> will cause it to overflow its container. Personally, if I want a full-width <input>, though, I generally don’t want any borders on its left or right other than those of its container.

CSS Columns

2009-10-26 – 10:01pm

In this post, I will walk through the new columns specification that arrived in CSS 3. I will show you the current implementation state of columns in the four major rendering engines: Gecko (Firefox), Webkit (Safari & Chrome), Trident (Internet Explorer), and Presto (Opera).

Before we get on to platform-specific issues and workarounds, though, we’ll look at the various CSS properties available for working with columns.

For more in-depth information on columns, you should check out the W3C working draft and Mozilla’s MDC page on columns. The Webkit blog also has an article, but it’s not particularly informative.

Contents

I will add more to this entry as I discover more about columns — the goal is to make it an easy-to-understand reference.

Browser capabilities

Property Gecko Webkit Trident Presto
column-count -moz-column-count -webkit-column-count
column-width -moz-column-width -webkit-column-width
columns -webkit-columns
column-gap -moz-column-gap -webkit-column-gap
column-rule-color -moz-column-rule-color -webkit-column-rule-color
column-rule-style -moz-column-rule-style -webkit-column-rule-style
column-rule-width -moz-column-rule-width -webkit-column-rule-width
column-rule -moz-column-rule column-rule
column-span
column-fill
break-before
break-inside

Browsers used for testing: Firefox 3.5.4 (Windows), Safari 4.0.2 (Windows), Internet Explorer 8.0.6001, Opera 10.00 (Windows)

Please let me know if this table is inaccurate, and I will update it.

Browser bugs

These are the bugs that I have encountered using CSS columns — if you know of more, please let me know, and I’ll add them to these lists.

Gecko bugs

  • Specifying an “overflow” (or “overflow-x” or “overflow-y”) property on an element with columns prevents the column rule from being rendered at all.
  • Column rules occasionally don’t render, regardless of the “overflow” property.
  • There is no way to break columns.

Webkit bugs

  • Pixel creep: Pixels from a later column can creep back to the bottom of the previous column. This can happen with plain text, but it is much more noticeable when you use a non-layout altering effect like text-shadow or box-shadow.
  • Text that overflows the column horizontally is chopped off
  • There is no way to break columns.

Properties

column-count

Value: | auto
Initial value: auto

If you don’t set the column-width property, column-count specifies the number of columns into which the content should be flowed.

If you specify column-width, column-count imposes a limit on the maximum number of columns to be rendered if you supply a numeric value.

column-width

Value: | auto
Initial value: auto

This property indicates the optimal column width — columns may be rendered narrower or wider by the UA, according to the available space.

If column-width has the value “auto”, then the width of the columns is determined by other means (for example, column-count).

columns

Value: column-width && column-count

The columns property is a short-hand property, used to set both column-width and column-count simultaneously.

column-gap

Value: | normal
Initial value: normal

Use column-gap to specify the size of the gutter that lies between columns. Most UAs will render “normal” as 1em.

column-rule-color

Value:

When a column-rule is specified, you may use column-rule-color to set the colour for the line drawn between columns. This property is approximately equivalent to the various border-(?)-color properties.

column-rule-style

Value:

By using column-rule-style, you may determine how the line between columns is to be rendered, if at all. Similar to border-(?)-style.

column-rule-width

Value:
Initial value: medium

column-rule-width sets the width of the line rendered in the gutter between columns. Basically, it’s the same as the border-(?)-width properties.

column-rule

Value: column-rule-width && column-rule-style & & column-rule-color

Shorthand for setting all three column-rule properties.

column-span

Value: 1 | all
Initial value: 1

By using column-span, you can allow an element to span either the entire set of columns, or none at all.

Note that you cannot set an arbitrary number of columns to span — this property essentially ‘interrupts’ the column flow and restarts it below the spanned element.

column-fill

Value: auto | balance
Initial value: balance

If you have set a height for your columnified element, setting column-fill to ‘auto’ will cause the columns to be ‘filled’ in turn, rather than have the content balanced equally between them.