Texture & Transparent Maths

This is the kind of post that would benefit greatly from the addition of screenshots, but I’m far too lazy so you’re going to have to put a lot of this into your head and create your own screenshots.

Now that’s out of the way, let’s talk about a situation that came up over the weekend. I was looking at a particular layout I’ve developed and lamented that the solid color background felt a little too empty. What it needed was some kind of texture to make it more visually interesting, but no so much that it takes attention away from the actual content of the page. What immediately came to mind were the linoleum tiles of an old grocery store I went to years ago which had solid color tiles with little dots of black and white color. I thought something like that might just pull off the trick of making things a little more visually interesting without taking away focus from the content of the page. So I needed to make some dots.

Continue reading

Advertisements

SSL/TLS Broken and Disabling Javascript Fixes It

In a few days a flaw or attack on SSL/TLS (the stuff that protects your passwords and personal data as it goes across the internet) will be presented at Ekoparty.

The attack requires the attacker be in position to intercept and inject into the data between the client and server, otherwise known as a man-in-the-middle attack. The attack appears to use javascript to send out known plaintext over an encrypted channel and allow attackers to then crack the encryption key using that known plaintext.

The simplest solution to protect yourself is to disable javascript.

As a web developer I look at things like noscript, cross-site scripting, and exploits like this as reasons to believe that users of my web site may not have javascript enabled. Therefore it is vital that javascript not be a critical component to using any site I manage. That doesn’t mean never use it, it only means that your web site still be usable without it. Treat it like Flash, or Java, or any other function that isn’t explicitly defined in the HTML or CSS specs. These things can make life easier for the user, but should never be a requirement.

This latest exploit, with the immediate message to end-users being disable javascript until a fix is ready, puts those web developers who rely on javascript to provide critical function to their site in a bad position. Don’t be one of those developers.

Eventually the practice of at least a white-list approach (see noscript) to Flash, Javascript, etc., if not completely removing them from the browser, will become the norm for even basic web users. It may not happen this year, or even in the next five years, but it’s very likely to happen as attacks on the web layer continue to grow.

printf(“Hello, world!\n”);

I haven’t been blogging much because I really haven’t had much to say. Browsers have gotten to a point where most people are using something that doesn’t require extensive or creative CSS hacks to work with basic CSS-driven layouts which was my bread-and-butter for the middle part of the last decade.

I recently did a bit of contract work which inspired me to work on a new layout which then inspired me to do some spring cleaning and share with you a bunch of old designs I’ve started over the last five years, but never got around to finishing. So hang on, there’s a bunch of new stuff to get through.
Continue reading

Responsive Web Design

Responsive web design is a term used to describe a web design that adapts itself to the end-user’s environment. This isn’t a new concept, but advancements in browser technology as well as a greater increase in viewing environment (desktop, netbook, smartphone, etc.) is allowing for some new and interesting tricks to our bag.

Responsive web design is something that’s been around since the first web designs came out utilizing percent values to define the widths of objects, such as TABLE, DIV, and IMG elements. The idea was that a person on a 640×480 resolution screen can view the web site, but a person with a larger resolution like 1024×768 would be able to see more content on their screen as the layout would expand to the edges of the larger viewport (the area in which a web page is rendered). This idea was somewhat radical back in the early 1990s as most layouts would simply set a fixed width for the layout (usually 780 or 1000 pixels) and state quite plainly on the web site that it was designed to be “best viewed in 1024×768”.

Things got more interesting with CSS. Web designs could now use percentages for margins, padding, and placement of elements within a page. Layouts that would expand and contract with the viewport could be more complicated. Especially handy were the CSS max-width and min-width attributes. These allowed you to set limits on just how much your layout would expand or contract before forcing the viewport to stop resizing the layout. Now layouts could expand and contract, but not so much that they became unusable.

Enter CSS3 media queries.

But first, a small caveat to web developers.

The CSS3 spec is not yet final. In fact there isn’t (or is, depending on your point of view) really a CSS3 spec at all. CSS3 is a collection of modules and therefore somewhat open-ended. You can see a list of some of the CSS3 modules and their curren status here. Some CSS3 modules are currently in an early format and not recommended for implementation, while others have reached a state where it’s not quite final, but browser authors are encouraged to implement these modules and supply feedback to help refine the spec before it becomes final. Media queries are in such a state and as such several modern browsers have already implemented them including the latest releases of Firefox, Chrome, Safari and Opera. So web developers can start making use of them now and those users who run modern web browsers will be able to enjoy your use of CSS3.

At the same time, I do not recommended you rely heavily on CSS3 modules in any designs for the near future, or that if you do, you do so while making sure to check compatibility of the layout against older browsers. While the general public appears to be more capable at keeping up to date with their browser (mainly thanks to the automated update features of several OSes and the increased proliferation of broadband internet connections),  there’s still a significant number of users (over 50% according to this site) who are using Internet Explorer 8 or earlier, which does not support media queries (or much else in the way of CSS3). IE9 will support media queries.

Now that that’s out of the way, what can media queries do for us? Simply stated, you can apply styles based on many attributes of the viewport. To keep things brief-ish and to the point, I’m going to specifically focus on width-related media queries. Let’s see what one looks like:

#frame { width: 1000px; margin: 0 auto; }
@media screen and ( max-width: 480px ) {
  #frame {
    width: 100%;
  }
}

The above example will make an element with the id of “frame” to be 1,000 pixels wide and will center (via the margin value auto for the left and right margin properties) it in the middle of the viewport if the viewport is wider than 1,000 pixels. On the second line is a media query. It begins with @media screen (in place of “screen” you can use “all” for any media, or “print” for print media, etc.) which lets the browser know that the following block of CSS should only be applied to the screen. This is followed by and ( max-width: 480px ) which is the media query. It states that the following block of rules should also only be applied when the viewport is at or less than 480 pixels in width. You can also use min-width to tell the browser the block of rules should only be applied when the viewport is at least 480 pixels wide.

Why would you want such a thing? If a viewport is that narrow and you have wide elements or you have multiple columns, chances are those elements would be very usable at such a narrow width. With a media query you can change the layout to something more usable on a small screen. For example, consider a layout that has multiple columns. At 480 pixels your columns will barely fit a few words per line, if any at all. Reading text becomes very difficult. With a media query you can drop your multiple columns into a single column layout. Now each column will have the full width of the viewport to render its content, making it much more usable.

In the example above I am removing the fixed-width on the #frame element and resetting its width to 100% of the viewport. Smartphone users will be able to view the content of the layout much more easily and without having to scroll horizontally to read each line.

Excellent! Now go and design for the masses!

But… not quite yet. There’s one problem. Some smartphones are a bit too smart. They understand not many web designs are out there that take advantage of these features. Instead these smartphones will scale the rendering of the page. While the screen may only have 480 pixels of width, it’ll render web pages as if it had 1024 pixels of width and then scale it down to fit the screen. Media queries alone won’t fix this problem.

However, there is a solution.

The viewport meta tag allows you to tell browsers how to scale the web page. Most mobile browsers understand this tag including the mobile version of Safari found on may Apple devices and the mobile version of Opera which is found just about everywhere else. So to fix the mobile browser scaling issues, just include the following META tag into your web page:

<meta name="viewport" content="width=device-width; initial-scale=1.0;">

This tag tells the browser to render the web page with a 1-to-1 pixel scaling. Meaning 1 pixel of your web site is 1 pixel on the device’s screen. There are many other attributes you can include in this META tag such as maximum and minimum scaling values or whether the user is allowed to scale the page. Disabling user scaling effectively disables the pinch-zoom feature of many mobile devices. I recommend against it.

One last thing to touch upon before I give you a working example. It’s a simple block of CSS that will help make everything run much more smoothly on a mobile browser:

img { max-width: 100%; }

This little CSS rule allows images to shrink as needed as their containing element shrinks. So a 600 pixel wide image will shrink enough to fit on a 480 pixel wide browser. It’s a cheap, but very useful trick. However I would suggest that you don’t use the exact CSS rule given above. To apply such a thing to all images may have unexpected negative effects on images that you don’t want to have shrink as needed. Instead use a more specific CSS selector such as

#frame .blog-post .post-content img { max-width: 100%; }

The more specific you are, the less surprises you’ll have down the road.

As promised, I have put together a demonstration web page that utilizes all these techniques. Grab a modern browser that isn’t Internet Explorer, open the layout, and start shrinking and growing your browser’s window to see the content and layout change to fit within the width of your window. Pop it open on your smartphone’s browser as well!

MARS: Responsive Layout Demo

The stylesheet is embedded in the source to encourage you to take a look at the whole source for the page. It has also been given some CSS hacks so that the layout will work even in IE 7 and IE 6 (in theory), but all the media query stuff will obviously not work.

One final note.

At home I have a very wide (16:10) monitor, while at work I have a standard (4:3) monitor. I like to set max-widths to my layouts because keeping the distance from end to end of a given line of text small helps reduce eyestrain and the whitespace on either side of the layouts is more visually pleasing. But on a very wide monitor, the whitespace on the sides is too much and it makes the layout look very small. With media queries I can fix this problem by increasing the max-width of my layout frame for those screens with a very large width (over 1280 pixels). I could also increase the font size to help with readability. The point is that media queries aren’t just for keeping your pages usable on a smartphone, but they also help keep them usable on very large screens as well.

A Brief Ping

It’s been nearly half a year since my last post and that needs to be rectified.

There are a few things worth talking about such as the situation with the HTML spec. W3C maintains one HTML spec, while WHATWG maintains another. They were playing nicely, but there’s been a small shake-up recently with WHATWG deciding to drop version numbers from the spec, while the W3C will continue to call the latest spec HTML5. How the hell did we wind up in this situation? Well WHATWG has a great piece in their HTML spec that gives a brief history of the HTML spec. It’s not too long and very much worth reading to get an idea of where HTML came from and where it’s going.

News web sites tend to have a template ready to go whenever there’s “breaking news”. It’s often a big, brightly colored box with bold text usually stating “BREAKING NEWS”. This is quite an attention getter. A fact that is not lost on modern news web site developers. Lately “BREAKING NEWS” web stingers are being used to report extremely mundane news. The reason they are using these stingers at all is to simply grab your attention and get you to click through to read the full story. The problem is these news sites are quickly diluting the news value of their “BREAKING NEWS” stingers and sooner rather than later we’ll start to ignore them alltogether. So what will news web sites do when real breaking news happens? I have some thoughts on that which I’ll save for a later blog post, but it’s something to consider.

A small gift to those who have read this far. Here is a template I put together last week to test palette options. This isn’t a layout. You could use it for a web site, but I haven’t done anything to make it compatible with older browsers. It’s more just to test potential color palettes for web sites. And a great place to find palettes is COLOURlovers.

Now that I’ve given away one of my design secrets, I’m off. I expect there will be less of a delay between this and my next post.

A Look Into The Crystal Ball

“The Cloud” is a buzzword meaning third-party hosted internet applications.

To the individual this means being able to manage your content from any location that provides some form of internet access. Things like gmail, Google Docs, Flickr, WordPress.com and YouTube are examples.

To the corporation it’s a form of outsourcing. Gone are the days of large data centers to manage corporate information. Now the information is stored in the cloud. Now it’s someone else’s nightmare to manage.

It’s also a security nightmare for those who dare to take a moment to consider the security costs rather than the monetary costs associated with “the cloud”. You lose control of your information. You’re putting it into the hands of a third-party. You may have a contract with them that makes them responsible for any security breaches. In fact some managers prefer the cloud specifically because there’s a security contract that, in legal form at least, takes responsibility off their heads. But that doesn’t mean a security breach won’t happen. And when it does, when the genie is out of the bottle, what becomes more significant, that the information is out there or that you’re not going to get fired?

Sadly, I think most IT managers would answer the latter.

Privacy is one aspect of security, but it’s a concept that’s slowly starting to catch on. The public is slowly and painfully becoming aware that putting all their information out on third-party sites, that probably doesn’t have the individual’s best interests in mind, is a bad idea. The recent stir surrounding Facebook’s privacy issues is one example of this.

And as much as I would love to see this catch hold and become a driving force that tears apart “The Cloud” and everything “2.0”, it won’t. People will be quick to forgive or forget or to tolerate those privacy issues in return for easy access to information and entertainment.

“The Cloud” is probably not going to go away. In fact, it’s probably going to be the future. And it will be incredibly attractive.

I’m going to focus mainly on “the Cloud” from the individual perspective.

Imagine an iTunes subscription. You could stream any music you want to any device you have, be it your phone while on the way to work or a tablet while you’re at home reading a book on it or a set-top box at your friend’s house who needs some background music for his or her party. Or from your hotel room while on a trip. You don’t have to carry any actual electronic device with you. Your music is in “The Cloud” and you can stream it from any electronic device.

Now apply the same idea to NetFlix or Hulu. Actually, NetFlix and Hulu (in many ways) already do exactly this.

E-mail? Photos? Documents? Gmail. Flickr. Google Docs.

All your information is in “The Cloud”. Ready for you to pull it up on any internet-enabled device, from your iPhone to a computer in an internet cafe halfway around the world.

This type of access already exists, but the interface is too clunky. I imagine a near future with some sort of set top device that you plug into a television that would provide all of this for you. It would become a common feature at most hotels and certainly everyone from grandma on down would have one in their house. No real computer needed anymore, just a thin client with a web browser and maybe a hardware video decoder.

And for the high-end user there would be the portable device. Something like an iPhone4 but with extra features like a micro projector to watch movies on the wall (who needs a TV?) and a small suction-cup device that turns any flat surface (window, table, etc) into a large speaker to provide clear sound.

There would be movie parties. Where everyone would sign into a private room on NetFlix and could watch the same movie and talk to each other, while each person sits in their own room separated by hundreds of miles.

Friendships would no longer need face-to-face meetings. Everyone becomes an avatar. A projected personality that may or may not relate to the individual’s physical presence.

Soon meetings would be conducted in a similar fashion. No longer do we need a boardroom, simply start up your telepresence app and everyone sees and hears each other without ever having to leave their cubicle.

Of course in such a world a room full of cubicles with dozens of separate conversations going on would create quite a bit of background noise and interference. Which is why cubicles would become something more like miniature offices with sound proofs walls and no windows.

You don’t really need to see outside. Just start up the local weather app to project an image of what it looks like outside; tailor-made to your preferred surroundings of a wooded area or urban setting.

Eventually such archaic devices like projectors, speakers, and microphones will be made obsolete with brain implants. Telepresence becomes more real. You don’t just see, you feel and smell and taste and touch. Physical contact with others can be achieved even though your thousands of miles apart.

The porn industry reaches its full potential. It’s not prostitution anymore, it’s all virtual. Every depraved and deviant fetish is now catered to, and it’s all virtual, it’s all fake. But it will feel very real. And what is real, but signals processed by your brain. It is real.

And one day some alien race might finally find our planet. Perhaps touch down and have a look around. They’ll walk the halls of large buildings filled with small, personal-refrigerator sized cubicles. Automated machines keep everything running smoothly. Perhaps interest gets the better of them. They peek inside one of the refrigerators and find a curious gray mass in a container of goo with some probes.

Say hello, then, to your grandchildren a million years from now.

In The Zone With Time

The account-expires attribute in Active Directory carries a value of time in 100 nanosecond units since January 1, 1601 00:00 UTC. In fact quite a lot of Microsoft products are now using this epoch. Java and Unix use January 1, 1970 00:00 UTC as their epoch.

This is important information if you’re ever going to develop code in ColdFusion that needs to, for example, figure out whether or not a domain account has expired.

Another piece of information that’s handy to have is an understanding of how ColdFusion handles large numbers. Numeric values are handled as signed 32-bit values that can range from -2,147,483,648 to 2,147,483,647. ColdFusion can handle much larger numbers, but it does so by converting numeric values into strings and then using its own library to handle math operations based on these strings. And it stores these large values in scientific notation. The problem with this is you start to lose precision. For example, if you run the following CF snippet:

<cfoutput>#( 2147483648 * 2147483648 )#</cfoutput><br>
<cfoutput>#( 2147483648 * 2147483648 + 1)#</cfoutput>

The output is the same for both operations, “4.61168601843E+018“. This loss of precision makes it impossible to calculate the exact time account-expires refers to. So what else can we do?

One trick that sort of works is to divide the value in account-expires
by 10000000 to convert from 100 nanoseconds to seconds. This will significantly shorten the number. So let’s try that on an account-expires value of “129247307050000000” (that’s 7/27/10 @2:58.25 EDT). The line of CF looks like this:

<cfoutput>#DateAdd( "s", ( 129247307050000000 / 10000000 ), "01/01/1601 12:00 AM")#</cfoutput>

Try to run this code and you get the error message “Cannot convert the value 1.2924730705E10 to an integer because it cannot fit inside an integer.”. It turns out that DateAdd() can’t handle a number larger than 2147483647 (the limit of a 32-bit signed integer). 2,147,483,647 seconds is about 70 years of time. To use DateAdd() we need to make the account-expires value much smaller. We could, for example, calculate the account-expires value with respect to a different epoch, one that’s within 70 years of the time referenced by account-expires. We could use any date we want, but I’m going to stick with Java’s epoch of January 1, 1970 to keep things in-line with what’s probably the most common epoch among computer systems.

The number of seconds between January 1, 1601 and January 1, 1970 is 11,644,473,600. If we plug this into the code above we get this:

<cfoutput>#DateAdd( "s", ( 129247307050000000 / 10000000 ) - 11644473600, "01/01/1970 12:00 AM")#</cfoutput>

Run this and we get a result! Specifically {ts '2010-07-27 19:58:25'}. Remember this is in UTC, we’ll need to convert to our local timezone. We’ll do that in just a moment. But first…

You should have recognized by now that this solution won’t work forever. It will fail whenever the data in account-expires is after January 19, 2038. Perhaps this doesn’t bother you since whatever applications you’re developing now will surely be either obsolete or running on a more modern ColdFusion system where DateAdd() can deal with larger numbers before account-expires with that large a value are in use.

Perhaps. But I hate making assumptions like that. Plan for the future! Assume nothing!

If we want lasting code free of the 2038 limitation we’ll need to steer clear of ColdFusion date and time functions. We can do this by using Java objects, specifically java.util.Calendar to manage date and time, and java.math.BigInteger to handle the very large numbers we’ll be working with.

The process is fairly straightforward, but there are a few things to watch out for. Java time is measured in milliseconds, not 100 nanoseconds, so we’ll have to do some conversion. Java and Microsoft’s epochs are different. Calendar objects with a date and time earlier than Java’s epoch will have a negative millisecond value. And we need to calculate this date/time with respect to UTC (GMT timezone) not the local timezone.

First create a BigInteger object. Initialize it to the value of account-expires, and then convert it to milliseconds as that’s the unit of time Java likes to work with.

01: <cfset variables.bigInt = CreateObject( "java", "java.math.BigInteger" ) />
02: <cfset variables.expTime = variables.bigInt.init( JavaCast( "String", "#arguments.accountExpires#" )) />
03: <cfset variables.expTime = variables.expTime.divide( variables.bigInt.valueOf( "10000" )) />

You can initialize BigInteger objects with strings and numerical values. I’m specifically casting account-expires as a string so that ColdFusion doesn’t treat it like an integer and try to put it into scientific notation. Note in line 3 the use of BigInteger’s valueOf() function. This takes a string and returns a BigInteger value. Math functions for BigInteger objects require BitInteger arguments, thus we need to pass all values (even static ones) through valueOf() instead of JavaCast().

Next we set up the calendar object. This means creating a java.util.TimeZone object, a java.util.Calendar object, and then initializing the calendar to the GMT timezone. Once the calendar object is initialized we set it to Microsoft’s epoch.

04: <cfset variables.tz = CreateObject( "java", "java.util.TimeZone" ) />
05: <cfset variables.Calendar = CreateObject( "java", "java.util.Calendar" ) />
06: <cfset variables.gCal = variables.Calendar.getInstance( tz.getTimeZone( "GMT" )) />
07: <cfset variables.gCal.set( 1601, 0, 1, 0, 0, 0 ) />

Note that the second argument of the calendar object’s set() function is 0. Java’s calendar object’s month index begins with 0 for January instead of 1. This is something to be aware of whenever dealing with Java calendar objects.

This next step requires a little explanation. variables.expTime is now in milliseconds thanks to line 3. I’m going to add the value of the calendar, in milliseconds, to variables.expTime. Because the calendar is set to a date before Java’s epoch it will actually be a negative number. The addition operation is actually a subtraction operation. The resulting value of variables.expTime will be the number of milliseconds since Java’s epoch.

08: <cfset variables.expTime = variables.expTime.add( variables.bigInt.valueOf( "#variables.gCal.getTimeInMillis()#" )) />

All we need to do now is reset the calendar to the value we now have in variables.expTime, then convert it to our local timezone and we’re done!

09: <cfset variables.gCal.setTimeInMillis( variables.expTime.longValue() ) />
10: <cfset variables.gCal.setTimeZone( tz.getDefault() ) />

Last, but not least, we convert the calendar object into a ColdFusion date/time object with ColdFusion’s CreateDateTime() function.

11: <cfset variables.expDateTime = CreateDateTime(
variables.gCal.get( variables.gCal.YEAR ),
variables.gCal.get( variables.gCal.MONTH ) + 1 ,
variables.gCal.get( variables.gCal.DAY_OF_MONTH ),
variables.gCal.get( variables.gCal.HOUR_OF_DAY ),
variables.gCal.get( variables.gCal.MINUTE ),
variables.gCal.get( variables.gCal.SECOND )
) />

Note that I’m adding 1 to the month variable because in Java 0 = January, but in ColdFusion 1 = January.

And there you have it. Converting from Microsoft’s 01/01/1601 100 nanosecond based timestamps to something a bit more usable in ColdFusion.

Of course you’ll need a reverse of this process as well, and I’ve already got that for you:

01:  <cfset variables.tz = CreateObject( "java", "java.util.TimeZone" ) />
02:  <cfset variables.Calendar = CreateObject( "java", "java.util.Calendar" ) />
03:  <cfset variables.gCal = variables.Calendar.getInstance( tz.getDefault() ) />
04:  <cfset variables.gCal.set(
Year( arguments.Date ),
Month( arguments.Date ) - 1,
Day( arguments.Date ),
Hour( arguments.Date ),
Minute( arguments.Date ),
Second( arguments.Date )
) />
05: <cfset variables.bigInt = CreateObject( "java", "java.math.BigInteger" ) />
06: <cfset variables.expTime = variables.bigInt.init( JavaCast( "String", "#variables.gCal.getTimeInMillis()#" )) />
07: <cfset variables.expTime = variables.bigInt.divide( variables.bigInt.valueOf( "1000" )) />
08: <cfset variables.expTime = variables.expTime.add( variables.bigInt.valueOf( "11644473600" )) />
09: <cfset variables.expTime = variables.expTime.multiply( variables.bigInt.valueOf( "10000000" )) />
10: <cfreturn variables.expTime.longValue() />

You should be able to follow along based on my explanation earlier in the article. However there are a couple extra bits I’d like to point out.

The calendar is initialized to the local timezone. We don’t have to worry about converting back to UTC/GMT because the calendar function getTimeInMillis() will give you the number of milliseconds from Java’s epoch, which is in UTC.

On line 8 I’m adding the number of seconds from Microsoft’s epoch to Java’s epoch. You’ll also notice the line before that I’m dividing by 1000 to convert time from milliseconds to seconds and after I add the epoch difference I’m converting to 100 nanoseconds by multiplying by 10000000. So why not skip the conversion to seconds and simply add three more zeroes to the end of the epoch difference (making the time in milliseconds) and multiplying by 10000?

The reason is that there’s a problem with precision and the resulting value will vary by a few hundred milliseconds. Since the times I’m working with are in seconds, those extra milliseconds could be ignored. But by dividing, adding, and then multiplying like this I don’t get the millisecond variances. I’m sure there’s better stuff on the ‘net to explain precision with BigInteger objects if you’re inclined to investigate further.

Before you go I have one piece of information I learned while working on this particular topic.

ColdFusion treats all date and time values as if they are in the local timezone. Specifically, if your timezone has daylight savings then all dates are treated as if they have daylight savings, including GMT/UTC times which do NOT have daylight savings time. DateConvert() will not protect you from this issue. There’s a deeper explanation here.

My solution is to check if GetTimeZoneInfo().isDSTon is TRUE. If it is then I need to add (or subtract) 1 hour from my UTC time. Note that this is only needed when converting between UTC and local timezones with ColdFusion date and time functions. The above code specifically stays away from ColdFusion date and time functions so this isn’t a problem with my example. But it is something to keep in the back of your head when you start to notice dates are being calculated an hour off the time they should be.