tachyonskenneth

A little more than a month ago we shipped a redesigned version of our homepage, http://rescale.com. During its development, we thought it would be a good time to reevaluate the way we were writing our CSS.

At the time, our main CSS file was more than 2000 lines long, written in the classic semantic-class-names style (e.g. the news section gets the .news class) with a couple of utility classes here and there.

From skimming our CSS code, we felt a little uneasy going into this redesign because 1) many of the CSS classes we had written were probably not reusable in the new design, so we were going to end up adding a lot more CSS, and 2) there were going to be a lot more responsive components, and the way we were writing responsive CSS was difficult to follow and change.

One of the major pain points with our old CSS was that it was very hard to visualize how an element with a particular CSS class would behave on different screen sizes just from reading the source code. This arose because our media-query sections were separated by hundreds of lines of CSS. For example, with this CSS:

If we were reading the .footer class under one of the media queries, it would be very difficult to remember what was in the base class, what base properties were being overridden, and which media query block we were even in. Adding more classes would only exacerbate the problem.

Around that time we stumbled across the Tachyons CSS library and an article written by its creator, Adam Morse, titled CSS and Scalability.

In it, Adam argues that the crux of CSS scalability and reusability problems is the use of semantic class name, and with such a system, we will never stop writing CSS.

Here are some of the most intriguing points made in that article:

If you’re going to build a new component, or change a piece of UI in your app – what do you do? I don’t know anyone that reads all the available CSS in the app to see if there is something they can reuse.

If you are starting from the assumption that your CSS isn’t reusable, your first instinct is to write new CSS. But most likely you aren’t creating a new classification of visual styles. In my experience it is likely that you are replicating visual styles that already exist.

In this model, you will never stop writing CSS. Refactoring CSS is hard and time consuming. Deleting unused CSS is hard and time consuming. And more often than not – it’s not work people are excited to do. So what happens? People keep writing more and more CSS.

With that, we adopted the Tachyons library and were amazed by how little CSS we had to write in order to implement our redesign, and that implementing responsive designs was fun again.

Tachyons comes with a bunch of CSS classes, each of which contains only one property. For example, .fl defines float: left. Furthermore, for each class there are classes with responsive modifiers. For example. .fl-ns means only apply float: left when the screen size is “not small”, or above 480px.

We use these classes as building blocks for components. For example, here’s one column of a responsive 4 column layout:

That says, float left and take up 50% of the width when the screen is bigger than “not small”, and take up 25% of the width when the screen is bigger than “medium”. If it’s smaller than “not small”, then use the default behavior of a div, which is to takes up 100% of the width.

The other thing Tachyons buys us is a set of predefined font sizes and padding/margin spacings also known as font and spacing scales. This system has some pros and cons.

One of the biggest pros is that we spend a lot less time deciding on sizes. For example, prior to adopting Tachyons, we would often ask ourselves if a particular section should use a font size of 16px or 18px, or should the padding be 8px or 10px. Tachyons reduces the number of decisions while increasing consistency.

The con is, of course, when we want to use a size not on these scales. The way we handle this is just to inline the style because usually they’re not going to be reused anyways so there’s no reason these one-off styles should be in CSS.

The other problem is there will be repetition of elements with the same classes, usually among sibling elements. For the 4 column component above, we would have repeated it 4 times. This is a minor issue for code editors with multiple cursors. If it becomes a problem we can use a template system for abstract away the components.

Overall, we think this is the right direction that CSS systems for scalability is heading. In other words, the best way to scale CSS is to stop writing CSS.

This article was written by Kenneth Chung.

ryanblogpost (1)
The web is the preferred delivery mechanism for most applications these days but there are scenarios where you might want to build a CLI or desktop application for your customers to use. However, once you leave the cozy confines of the browser there are a whole slew of proxy configurations that your poor application will have to deal with if it needs to run within a typical corporate network.

For the purposes of this post, “typical corporate network” means your users are running some flavor of Windows and are sitting behind an authenticating HTTP proxy. While this does seem like a pretty common setup, a surprising number of applications will simply not work in this environment.

Thankfully, when writing a .NET application, the default settings get you most of the way there for free. The default web proxy will automatically use whatever proxy settings the user has configured in IE. If possible, this is what you should rely on. It is tempting to expose proxy hostname and port configuration values that the user can pass to the application, however in some cases a corporate user may not have a single well-known proxy to use. WPAD and PAC files allow proxies to be configured dynamically. See this post for more gory details.

Unfortunately, the default settings do not handle authentication for you out-of-the-box. Web requests will typically fail with a 407 ProxyAuthenticationRequired error. The next step is to examine the Proxy-Authenticate response header returned to see what type of authentication the proxy accepts. Typically this will be some combination of Basic, Digest, NTLM, or Negotiate. If the proxy supports either NTLM or Negotiate, then it is possible to automatically authenticate the signed in user running your application by simply adding the useDefaultCredentials=true attribute to your app.config as described here:

This is particularly nice because we don’t have to modify any of our application code nor deal with the headaches of dealing with credential management. Alas, this won’t work if the proxy is configured to use Basic or Digest authentication. While this is an unusual setup, it is something that you will come across in the wild every so often. If this is the case then you will need a way to read in a username and password and then store that in the IWebProxy.Credentials property. As pointed out here, this setup is not typically used because it puts the burden on every application to manage proxy credentials.

In C#, the default proxy settings configured in the app.config are reflected in the WebRequest.DefaultWebProxy static variable. Rather than directly modifying its Credentials, it is cleaner to create a decorator for the proxy that passes through the read requests but manages its own set of credentials without touching the underlying proxy:

Then, you can do something like the following to use the default proxy settings with custom credentials:

This lets you easily switch back to the original credentials that were configured in the app.config or use a different set as needed.

Note that while all of this is pretty straightforward for people using .NET, it might not be as easy to support authenticating proxies (particularly ones that only use NTLM and Negotiate) in http libraries used in other languages. In these scenarios, some people have had success using cntlm as a proxy for the authenticating proxy.

TL;DR: For people writing applications in .NET, you should simply set useDefaultCredentials=true in your app.config file and that should “just work” most of the time.

This article was written by Ryan Kaneshiro.