Home > CSS Blog > 5 Ways To Optimize Your CSS

5 Ways To Optimize Your CSS

March 21st, 2009

5 Ways To Optimize Your CSS



Recently I have been working on a social networking site that was experiencing downtime due to the amount of stress its users were putting on the server. I spent a good amount of time looking for ways to improve the speed of the site, and one of this was through CSS optimization.

Structure your CSS and HTML elegantly
“CSS” Stands for Cascading Style Sheets. Notice the first word, “Cascading”? The power of this language is readily available, and it is up to you, the designer, to maximize its use. It is an interesting concept that is not too difficult to grasp. Try to find instances wherein this can be applied.

For example, the code below:

<p class="someClass">First</p>
<p class="someClass">Second</p>
<p class="someClass">Third</p>
<p class="someClass">Forth</p>
<p class="someClass">Fifth</p>

Can be rewritten this way:

<div class="someClass">
<p>First</p>
<p>Second</p>
<p>Third</p>
<p>Forth</p>
<p>Fifth</p>
</div>

But what if our code looks like this:

<p class="firstClass">First</p>
<p class="someClass">Second</p>
<p class="someClass">Third</p>
<p class="someClass">Forth</p>
<p class="someClass">Fifth</p>

We can take advantage of CSS by rewriting HTML this way:

<div class="someClass">
<p class="firstClass">First</p>
<p>Second</p>
<p>Third</p>
<p>Forth</p>
<p>Fifth</p>
</div>

Then, cascade rules defined in “firstClass” to overwrite styling principles in “someClass”.

This is just one simple example, and I hope you understand what I’m trying to get at. Just keep in mind the concept of cascading rules and it won’t be long before things like this become second nature and automatic.

Re-structure your CSS
I am a huge fan of single line CSS style. Not only does it save up space, it is also more readable. The readability bit is debatable, though. Simply put, I find it easier to locate relevant tags if the tag names are all on the same left-hand side and I do not have to scroll so much to find what I need to change. After all, designers are only concerned with CSS selectors, not the rules that are applied to it.

Optimize Your CSS
Some time ago, I wrote an article about improving website performance using CSS optimizers. I still use CSS Optimiser up to this day. For very large CSS files it is a quick and easy way to rewrite things that may otherwise prove too time-consuming to optimize manuallyt.

Use CSS Shorthand Rules
When I was still learning CSS, I found shorthand rules to be quite daunting and confusing at times. But I strived to learn the shorthand syntax for every rule simply because I am lazy and do not want to bother typing the same thing over and over not to mention having to memorize all the rule names.

Compare the example longhand its equivalent shorthand below.

Original longhand:

#someid {
background-attachment: fixed;
background-color: #000000;
background-image: url(images/image.png);
background-repeat: no-repeat;
background-position: left bottom;
}

Shorthand version:

#someid { background: #000 url(images/image.png) no-repeat fixed left bottom; }

The folks over at SitePoint has a good introduction to the art of CSS Shorthand that I can recommend to anyone who’s willing to learn.

Server-side Compression
Server-side compression techniques have long been put to use by large scale applications for two main reasons. First, bandwidth is precious and expensive. Second, it does not require having to modify code for it to work. What it does require, however, is supported server software (or hardware). Hence the term “server-side”.

One such solution can easily be deployed on Apache servers. Once again SitePoint has written an introduction to server-side compression using Apache and mod_gzip.

The drawback to this is increased CPU load. Indeed, server-side compression is a double-edged sword, but usually the pros far outweigh the cons.

Share

Read More


Similar Posts

    Introduction to Cascading Style Sheets Rules

    An introduction to Cascading Style Sheets rules for Web pages. <META NAME … What is a CSS rule? Linking to external style sheet. Using In-line Style …

    Source

    8 methods to bring your front end coding to rockstar levels

    There are a lot of good front end developers out their right now. If you fancy yourself as a front end editor then you really should be looking at how you can differentiate yourself from the rest. Yes there are lots of “good” front end developers, but there are not a whole lot of excellent front end developers.

    1. Improve Your Semantic Names

    If you work in a team or ever revisit your code and need to update it then you should think about the quality of your class and ID names. It is not uncommon for developers to use class names like “box”, “wrapper”, or “container.” While you may think that these naming conventions or “semanitc enough” none of them describe the content that is inside them. Instead consider using HTML5 spec’s such as “content-sub”, “section”, “content-aside” or “content-sup.”

    You and your team will have a much easier time sorting through code that describes the content than trying to remember the details of “box.”

    Read more about semantic naming from Andy Clarke and A List Apart.

    2. Improve the Organization of Your Files

    I think it is reasonable safe to assume that most developers have at least started to organize their files by type (ie: a folder for images, css, javascript, etc…). You can go a step further and improve the organization even more, particularly any folder that is going to have a lot of files (such as Images in particular and CSS as a secondary.)

    I find it best to create sub folders with in images and separate images based on design structure, buttons, headlines, photos, etc…

    There are plenty of other folders you may want to create to keep the updating and growth of a site easy and efficient, including:

    • Documents
    • Client files
    • Copy
    • Proofs
    • Staged/Development area (folder for a “clone of the site” where you can make changes and get sign off)
    • Downloads

    The Elements CSS Framework does a great job of organizing files based on the normal client/provider workflow.

    3. Use Commenting in Your XHTML

    Any time you end up developing complex layouts you are bound to use a lot of <div>s in your markup. This can be particularly confusing to go back and edit as it becomes hard to figure out which div is being closed where. You may see three </div>s all in a row.

    To combat this simply add some coments at each </div> (or any other closing element if you find that it will be helpful) to let you know what element was just closed.

    
         <div id="header" class="section">
              <div id="header-logo">
                   <h1>HTMLiZER</h1>
              </div><!--/#header-logo-->
         </div><!--/#header-->
    

    If you find it useful you can take it one step further and comment the primary area you would be editing (such as the main content area, sidebar, etc…)

    4. Segment Your CSS

    For small 4 – 5 page brochure sites your CSS will be pretty manageable even if you don’t spend the time and effort you should into organizing and commenting. Once you start developing web applications or large sites with a vast array of design “modules” you should make sure that you organize your CSS in way that is easy to manage.

    I recommend splitting your css into logical different files for better organization, such as:

    • reset.css
    • main.css
    • structure.css
    • typography.css
    • print.css
    • helpers.css

    This way you don’t have to sort through all of the typography styling to find the area where you defined the size of the header. Likewise if you want to adjust the headings it is pretty simple to find it through a small typography.css file rather than a huge file that has everything.

    5. Create a TOC With Comments in Your CSS

    Every CSS file you plan on editing and extending over time should have a table of contents at the begining and a headline seperator at every section. This will allow you to easily jump to a section using “find” rather than scrolling for that one area that had the CSS you are hoping to modify.

    EX

    /***********

    TOC:

    =1: Header
    =2: Content
    =3: Footer
    =4: Navigation
    =5: Portfolio

    ****************/

    /* *********  =1: HEADER *********** */

    #header { … }

    6. Compress and Combine Your CSS files

    Even though it is easier to work on a site when you segment and organize your css into several different file names, it actually causes your site to load slower. The more calls the browser has to make to the server for additional files the slower it will load.

    Before deploying your css files you should combine and compress them. Compressing them removes any uncessary whitespace, comments, etc… that is unnecissary when the site is live.

    There are several handy tools to do this including this online version.

    7. Create your own framework (or improve on another one)

    As you get more experience under your belt you will find that you use the same methods and naming conventions over and over. This is helpful for several reasons and it should be encouraged. It has lots of benefits including:

    • More consistant rendering due to reusing ideal CSS techniques
    • Easier editing and maintenance as you can better recall what names mean
    • The start of code that can be saved and reused every time

    Chances are that you end up rewriting the same type of code over and over again, simply because you don’t have it stored somewhere. Some examples may be:

    • A class that floats an image left / right and gives it some margin
    • The structure for an unordered list navigation
    • The structure for a form
    • external link, pdf and download icons
    • clearfix
    • png fix
    • Typeography baselines and hierarchies
    • etc…

    Rather than reusing these bits of codes write modules into your own CSS framework (or you could imrpove on another one). This way you can streamline the development process so it takes less time and improve the consistancy of your work.

    8. Develop your CSS to be modular or “object oriented”

    You could assign every bit of code an unique ID or adjust the margins and padding per instance. Lots of coders do this to try and get the CSS as close to the designers comp as possible. However this is inefficient in development time and file size. Establish a set rule for differnt types of content and how they should be styled, this should include basic things such as:

    • Font sizing (all normal text is 12px, featured text is 14px bold)
    • Margin’s (normal margin is 10px between elements, margin between two content blocks is 40px, etc…)
    • All navigation tabs will have 15px height and 13px font
    • etc…

    This way you don’t have to rewrite the code for every new item added to the site. Additionally it will keep the site feeling consistant and well balanced visually. If all elements and every page follows the same rhythm it will feel more unified as a whole.

    Some call this object oriented css, it is worth looking into for rockstar like front end coding.

    Read More

    15 Surefire Ways to Break Your CSS

    'Fixed' by Don Fulano. Used under a Creative Commons license.

    The life of a CSS developer isn’t all about attending glamorous champagne parties, jet-setting around the world and hanging out with supermodels. In fact, when your CSS doesn’t behave the way it should, the job can be downright tedious. I’ve spent untold hours of my life debugging my code — and I’m guessing I’m not alone here.

    But as silly as it may seem, some of the biggest CSS blunders stem from the simplest of errors. Knowing what some of those errors are and remembering to look for them can save you hours of wasted labor. Here are fifteen ways I’ve found to break my CSS for sure — and fifteen things I always look for whenever I have a problem in my code.

    Missing a Semicolon

    CSS rules are comprised of property-value pairs (declarations) followed by a semicolon. Accordng to the CSS specification, the last declaration doesn’t need a semicolon — because the closing brace effectively ends the declaration just as well. That means something like this is perfectly acceptable:

    body {
    	background-color: #444;
    	color: #eee }

    The only problem is, as soon as you decide to add another declaration to your previous rule, you’ve now made it all too easy to forget to add the semicolon to your once-last rule:

    body {
    	background-color: #444;
    	color: #eee
    font-family: Helvetica, Arial, sans-serif }

    The result? Your font-family rule never gets applied, because the parser reads “font-family” as part of the color value. Which is why I make a habit of adding the final semicolon in a rule, no matter what.

    Missing a Colon

    I’ve seen this particular problem crop up frequently while teaching classes on CSS. People get excited when CSS starts to make sense, and their typing speed increases. The downside: this makes errors of omission much more likely. And a missing colon is particularly tough to see, since it sits right in the middle of a declaration. Consider the following two lines:

    body { font-family Helvetica, Arial, sans-serif; }
    body { font-family: Helvetica, Arial, sans-serif; }

    It’s easy to see how the colon could get overlooked in the jumble of braces, hyphens, semicolons and cryptic words. As a rule of thumb, if you only have one declaration not behaving itself, this is a good place to start looking.

    Missing a Brace

    {Braces} around a CSS rule are like the circle of life: regular, natural, and expected. And if you ever miss a brace (generally a closing brace for whatever reason) — just like if you have a zombified corpse that refuses to die — you suddenly have all sorts of mayhem on your hands.

    When an unsuspecting browser comes across a pair of rules like this:

    body {
    	font-family: Helvetica, Arial, sans-serif;
    #wrap {
    	width: 960px; }

    The browser is going to choke. Two opening braces before a closing brace is right out: everything from your #wrap rule (in this example) on would be ignored.

    However, this does make debugging easier. Do you have a whole chunk of CSS being ignored? Which is the first rule that is being neglected? There’s a good chance you have an uneven number of braces hanging out in the vicinity.

    Misspelled Properties

    I consider the following few errors the bane of dyslexic developers everywhere. Generally speaking, I’m a good speller. But when I’m “in the zone” and typing as fast as my fingers can carry me, I tend to transpose a few letters here and there. In writing, this isn’t such a big deal: people can generally figure out what I mean. Computers, sadly, are less discerning.

    div { border-bototm: 5px; }

    Now, I have no idea what a “bototm” is, but I do know I write the word at least one time in five when I’m trying to refer to the lower edge of an element. I’m lucky in that I have a decent eye for editing and often catch these mistakes as I make them. If you’re not so fortunate, using a program with code coloring like Notepad++ or Adobe Dreamweaver (my personal favorite) can make the job a lot easier: if a property isn’t colored like the other properties, than it’s probably not much of a property at all.

    Misspelled Values

    Misspellings aren’t limited to just properties. And sometimes a misspelled value can be even more difficult to notice:

    #wrap { padding: 10px 20pz 25px 20px; }

    Unfortunately for the rule above, I’m fairly sure only Snoop Dogg and I have ever tried to measure elements in pizzles. Instead of the generous padding you’d expect this rule to generate, this one misspelled unit renders the entire declaration invalid.

    Misspelled Classes and IDs

    No matter how often I create a div with an ID of “navigation,” I still find myself writing rules that look more like this:

    #navigaiton { float: left; } 

    This can be a frustrating error to track down, because color-coded editors won’t help you out here: you could just as easily purposefully name an element “navigaiton” if you really wanted. But I’d recommend against it.

    Improperly Ordered Values

    Some CSS properties have a built-in shorthand, which is a great way to save yourself a few lines of code. Unfortunately, most of the shorthand properties are very picky about the order of the property’s values. For example:

    div { font: 2em Helvetica, Arial, sans-serif; }
    a { font: "Times New Roman", serif 1.5em; }

    The first rule will result in all divs gaining a specific typeface and size. The second rule will result in a debugging session — while it’s okay to leave some values out of the font declaration, changing up the order of the values will result in problems.

    Measurement Values Without Units

    CSS Newbie reader Justin reminded me of this problem the last time I wrote about CSS faux pas. With only a few limited exceptions, all measurement values in CSS need a unit of measurement associated with it. Take the following rule for example:

    #wrap { margin: 3; }

    Three what? Ems? Inches? Pizzles? The flexibility of CSS that allows us to pick from several units of measurement also means specifying a unit is fairly important.

    Bonus — Two unit-agnostic measurements:

    1. Values of zero don’t need a unit of measurement. Turns out, zero pixels and zero miles are exactly the same length.
    2. Line heights needn’t have a specific unit. A line height of “1.5″, for example, will simply assume you meant “1.5 times my font size.” For more on this phenomenon, visit Eric Meyer’s article on Unitless Line Heights.

    Competing Identical Rules

    Once a stylesheet gets to be a certain length, it can be difficult to remember which rules you’ve already written unless your CSS is very well organized. And two identical rules at different spots in your CSS file can wreak havoc on your design and sanity alike.

    ul li { margin: 0 2em; }
    ... 300 lines later ...
    ul li { margin: 0; padding: 10px; }

    In this scenario, the latter rule would win out over the former, thus removing the margin and applying padding instead. But if you’ve forgotten about this duplicity, you might go back into your CSS later and try editing the first rule only, and remain perplexed as to why, no matter how you tweak your margin, you can’t seem to make any difference.

    Unintentionally Competing Rules

    A similar problem could force your CSS to compete with itself in ways you didn’t expect. For example, if you had the following code in your XHTML:

    <div id="navigation" class="nav">...</div>

    You could refer to this element by either its class or its ID. The problem arises when you do both, and forget that you’ve done so:

    .nav { width: 50%; }
    ... later in the code ...
    #navigation { width: 500px; }

    This code would result in a fixed-width navigation bar, even though the first rule would suggest a more flexible width. Again, having a well organized stylesheet is the easiest way to avoid this problem.

    Calling a Class an ID (or vice-versa)

    I fall into this particular trap all the time. I’ll write a rule like this:

    .navigation {
    	float: left;
    	width: 100%;
    	height: 4em; }

    And nothing will happen! It often takes me a minute or two to realize that the real problem is that I’d given my navigation bar an ID, not a class. My best advice here is to pick a naming system that works well for you and be consistent. If you always call your top navigation bar “#topnav”, for example, you’re far less likely to misremember your element names.

    Using a Nonexistent Property

    Not all CSS properties are named the most intuitively. For example, this might look like a perfectly acceptable rule to someone new to CSS:

    body { text-size: 3em; }

    The problem is, while there are certainly several text-riffic properties, text-size isn’t one of them. Instead, we use font-size. Which means that the rule above wouldn’t do much of anything. Intelligent code-coloring editors like Dreamweaver usually make this sort of debugging much easier: if it’s not a real CSS property, it won’t be the same color as the surrounding properties. That’s usually my first clue I’ve done something wrong.

    Using a Nonexistent Value

    This is a sister stumbling block to the one above. Some values just seem to make sense, but will fail you nonetheless:

    td { vertical-align: center; }

    You would assume that this rule would vertically center your table text, right? Unfortunately, while “center” is indeed an acceptable value for text-align, vertical-align uses the perhaps less intuitive “middle” instead. And you’d have to ask a better educated rhetorician than me to figure out the difference between middle and center in this context, because I’m at a loss.

    Improperly Matching Properties and Values

    Certain CSS declarations can look correct even to the trained eye, unless that eye is paying particularly close attention. For example:

    a { text-transform: italic; }

    While this might look like a perfectly reasonable rule, you won’t end up with italicized text. That’s because “italic” belongs to the font-style property, not the text-transform property. But even most advanced editors won’t catch that bug, as you’ve used a perfectly reasonable property and value — you’ve just used them in an inappropriate combination.

    Not Closing Comments

    The gentle persons at BlogThemeMachine tipped me off to this common CSS problem. Can you spot the major difference between these two sets of rules?

    /* Navigation goes here. */
    #nav {
    	float: left;
    	width: 100%;
    	height: 3em; }
    /* Navigation goes here. /*
    #nav {
    	float: left;
    	width: 100%;
    	height: 3em; }

    The only difference is that the second rule has an improperly closed comment tag: /* versus */. That seemingly insignificant difference can result in entire swaths of your CSS suddenly not working. In fact, this tiny blunder will negate all your CSS from the start of your comment until you successfully close a second comment. Which if you’re using comments to organize your CSS means an entire section of your site will lose its styling.

    These fifteen tiny blunders are sure to give you hours upon hours of CSS frustration… unless you know to watch for them. What are some other self-introduced bugs you often find in your code? I’d love to hear about them in the comments!

    Read More

    CSS Classes, CSS Tutorial

    Learn Cascading Style Sheets to devlop your skills and optimize your web site with w3c … Grouping elements with class in CSS …

    Source

    CSS3 Multi-Colum Layout Demonstration and Documentation – CSScripting.com

    … css structures (like cascading rules). This is ok: .article { column-count: … that some CSS rules may not work after the multi-column layout is applied. …

    Source

    Using JavaScript to Style Active Navigation Elements

    active navigation element

    I’m all about efficiency when I’m writing web code. Any time I find myself writing the same functionality more than once or twice, I try to consider whether my repeated code could be wrapped into a function of some sort.

    Navigation is often one of those areas where I try to improve my efficiency. I like my navigation elements to pull double duty. I want them to:

    1. Show the user where they can go, and
    2. Show the user where they currently are.

    In other words, I want some sort of visual indication in my navigation that shows my user which section of my site they’re in. You can see this on the CSS Newbie site: if you click on the TOC (Table of Contents) link in the bar at the top of the page, you’ll see that link gets special styling when the table of content loads.

    Now, I could manually set this on every page using a CSS class. But that’s inefficient — depending on the size of my site, I could end up writing dozens or hundreds of lines of one-off code. And why go to all that work, when you could just wrap it all up into a nice JavaScript function?

    First, I’ll explain the logic behind my functions — because they won’t work equally well for every site. Then I’ll walk you through a few examples of the code that makes it all happen.

    The Logic

    All of my functions assume a very clean, straightforward directory structure. For example, if you have an About section, a Blog section, and a Contact section on your site, a logical directory structure might be:

    /
    /about/
    /blog/
    /contact/
    

    And if you had several blog entries inside your blog directory, your structure might grow like this:

    /
    /about/
    /blog/
    /blog/post-one/
    /blog/post-two/
    /blog/post-three/
    /contact/
    

    And therefore, a function could logically assume that anything inside the blog directory should be considered a part of the blog section of your site, and mark the blog link as active for those pages. This makes our job a lot easier. And luckily, most CMS platforms make this sort of directory structure pretty easy to create.

    The functions also assume that you have either a fairly shallow directory structure, or that you’re not linking to too many similarly nested directories. What I mean by this is, if you have this sort of a structure:

    /
    /contact/
    /contact/me/
    /contact/me/here/
    

    And you wanted to link to both /contact/ and /contact/me/here/ in your navigation bar, you might run into problems distinguishing between the two. There are ways to increase precision, but they come at the cost of flexibility.

    But enough of that. Let’s get to the good stuff!

    A JavaScript Solution

    I’ve written about this method before, when I previously talked about building intelligent navigation bars. This technique is nice because it doesn’t rely on any JS frameworks, so you can add it to older sites without needing jQuery or the like. The basic function looks like this:

    function setActive() {
      aObj = document.getElementById('nav').getElementsByTagName('a');
      for(i=0;i<aObj.length;i++) {
        if(document.location.href.indexOf(aObj[i].href)>=0) {
          aObj[i].className='active';
        }
      }
    }

    This function looks for an element with an id of “nav” (presumably your navigation bar), then looks at each of the anchor tags inside it. It then compares the anchor tag’s href tag with the page’s URL. If the href tag is contained within the URL anywhere, it gives that link a class of “active,” which I can then style specially in my CSS.

    As an example of what I mean by all that, if I had an anchor tag in my navigation bar that linked to “/blog/” and the page I was on was “/blog/this-is-a-post.html”, my blog link would be styled as active, because “/blog/” is contained within “/blog/this-is-a-post.html”.

    As a final note, you wouldn’t want to call this function until the page was finished loading: if you call it too soon, your links won’t exist yet! So you can either call it at the very end of your document, or dynamically call it when your page is done loading, with something like this:

    window.onload = setActive;

    A jQuery Solution

    If you are already loading a framework like jQuery (like I do on almost every site I work on these days), this sort of functionality could be written even more succinctly. And like I said earlier, I’m a sucker for efficiency. Here’s a jQuery solution that does essentially the same thing in a much smaller space:

    $(document).ready(function() {
    	$('#nav a[href^="/' + location.pathname.split("/")[1] + '"]').addClass('active');
    });

    This function is making use of both native JavaScript and jQuery tricks to reach a whole new level of brevity. First, the whole thing is wrapped in a “document ready” function, which means it won’t fire until the page is loaded and our links are in place. Next, we’re looking for anchor tags inside our “nav” ID. And really, we’re looking for a very specific anchor tag: one whose href starts with (^=) a slash, followed by a part of our page’s location (location.pathname). Specifically, we’re looking for the first directory in our page’s URL.

    We’re doing this by making use of the JavaScript split() method, which lets us take any string (for example, “/blog/this-is-a-post.html”) and break it into an array based on a substring (in our case, the forward slash). If you’re familiar with PHP, it’s similar to the explode() function. In our example, we’d end up with a three-part array that looked like this:

    ["","blog","this-is-a-post.html"]

    Which means that if we look at the second value of our array (arrays start counting at zero, so [1] is the second value), that should give our first-level directory (”blog”, in our example). This lets us match any subsequent child directories with our parent in the navigation bar.

    Tweaking for Home Links

    Our jQuery function works great in most scenarios, but it fails if you have a “home” link where you’re just pointing to the root directory, like this:

    <a href="/">Home</a>

    And because I tend to have a link like that, I needed a workaround. Here’s a way to get around that with just a little more code to account for our special case:

    $(document).ready(function() {
    	if(location.pathname != "/") {
    		$('#nav a[href^="/' + location.pathname.split("/")[1] + '"]').addClass('active');
    	} else $('#nav a:eq(0)').addClass('active');
    });

    Here, we’re checking to see if we’re in the root directory. If so, we’re skipping the loop through our anchor tags and just making a specific anchor tag active. In this case, I’m giving the active class to the first anchor in our list (which is the most common location for a home link).

    And that’s that. If you know of even more efficient or fool-proof ways to accomplish this task, I’d love to hear about them in the comments section. Or if you’re skilled in a framework other than jQuery, feel free to share the equivalent code!

    Note: I apologize for the long gap between articles. I had some problems while rebuilding my PC (DOA motherboard) and was without my computer for several weeks.

    Read More

    Introduction to CSS, learn CSS with our basic guide to Cascading Style …

    Beginner’s introduction to Cascading Style Sheets (CSS), learn CSS. … There are 3 main ways CSS styles can be applied: Inline with HTML. On-page style definitions …

    Source

    Standardizing CSS class and id names

    Web builders create CSS class and id names to identify divs and other page … These are all valid names for CSS and XHTML classes and ids. …

    Source

    MaKo 4 CSS: CSS Basics – CLASS and ID

    Cascading Style Sheets (CSS) – basic class and id containers … The CSS Discuss List has a very good short introduction at Class vs. ID …

    Source

    Cascading Style Sheets (CSS) Interview with MicroAssist CSS Class …

    Interview on Cascading Style Sheets (CSS) with MicroAssist Austin CSS Class Instructor, Scott Allen … your students learn from your Introduction to CSS Class? …

    Source