The Q v2.0

Welcome to The Q. This is a place where the designers, developers, and marketing experts here at MC² Design can let loose and casually share information about their passions. It's a place where we can rave about the things we love, rant about the things we hate, and hopefully we'll all learn a thing or two along the way.

Opacity CSS Validation Using Javascript

Posted on May 29th, 2009 by Jarrett M. Barnett

I’ve always been annoyed by browser specific CSS properties. Not necessarily because of the purpose browser specific CSS properties serve, but more so the isolation of each property. For instance, applying opacity across multiple browsers requires something like the following:

#selector {
    filter:alpha(opacity=80); /* Internet Explorer */
    -moz-opacity:0.8; /* Mozilla Firefox (legacy) */
    opacity: 0.8; /* CSS3 Standard */
}

Someday when CSS3 goes completely live, we won’t have to worry about opacity not validating; however, what about other browser specific styles that we need in order to support multiple browsers? If you don’t care about passing W3 CSS Validation, then this article is not for you. But for those of you whom require validation, or have a perfectionist nature, can workaround the validation engine using both JavaScript and CSS.

Although it may not be the best method out there, using JavaScript to implement impossible-to-validate CSS works the best for me.

Why does it work? Well its simple. Most bots/spiders don’t render JavaScript, which I imagine is for a number of reasons. Perhaps rendering JavaScript would slow down the bots’ very purpose of data mining (or with bad bots, the purpose of infiltrating). In fact, there usually isn’t anything valuable to a bot that would come from having to render JavaScript. (As a side note, this doesn’t mean that their aren’t bots that seek out sites that have vulnerabilities in their JavaScript markup, but reading JavaScript and rendering JavaScript are completely different).

So first, its a matter of migrating browser specific code to its own spreadsheet (so our JavaScript can include it). 

/* invalidable.css */
#selector {
  /* random properties */
    zoom: 1;
    -moz-border-radius
  /* opacity properties */
    filter:alpha(opacity=80); /* Internet Explorer */
    -moz-opacity:0.8; /* Mozilla Firefox (legacy) */
    opacity: 0.8; /* CSS3 Standard */
}

Once you have your browser specific properties on its own stylesheet, its just a matter of creating a JavaScript file that will “dynamically” insert the <link type=”text/css” rel=”stylesheet” href=”/assets/styles/invalidable.css” media=”screen”/> into your page (thus keeping with XHTML Strict standards).

// invalidable.js  <-- note the extension
//
// Dynamically Inserts CSS Link Tag
var headTag = document.getElementsByTagName("head")[0];
var linkTag = document.createElement('link');
linkTag.type = 'text/css';
linkTag.rel = 'stylesheet';
linkTag.href = '/assets/styles/invalidable.css';
linkTag.media = 'screen';
headTag.appendChild(linkTag);

Now all you have to do is throw in an JavaScript include tag:

<script type="text/javascript" src="/assets/js/invalidable.js"></script>

Your done! Bots will now only get this: 

<script type="text/javascript" src="/assets/js/invalidable.js"></script>

…while visitors will get this:

<script type="text/javascript" src="/assets/js/invalidable.js"></script>
<link type="text/css" rel="stylesheet" href="/assets/styles/invalidable.css" media="screen"/>

NOTE: It’s important to mention that visitors who have JavaScript DISABLED will NOT have the CSS file included, simply because the JavaScript won’t process; however, I will go on to say that its incredibly rare for you to have visitors that have JavaScript disabled. The only cases you’ll probably run into is visitors who visit your site from a cheap mobile phone (iPhone supports JavaScript), or a visitor who knows what their doing and has a Firefox plugin like “NoScript” installed.

On another subject, its important to mention that Google now penalizes for showing “different” content to search engines than to visitors. Would I classify an extra line in the section as different? Probably not. It’s my opinion that Google’s algorithm would check for differences in content, and not necessarily markup. I also haven’t seen very many cases where practices such as using JavaScript to “show/hide” content, be penalized in anyway. 

Wordpress /backup/.htaccess Error

Posted on May 8th, 2009 by Jarrett M. Barnett

This is a solution for anyone that has encountered this problem: Backup .htaccess File Error.

Having recently upgraded a Wordpress solution and migrating it to another server, I encountered a similar error where the /backup/.htaccess file is not able to be reached. Having spent a few minutes researching it, I found that the “Backup Wordpress” plugin, that the client had added to their Wordpress solution, was the culprit. The plugin was looking for the .htaccess in the directory path of the old server, and not the new one.

Instead of trying to dig through PHP files to try and find some kind of absolute path, I simply deactivated and deleted the plugin, upgraded to the latest version of Wordpress, and added another “Wordpress Backup” solution via the built-in plugin search in the admin area.

Limit Characters or Words in ExpressionEngine

Posted on May 5th, 2009 by Jarrett M. Barnett

The more I use ExpressionEngine, the more I love it as there’s a solution for anything that I can find a need for.

I couldn’t find a parameter that I could use in ExpressionEngine (that was already built in) that limited how many characters were used from a variable. In PHP, you could use substr() and trim(), but I wanted to avoid using PHP in ExpressionEngine as much as possible. So after a bit of searching I found this ExpressionEngine plugin called “Character Limiter” which allows me to use the following expression:

{exp:char_limit total="100"}
    {variable}
{/exp:char_limit}

Simple as that.

You may find that you would rather limit the number of words outputted. To do this, use the ExpressionEngine plugin called “Word Limit Plus“. Upload “pi.word_limit_plus.php” to the /system/plugins/ directory, and use the following expression to limit the amount of words outputted:

{exp:word_limit_plus if_exceeds="600" stop_after="500" the_link="<a href='{title_permalink=weblog/comments}'>MORE...</a>"}
   {variable}
{/exp:word_limit_plus}

I haven’t used this plugin yet, but from the “Word Limit Plus” plugin documentation, the “if_exceeds” parameter is the amount of words that need to be met before the text is triggered to be truncated. The amount of words that the text string would be truncated TO is the “stop_after” parameter. 

Again I haven’t confirmed this, but if I am correct, then a paragraph that has more than 600 words would be truncated to only be 500 words, while a paragraph of 599 words would not be truncated at all. I imagine this is to prevent from having blogs posts that truncate and leave out only a few words (obviously if there’s only a few more words left to display of a blog post, why not just display them rather than truncate the extra words out).

The “the_link” parameter is not required, but from what I can tell, its tacked onto the end of the outputted text and serves as a way to display a “Read more…” link at the end of a blog post.

A good side note is through my research of the “Word Limit Plus” ExpressionEngine plugin, I did find that because the “Word Limit Plus” looks for spaces (to determine the word count), consecutive spaces may cause an error.

None-the-less, the ExpressionEngine “Word Limit Plus” plugin could be useful for summarizing blog posts on your home page, building a custom RSS feed to be used for feeding data to Twitter, or simply feeding data to another portion of your site. I won’t go into too much detail about it, but I’m sure the possibilities are fairly endless.

Save the swine!

Posted on May 1st, 2009 by Jarrett M. Barnett

The Swine Flu Piggy Mask
mc2design_piggymask

Random Fields Extension in ExpressionEngine

Posted on May 1st, 2009 by Jarrett M. Barnett

Early last month I posted two different ways to have random fields in ExpressionEngine stating that “…in ExpressionEngine, a ‘random number’ expression has yet to exist”. Well I hate to say but I was wrong! In fact, ExpressionEngine comes with a “Randomizer” plugin built right in. Simply navigate to: Admin > Utilities > Plugin Manager.

However, there is an inconvenience with the “Randomizer” plugin. It’s a pain to use! 

The instructions state:
-Open this file: /plugins/pi.randomizer.php
-Fill the array with as many quotes as you want.
-Then place the following tag in any of your templates: {exp:randomizer:set_one}

A friendly no thanks to that plugin. So I did a bit of searching and found a plugin (by a different author) called “Randomizer Plus” and its the best solution I’ve found so far to randomization within ExpressionEngine’s template system.

Setting it up is also really easy. Take the pi.randomizer_plus.php file from the downloaded zip archive file, and upload it into your ‘plugins’ directory, located in /system/plugins. 

From there, its just a matter of using the appropriate tag in your page template, and to specify the seperator (delimiter):

{exp:randomizer_plus separator="{OR}"}
Random Value 1
{OR}
Random Value 2
{OR}
Random Value 3
{/exp:randomizer_plus}

Looks clean and super easy to use! It makes you just love ExpressionEngine just that much more.

Random Number in ExpressionEngine With & Without PHP

Posted on April 8th, 2009 by Jarrett M. Barnett

The rand() function in PHP is a quick and easy way to have a nice random number generated. Without it, faking randomization can quickly become cumbersome. After all, a random number has so many uses. Maybe you want to display a random testimonial on each page load, a featured blog post, or even use a different stylesheet. 

To get a random number with ExpressionEngine, we can go the PHP route, or the non-PHP route. Going the PHP route is obviously easier to output and write the markup for (not to mention, is truely “random”), but enabling PHP in your templates may not be your answer; especially if you don’t want users [who have the ability to create/edit blog posts] have the power to do anything that PHP would allow them to do (such as outputting normally unobtainable data from the database).

Unfortunately, in ExpressionEngine, a “random number” expression has yet to exist; however, one of the nice things about ExpressionEngine is the ability to process PHP at the flip of a switch. 

The PHP Solution:
First, turn on PHP processing in: Templates (tab) > Template Preferences Manager (link) > Allow PHP (dropdown)

Then we simply assign the rand() to a variable, and check against that variable to output accordingly.

<?php 

$random_number = rand(0,6); 

if ($random_number == 1) { echo '<img src="/assets/images/image1.png" />'; }
elseif ($random_number == 2) { echo '<img src="/assets/images/image2.png" />'; }
elseif ($random_number == 3) { echo '<img src="/assets/images/image3.png" />'; }
elseif ($random_number == 4) { echo '<img src="/assets/images/image4.png" />'; }
elseif ($random_number == 5) { echo '<img src="/assets/images/image5.png" />'; }
elseif ($random_number == 6) { echo '<img src="/assets/images/image6.png" />'; }

// ensures an image is displayed even when no other conditions are met (in this case, it really only displays when random_number = 0)
else { echo '<img src="\/assets\/images\/image0.png" \/>'; } 

?>

For those that prefer to avoid PHP, here’s a quick way to (in a way) fake a random number. I figured a good way to do this was using the {current_time}, but only the seconds portion. Granted, its not the most elegant solution, but it gets the job done.

The Non-PHP Solution:

{!-- Sets current time (seconds) to the variable 'current_time_seconds' --}
{assign_variable:current_time_seconds="{current_time format="%s"}"}

{!-- %s = Seconds range: 00-59 --}
{!-- Check current time in seconds and displays a different image based on current time in seconds --}

{!-- displays if 1-9 --}
{if {current_time_seconds} > 0 && {current_time_seconds} < 10}
<img src="/assets/images/image1.png" />

{!-- displays if 11-19 --}
{if:elseif {current_time_seconds} > 10 && {current_time_seconds} < 20}
<img src="/assets/images/image2.png" />

{!-- displays if 21-29 --}
{if:elseif {current_time_seconds} > 20 && {current_time_seconds} < 30}
<img src="/assets/images/image3" />

{!-- displays if 31-39 --}
{if:elseif {current_time_seconds} > 30 && {current_time_seconds} < 40}
<img src="/assets/images/image4.png" />

{!-- displays if 41-49 --}
{if:elseif {current_time_seconds} > 40 && {current_time_seconds} < 50}
<img src="/assets/images/image5.png" />

{!-- displays if 51-59 --}
{if:elseif {current_time_seconds} > 50 && {current_time_seconds} < 60}
<img src="/assets/images/image6.png" />

{!-- displays if seconds don't match any of the conditions above (basically the following times in seconds: 00,10,20,30,40,50) --}
{if:else}
<img src="/assets/images/image0.png" />

{/if}

The non-PHP solution can be a great solution for someone who doesn’t want a random image “every single time” (for the visitors who are clicking through pages within seconds of eachother).

CSS Coders. It’s Time To Clean-up Your Markup!

Posted on March 27th, 2009 by Jarrett M. Barnett

It’s so easy to write CSS without laying out a single comment. After all, in those glorious moments of coding, everything is understood. You know what your coding because, well frankly, you’ve been coding it! Don’t get me wrong, I’m a true believer in balancing time constraints and code quality. I’m also a true believer in finding the perfect balance between code simplicity and code expandability. But quite frankly, I’ve mopped up too many messy stylesheets recently that I felt obligated to encourage good practices.

So time goes by and lucky for you, your all done with that site so your markup doesn’t really matter. After all, it works, and if it ain’t broke, don’t fix it. But then comes the day where you get that phone call, and you’ll need to make changes to that spreadsheet you coded so mindlessly way back when. Oops! I guess it doesn’t make as much sense as it did when you were coding it. “What was I thinking!?” -or maybe its more along the lines of “What in the world was this guy thinking!?” 

Thank goodness for Firefox Add-ons like Firebug! Oh where would I be without it. But regardless, I am finding more and more that CSS markup conventions are just lacking, and designers are the ones responsible!

Here’s some practices that may save you (or anyone else for that matter) a fair amount of time when editing those stylesheets.

Though I don’t like resetting styles when I don’t have to, I tend to like defaulting specific elements to have no padding, margin, and border. Until all browsers conform to the exact same “default browser spreadsheet”, resetting styles is beneficial in the sense that it overrides specific properties to be the same across all browsers.

/*********************
  RESET STYLES
*********************/
img, table, tr, td, tbody, ul, li, ol {
	padding: 0;
	margin: 0;
	border: 0;
}

I always like to keep “tag specified” styles in its own section at the top of my file (they can always be overwritten by compound CSS):

/*********************
  TAG SPECIFIC STYLES
*********************/
body {
	background: url('../graphics/design/body-bg.jpg');
	font: .9em normal Arial, Verdana, Tahoma;
	color: #666666;
}
a {
	color: #666666;
}
a:hover {
	color: #000000;
}
a:active {
	color: #666666;
}
fieldset {
	border-color:#999999;
	border-style:solid none none;
	border-width:1px;
	padding:0.75em;
}

It’s also nice to have “general classes” for those rogue elements that you don’t know what to do with:

/*********************
  CLASS SPECIFIC STYLES
*********************/

.noborder {	border: 0; }
.nomargin { margin: 0; }
.nopadding { padding: 0; }

.floatleft { float: left; }
.floatright { float: right; }
.block { display: block; }
.inlineblock { display: inline-block; }
.inline { display: inline; }

… and finally some general advise for your CSS properties:

/*
##	COLOR MAPPING - to help with managing frequently used colors
##
##		Mango Orange: CE882D
##		Dark Red: 621817
*/

/*  Comments next to specific properties along with author notes
      help you remember why the "value" is coded a particular way */
	#newsletter h3 {
		color: #ce882d; /* Orange */
		margin: 10px 0;
	}
#footer {
	width: 100%;
	height: 13px; /* absolute height is specified for all footer items for IE6 compatibility - jbarnett@mc2design.com */
	display: block;
	vertical-align: top;
}

A technique that I sometimes use (when colors are not specified) is obtaining a color code of a certain element using the Firefox Add-On ColorZilla, and simply performing a CTRL+F[ind] (or CMD+F in OSX) and searching for the color code in the stylesheet. However, its actually more useful to use the “Inspect” tool in Firebug and to obtain the exact line you need to modify.

Some might be thinking, “Well with all that time trying to comment-up my stylesheets, I could of just spent it figuring it out sometime in the future”. Wrong! The time you spend making your spreadsheet understandable is nothing compared to the time you’ll waste trying to figure your spreadsheet out later on. I find that the best way to comment your stylesheets, is to comment as you code. Not after your done writing it. But while you write it!

Useful Knowledge About the Internet Explorer 6 “PNG Fix”

Posted on March 27th, 2009 by Jarrett M. Barnett

As a web designer constantly dealing with deadlines, I’m constantly managing the time I spend on implementing features, fixing bugs, creating markup, you name it. More recently I’ve had to deal with PNG issues in Internet Explorer 6 a lot more than I would have liked to. Having worked on a project that required a large amount of PNG transparent images, I was quickly reminded of how the PNG fix for IE6 actually works. 

When I wrote the markup for a recent project, I did what felt right. I made use of background images for things like the logo, borders, and corners. I did everything possible to keep everything in the stylesheet. But that doesn’t work when it comes to IE6.

When I first got my hands dirty with the IE6 PNG Fix, it wasn’t an easy implementation for me some 2 years a go, but I included the pngfix.js file as I was supposed to (which can be found here: http://homepage.ntlworld.com/bobosola/) and was ready to move on. Unfortunately, the transparent part of the PNG images were a pastel blue. So thinking that perhaps I didn’t implement the javascript correctly, I went through the troubleshooting process. After about 15 minutes, and still staring at PNG images with pastel blue instead of transparency, I found myself cursing Internet Explorer 6, about ready to create an IF statement that kicked IE6 users to the curb. But as so many users were on IE6 at the time (and a decent number still using IE6 to this day), I pushed myself to nail down the specifics of the PNG fix.

What I learned?
The PNG fix doesn’t fix background images specified using CSS. Rather, you need to actually have the PNG image in the markup.

For example, the following markup would result in the transparent portions of the image to not be transparent at all:

/* CSS Stylesheet */
#footer {
   background-image: url('/assets/graphics/footer-bottom.png');
   height: 10px;
   width: 980px;
}
<!-- XHTML Markup -->
<div id="footer">
</div>

To have the PNG fix actually work, the image needs to be in the markup. I also created a new CSS selector to specify the dimensions of the image (so I wouldn’t have to specify the dimensions in the markup):

/* CSS Stylesheet */
#footer {
   height: 10px;
   width: 980px;
}
   /* For PNG Fix to work properly, image dimensions need to be specified.
       I prefer to keep everything in my external stylesheet, rather than
       having it in the <img> element */
   #footer img {
      height: 10px;
      width: 980px;
   }
<!-- XHTML Markup -->
<div id="footer">
   <img src="/assets/graphics/footer-bottom.png" />
</div>

It’s also good to remember that in general, IE6 doesn’t follow the “inherit” value (nor does it automatically assume to inherit the parent). Therefore its a good rule of thumb that in order to minimize IE6 problems, specify dimensions for every “selector”. It does make it a little inconvenient as you’ll need to change both parent and child element dimensions (rather than simply changing the parent element dimensions). But at least it keeps your IE6 css only file minimal (and in many cases, found that I didn’t need one).

Internet Explorer 7 Flash Overlapping Problem

Posted on March 25th, 2009 by Jarrett M. Barnett

Anyone who’s had anything to do with web design, knows what a lightbox is, or at least has clicked on their fair share of them. For any web designer lucky enough to experience a YouTube video or Flash video overlapping their oh-so-beautiful lightbox, or their lovely css/javascript dropdown menu, will know that its one of those… you guessed it, Internet Explorer annoyances (in this case IE7). 

With the move from Internet Explorer 7, we were finally able to use PNG graphics (at least without having to add an IF IE7 condition statement to our head markup); however, when using flash, you’ll notice it renders as the upper most element, overlapping anything that dares try to be on top. The fix? Well its actually quite simple.

Here is an example object/embed element.

<object width="450" height="300" data="http://www.somedomain.com/video.mov">
<param name="movie" value="http://www.somedomain.com/video.mov"></param>
<param name="wmode" value="transparent"></param>
</object>

To prevent Flash from overlapping other elements, we simply need to remove ‘Line 3′.

<param name="wmode" value="transparent"></param>

For those that use sIFR to render standard text as flash, you’ll need to change the “sWmode” from transparent to opaque as is the case in the following line:

sIFR.replaceElement(named({sSelector:"h2#phrase", sFlashSrc:"/assets/typography/walbaum.swf", sColor:"#FFFFFF", sLinkColor:"#FFFFFF", sBgColor:"#000000", sHoverColor:"#CCCCCC", sWmode:"opaque", nPaddingTop:1, nPaddingRight:10, sFlashVars:"textalign=right&offsetTop=0"}));

Once your done changing your markup, Flash elements will FINALLY play nicely with the rest of your site. :) 

Code it right! YO!

Posted on February 24th, 2009 by Michael