My Blog

contains PHP and other web related content. (Sometimes there are some off topic things - don't freak out!)

Archive for the ‘CSS’ Category

Javascript and CSS Compression and Cache

Thursday, February 25th, 2010

I’ve been researching caching and compression techniques for my external resources for some time. My first design of JEMDiary was very greedy with HTTP connections. Couple that with having a less-than-perfect host (Dreamhost bleh…), users could feel the burn. I didn’t like it because it would even take ME forever to use my own website. I went on to discover many different key points I use when creating sites now – the Steps to Optimize Assets.

Steps to Optimize Assets

There are a few steps I live by when I design my websites now.

  • Use a subdomain for images, js and css. While I don’t go overkill with this (see: not 5 page brochure website), I do try to separate assets over multiple subdomains. The important thing is not to have too many – but none what so ever limit your user from loading your site as quick as possible. I generally use one for my assets and one for user submitted assets.
  • Use sprites. Whenever possible, reduce the amount of HTTP requests by combining images. It is faster to load an image that is 3x the size of the one you’re displaying than to open 2 more HTTP connections after you download the first image.
  • Cache non changing elements as long as possible. One of the biggest things I noticed on my dreamhost server was the misconfiguration of e-tags. After disabling them, I went and looked further into caching techniques. I found that most of my assets didn’t change – so I cached them up to a year.
  • Compress away white space. After you edit the source of your css, it doesn’t need to be pretty. In fact, things like comments and white space in css and javascript are just wasted bytes… bytes you could remove… but bytes you shouldn’t remove from your source. I deal with this by making a compressed copy on build.

These are my main rules. This article, however, is going to focus on how I deal with Javascript and CSS.

Disclaimer: The methods I’m going to describe here can be labor intensive. When you build your own system, you should strive to make some of these automated.

Preparing CSS for deployment

The first thing I do is create that subdomain. For my site example.com, users can visit http://example.com for the content. I create a subdomain called assets.example.com which is where I expect to get my content from. I generally create a server alias in the main config. This technically means that duplicate content could be served at both assets.example.com and example.com. I finish up by adding the following lines to the .htaccess file:

1
2
3
4
5
6
#make sure assets load properly
RewriteCond %{HTTP_HOST} ^assets.example.com
RewriteCond %{REQUEST_URI} !^/css
RewriteCond %{REQUEST_URI} !^/js
RewriteCond %{REQUEST_URI} !^/images
RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]

This make sure that if the host is assets.example.com and the content is not coming form the css, js or images folder, to redirect with a 301 to the main domain. This will stop duplicate content.

Enough about this, what about my CSS?

I actually hold my css in a different folder in my architecture – not some place that is world readable. I usually call it the public_source folder – which is at the same level in the source tree as say the www or html folder. In this example, I’m going to call my example file main.css. So it is actually located at /var/www/public_source/main.css.

Next, I’ll create a file called dev.php in the assets folder where I plan to test my css from. So, this file is located at /var/www/html/css/dev.php. It may contain this content:

1
2
header ('Content-type: text/css');
readfile('/var/www/public_source/main.css');

So, now when I load my website, I can do the following to load my source css:

1
<link rel="stylesheet" type="text/css" href="http://assets.example.com/css/dev.php" />

Of course, when the website is built and deployed, we will be using a different URL.

Next, lets talk about compression of the CSS. I use CSS Tidy to compress my code. The code to invoke this is pretty simple.

1
2
3
4
5
6
7
8
9
10
11
require 'csstidy-1.3/class.csstidy.php';
$cssSource = file_get_contents('/var/www/public_source/main.css');
 
$css = new csstidy();
$css->load_template('highest_compression');
$css->set_cfg('remove_last_;',TRUE);
$css->set_cfg('sort_properties', TRUE);
$css->parse($cssSource);
$cssFinished = $css->print->plain();
 
file_put_contents('/var/www/html/css/main.1.css', $cssFinished);

You’ll notice that I named the file main.1.css. The number will be explained later (its used for caching).

So, the CSS is read, compressed and cleaned, and outputted to a location that the webserver can serve it from. Now, instead of using dev.php as the source, we’ll use main.1.css. Congratulations – a smaller CSS file!

The final thing to do is adjust the caching of this script. Whenever we change the CSS on the development platform, we’re reading it in new using dev.php. However, when this is built and deployed, it should be a built version (or compressed) of the file. This means every code deploy requires this build system. And with release numbers on main software, we’re also going to increment our file name. So our second deployment of the software package (if the CSS source has changed) will now be built using main.2.css – and the link statement will be pointed towards that.

The caching then can make the assumption that this file will never change. The CSS may change but the file is a new name then. And since we can’t just load portions of a file whenever there is a change, even a small change in a non-cached file will make the entire file load. So with this in mind, I cache my CSS files for one year. I put the following in my config:

1
2
3
ExpiresActive On
#1 yr
ExpiresByType text/css A31536000

This means that the file will be cached one year from the first time it is accessed. So, if the source HTML continues to point at the same CSS file (say… main

Protect Your Image from Download

Wednesday, December 16th, 2009

I came across a great idea dealing with protecting image downloads from the site. Now, this is not fool-proof. There are lots of other ways to download the image, but this may stop the casual downloader. Nope, its not disabling the right click or using java. It requires one single transparent gif. Let’s see how.

(more…)

Printing a small segment of the page using JQuery

Monday, November 23rd, 2009

Using Yahoo’s Grid Tools, I created a pretty decent page layout. After all this was complete, I needed to generate a printable version of only a portion of the site. This was a particular set of instructions. I decided to tackle this with JQuery.

The Setup

The page was created with Yahoo’s Grids.
There were 4 sets of instructions on the site.
Each instruction had its own box containing the content – as well as a ‘print this’ link.
Users were liable to click the wrong link – and have to do it again.

The Code

The following is the JQuery I wrote to solve my problem:

1
2
3
4
5
6
7
8
	$(".printinstructions").click(function(){
		$('.instructionalli').remove();
		var box = $(this).parent();
		$("<style type='text/css' media='print'>#bd,#ft,#nav,#hd{display: none}a.printinstructions{display:none}.instructionalli{display:block}</style>").appendTo($('head'));
		$(box).clone().insertAfter($('body')).addClass('instructionalli');
		window.print();
		return false;
	});

This is what the content may have looked like:

1
2
3
4
5
6
7
8
<div>
<a href="#" class="printinstructions">Print These</a>
<ol>
<li>Do Step 1</li>
<li>Do Step 2</li>
</ol>
</div>
<!-- three more of these -->

The Explanation

First, any time a link with the class ‘printinstructions’ is clicked, the function launches. The first line in the function is responsible for undoing this process I’m about to describe. This is necessary just in case someone clicked the ‘print’ button earlier on the wrong element by accident.

The first step is to get the parent container. This is the content that we’re going to make our only printed content.

Next, create a new stylesheet that makes everything “display: none” except for the body itself. The media type is print. Finally, it does make the class “instructionalli” “display: block”. (Note: I could have just as easily attached the page in the source… but I needed to only have this activate if the print button was clicked).

The final step is to clone the box (that is inside of something that is ‘display: none’) and add that after the body content. Then, add the “display: block” class to it. Finally the window.print() method is invoked. For the most part, the user will have no idea any of this happened. The final result is a printed version of the instruction’s box content only.

Enabling Javascript Specific CSS

Monday, May 11th, 2009

While reading the blog post about Enabling Javascript specific CSS and the comments, I started thinking about my own ways to implement this. And how to do it validly.

Why Use Javascript Specific CSS

Believe it or not, we still have visitors to our websites that disable javascript. It could be a configuration setting on purpose, a malfunction or even an older browser (or a mobile one…?) At any rate, if you can make portions of your site accessible without javascript, you should do so. (I know some would argue that you should always make your site accessible without javascript enabled… but thats a whole other discussion.)

Before this method we’re going to talk about, the only way to display stuff to users without javascript was to use the NOSCRIPT tag. Luckily, this takes it one step further. You are not limited to using that tag. Instead, CSS attributes can be added to items that you would like to be visible (or invisible) if no javascript is enabled. Conversely, other stylings can take affect if javascript is on. One of the commentors on the previous link suggests using this technique to limit the visibility of icons that represent more dynamic behavior when javascript is disabled. Other usability enhancements include expanding hidden content automatically if no javascript controls are available.

How are people doing this?

The consensus after comments and edits appears to be to create the following type of code (this is just for an example)

main.css

1
2
.no_js a { color: #f00 }
.js a { color: #0f0 }

test.html

1
2
3
4
5
6
7
8
9
10
11
12
<html class="nojs">
  <head>
    <link rel="stylesheet" type="text/css" href="main.css" />
    <script type="text/javascript">
      document.documentElement.className = 'js';
    </script>
  </head>
  <body>
    <h1>Hello!</h1>
    <a href="http://www.somewhere.com">Link!</a>
  </body>
</html>

Basically, when javascript is enabled, it replaces the html’s class of ‘nojs’ with ‘js’ – then any of the CSS qualified with ‘.js’ is executed.

Not a bad idea.

How I Would Do It

I like the idea – but I have to point to the HTML tag reference and note that using a class attribute in your HTML tag is illegal.

You can use it on your body tag though. This is how I would do it.

1
2
3
4
5
6
7
8
9
10
11
12
<html>
  <head>
    <link rel="stylesheet" type="text/css" href="main.css" />
  </head>
  <body class="nojs">
    <script type="text/javascript">
      document.body.className = 'js';
    </script>
    <h1>Hello!</h1>
    <a href="http://www.somewhere.com">Link!</a>
  </body>
</html>

This should execute the javascript as the very first part of the body rendering. Then, the CSS will work fine – and its valid.

Thoughts?

Flash of Unstyled Content – in FireFox 3

Tuesday, April 28th, 2009

So I’ve heard of the Flash of Unstyled Content before – but never really had this problem. I always use a LINK tag for my stylesheets.

However, I just ran into it today – in FireFox even with a LINK tag…

Fixing Flash of Unstyled Content in Firefox

Simple really – I was loading way too much javascript before my stylesheet (not my fault on the large amount of js!!) – and the delay was causing the flash. I moved the link to the very first part of the content – and presto – good to go.

So, instead of

1
2
3
4
5
6
7
<head>
<script src="#"></script>
<script src="#"></script>
<script src="#"></script>
<script src="#"></script>
<link href="#" type="text/css" rel="stylesheet" />
</head>

Just move it to the top:

1
2
3
4
5
6
7
<head>
<link href="#" type="text/css" rel="stylesheet" />
<script src="#"></script>
<script src="#"></script>
<script src="#"></script>
<script src="#"></script>
</head>

… next battle, getting rid of sooo much js ;)

Remove Internet Explorer Button Border

Thursday, April 9th, 2009

Internet Explorer provides an additional border to any BUTTON element in the page if you don’t explicitly assign a 0px border to it. i have a bunch of buttons on a design that I’d like to have a 1px #fff border on. Unfortunately, with the additional border that IE adds, it looks horrible.

The solution was to add a span around the button:

1
2
3
4
5
6
button { 
border: 0px;
}
.button {
border: 1px solid #fff;
}
1
<span class="button"><button>My Button</button></span>

Another example of CSRF – in CSS

Thursday, March 5th, 2009

Just saw this really cool example get submitted on one of my websites testing for CSRF:

1
#logo{background:url(deletepost.process.php?id=12345&userID=12345);

Just another great example of why you should
1) not use GET for irreversible changes
2) filter filter filter! (I edited that posting, it was a filtered by my script already…)

Name CSS Classes More Descriptive

Thursday, October 30th, 2008

One thing I remember being pounded into my head is to not create CSS classes after their physical attributes. So, for example, if your error text is red, do not call the class red. Instead, be more descriptive of the content.

BAD!

1
.red { color: red }
1
<span class="red">There was an error!</span>

Instead, I was always encouraged to give the class something more descriptive, such as ‘error’.

GOOD!

1
.error { color: red; }
1
<span class="error">There was an error!</span>

Well, that seems pretty cut-n-dry for a simple example like that. However, in my most recent design, I’ve come across some more complex situations. For example, when you’re visiting the webpage, the background of an element might be a really dark grey. When you’re an authenticated user, however, I need it to be a medium grey (hey don’t ask – just wait for WhereIsTheBand.com to be done!).

Of course, during design, I went to the dark side right away:

BAD!

1
2
.darkGrey { color: #101011 }
.mediumGrey { color: #212122 }

Now, I know I should come up with some descriptive name, perhaps something like “userLoggedIn” or something, but I plan on using these classes in different areas as well. They might not be dependent on the user being logged in – just might look better that way. I didn’t want to make a lot of duplicate CSS code either.

The compromise: be semi descriptive.

COMPROMISE!

1
2
.lowContrastBackground { color: #101011 }
.mediumContractBackground { color: #212122 }

Not perfect, but seems like a better alternative.

CSS incompatibility finder

Thursday, September 25th, 2008

This is more of a proof of concept than anything else – as most of my scripts are ;) But, lets say you have some files that have css in them, either external stylesheets, internal one with style tags or even style attributes – and you need to update the browser support. Wouldn’t it be great to have a tool that could look through these files and point out that there are incompatibilities?

Well here is such a script!
(more…)

Internet Explorer CSS Hacks – Transparent PNG and Selectors

Saturday, February 23rd, 2008

As a reference for myself, I wanted to jot these things down.

First off, lets look at some common css selectors – and how we can use them to identify styles for specific versions of IE. (Note: I am way not into using hacks such as broken comments, etc, in CSS. I’d rather write a selector)

IE 6 and below

* html {}

IE 7 and below

*:first-child+html {} * html {}

IE 7 only

*:first-child+html {}

IE 7 and modern browsers only

html>body {}

** I can’t tell you how many times I wished for the parent/child selector option in IE 6. I’ve written way too many ‘ul ul ul li ul’ type strings

Next, lets check out the behavior for transparent GIFs:

First off, use the conditional comment to bring in the stylesheet only when needed.


Then, the actual behavior:

* html img {
position:relative;
behavior: expression((this.runtimeStyle.behavior="none")&&(this.pngSet?this.pngSet=true:(this.nodeName == "IMG" && this.src.toLowerCase().indexOf('.png')>-1?(this.runtimeStyle.backgroundImage = "none",
this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "', sizingMethod='image')",
this.src = "transparent.gif"):(this.origBg = this.origBg? this.origBg :this.currentStyle.backgroundImage.toString().replace('url("','').replace('")',''),
this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.origBg + "', sizingMethod='crop')",
this.runtimeStyle.backgroundImage = "none")),this.pngSet=true)
);
}

The original article (I’ll link it at the end) references HTML .png as well – but I don’t give my png files a class of png… so its not worth it.

At any rate, I’m referencing this article and that article. I just didn’t want them to go offline and not have a copy of them. ;)

  • twitter loader

Follow me on twitter: @aaronsaray

The views on this website are my own and do not reflect the opinions of my employer or clients.
Creative Commons License Home | Open Source | Book | Music | Art | Bio | Resume | Contact
My Baby