Subscribe

Close

Thank you for visiting!

Please consider subscribing to the RSS feed or following me on Twitter.

Archive for Web development:

Check if Bootstrap CSS is Loaded and Provide Local Fallback

When a CDN somehow fails, you want to make sure you can load a local fallback.

Here's a snippet to check if Bootstrap CDN is down, and then proceed to load a local Boostrap fallback version, utilizing Boostrap's hidden CSS class.

If Bootstrap is loaded, the span will be hidden. We simply check if it is hidden, and if it aint - we assume Bootstrap wasn't loaded from CDN and load our local fallback instead.

Run this script after you've tried to load Boostrap from a CDN.

var $span = $('<span class="bs hidden"></span>');
var $bs = $('body').append($span).find('.bs');

if ($bs.css('display') !== 'none') {
	$("head").append('<link rel="stylesheet" href="/css/Bootstrap/bootstrap.min.css">');
}
$bs.remove();

Other, more sofisticated methods, depend on libraries like yepnope or requirejs. Meanwhile, this method works just fine.

Foolproof Custom File Input

So you wan't a custom file upload button.

It's easy. Just hide it, add a button, a couple of click events and you're fine. Except, you're not. IE is quite strict when it comes to file inputs. Browser backward compatibility issues will make life harder for you.

Here's a working solution tested in IE9 and later, and modern browsers.

  1. Place your input file field in a hidden div.
  2. Wrap a label around the hidden div.
  3. Make the label look like a button.
  4. When the label is clicked, trigger the hidden input field.
  5. When a file is chosen, use the change event to display the file name.
The HTML:

<form action="http://localhost/upload" method="post" enctype="multipart/form-data">
<label class="button upload">Upload file
<div class="hidden">
<input class="uploadfile" type="file" />
</div>
</label>
<input type="submit" class="button" value="Submit">
<span></span>
<form>
The JavaScript:

$('.button.upload').click(function () {
var uploadFile = $(this).find('.uploadfile');
uploadFile.trigger('click');
});

$('.uploadfile').change(function() {
var elm = $(this);
var file = elm.val().split('\\');
var fileName = file[file.length - 1];
$(this).closest('form').find('span').html(fileName);
});

And the basic CSS looks like this:

.hidden { display: none }
.button { border: solid 2px #333 }

Firefox Redirecting Localhost and How To Solve It

Recently experienced Firefox redirecting localhost to something completely else, like localhost.com?

Fear no more. This is how you solve it:

  1. In Firefox, type about:config in the address bar and press enter.
  2. Find browser.fixup.alternate.enabled and set it to false.
  3. Done!

Note: this problem most often occur when using other urls than http://localhost for your development websites.

How To Name Controls in ASP.NET Web Forms

When working with ASP.NET, particularly Web Forms up until version 4 of the ASP.NET framework, one might want to think a bit at the naming of the controls used.

I often stumble upon control names looking like this: ChoicesPlaceHolder, MessageLabel and similar. That's clear and decent naming, but it can be improved.

Me and fellow developers have found a simple yet useful and clear naming convention, based on a prefix and a descriptive control name (using Hungarian notation).

This is how it can look instead: phChoices, lblMsg

Naming is particularly important when dealing with nested controls and ContentPlaceHolders. Using better naming, you can improve and reduce this rendered control id:

ctl00_ContentPlaceHolderAllColumns_ContentPlaceHolderAllContentColumns_
ContentPlaceHolderSubNavigation_SubNavigation_RepeaterNavigation_ctl06_
HyperLinkNavigationPageLink

To this id:

ctl00_cphAllColumns_cphAllContentColumns_cphSubNav_SubNav_rptNav_
ctl06_hlNavLnk

Pretty much better, huh? Plus it saves bandwidth.

Also, think twice about where you put runat="server". Is it needed on all controls?

Here's a table with common controls, their prefix and an example naming.

Table: Common ASP.NET Web Forms control and naming
ASP.NET Control Prefix Example
Button btn btnSend
CheckBoxList cbl cblColourCombinations
ContentPlaceHolder cph cphMain
DropDownList ddl ddlNavChoices
Label lbl lblMsg
Literal lit litMsg
Panel pnl pnlLogin
PlaceHolder ph phArticles
RadioButtonList rbl rblPaymentChoices
TextBox tb tbUserName

Regarding style sheets and the title attribute

When linking to external style sheets and using the title attribute, you have to be a bit careful. I'll explain to you how to correctly link to external style sheets.

Normally, you link to an external style sheet like this:

<link rel="stylesheet" type="text/css" href="/css/main.css"
	media="screen,projection" />

Perfectly fine!

However, you'd like to add a print stylesheet to, using media="print":

<link rel="stylesheet" type="text/css" href="/css/print.css"
	media="print" />

Now, this too works fine. However - when you want to use the title attribute with your style sheets, you have to be careful.

The title attribute is great to use if you want simple style switching and alternative style sheets. But you need to know what you do to get it to work!

In this code, the print style sheet will not work, it won't be triggered in different browsers:

<link rel="stylesheet" type="text/css" href="/css/main.css"
	media="screen,projection" title="Default stylesheet" />
<link rel="stylesheet" type="text/css" href="/css/print.css"
	media="print" title="Print stylesheet" /> 

It's because the print style sheet's title attribute has a value. If the value is removed, or the whole title attribute, the print style sheet will work.

This happens because there are three different types of style sheets - and if an external style sheet is of the wrong kind - this style sheet will simply be ignored.

Three different types of style sheets

The three types of style sheets are:

  1. Persistent, which is a kind of default style sheet. No title attribute is needed.
  2. Preferred, which is the style sheet web browsers apply. Title attribute is needed.
  3. Alternate, which is alternatives to already existing style sheets. Title attribute is needed.

If these are mixed up, things might not be working as expected. Here's more on specifying external style sheets.

Conclusion

If you want your style sheets to work, make sure they're of the correct style sheet type. This final example works very well:

<link rel="stylesheet" type="text/css" href="/css/main.css"
	media="screen,projection" title="Default stylesheet" />
<link rel="stylesheet" type="text/css" href="/css/print.css"
	media="print" />

Why developers should do time estimates

Over and over again, I stumble upon web projects where someone other than the developer has estimated the development time. Nothing could be more wrong.

A developer, no one else, should estimate the time for a set of tasks involving development.

Even more important, the developer(s) involved in the project, should do the time estimation.

Why is this? Well, for starters, this will give you a more accurate timesheet. And this will certainly help your customer relationship.

Here's some more reasons to why developers and no one else should do the time estimates:

  • Developers probably has the best knowledge of how much time a specific task will consume
  • A more accurate time estimation will actually give you an idea on how much time is needed for a specific project, making planning a bit easier
  • Issues might be found earlier
It's a no-brainer, the craftsman whose expertise area is development, should do the time estimation.

So when the next project is due - take your time and make sure a developer does the time estimation before a time limit and definite price is set with the customer. It'll help you a lot.

 

ASP.NET and improving web standards

Developers often ask me what they can do to improve web standards on their ASP.NET website. There are a number of tricks available and I thought I'd share them with you.

Web.Config magic

First thing to do, is to make sure you've got your Web.Config ready for web standards. This is really simple, as there's only some copy and paste needed. What you want to do is setting xhtmlConformance mode to Strict and make use of browserCaps, both in the system.web section, like this:

<system.web>
<xhtmlConformance mode="Strict" />
<browserCaps>
  <case match="W3C_Validator*">
    TagWriter = System.Web.UI.HtmlTextWriter
    W3CDomVersion = 1.0
  </case>
</browserCaps>

....
</system.web>

Use the best .NET controls at your disposal

Countless of times you see .NET controls such as Label and Panel used. Not good, since both render extra HTML output. A label renders an extra span and a Panel renders an extra div, thus affecting the markup of the website - and at worst even breaking the layout.

To the rescue, comes the Literal and PlaceHolder controls. The Literal and PlaceHolder don't render extra markup, and I've never ran into a single problem using them instead.

Also, I like to use the Repeater as often as I can, since I don't always trust third party controls.

Set CSS class on the first listing item

You might have seen class="first" set on the first item in a listing, a number of times. For some, this is a pain to address. However, nothing could be easier than setting a specific CSS class on the first item in a listing. You just have to use the onItemDataBound event on your control. Here's how it might look:

<asp:Repeater ID="rptListing" OnItemDataBound="cssAddons" runat="server">
<ItemTemplate>
	<li<asp:Literal ID="cssClass" Visible="false" runat="server"> class="first"</asp:Literal>>
		<%#Eval("Item") %>
	</li>
</ItemTemplate>
</asp:Repeater>

And the codebehind:

protected void cssAddons(object sender, RepeaterItemEventArgs e)
{
	ListItemType type = e.Item.ItemType;

	if (type == ListItemType.Item)
	{
		if (e.Item.ItemIndex == 0)
		{
			Literal litCssClass = (Literal)e.Item.FindControl("cssClass");
			if (litCssClass != null) litCssClass.Visible = true;
		}
	}
}

You should never be forced to rebuild a project when doing layout changes - that's why one would prefer to use a hidden Literal with the CSS class in the ItemTemplate, and toggling the visibility if it's the first item in a listing.

Customized web controls and CompositeControl

A lot of you are perhaps writing your own web controls. Take note though, inheriting from CompositeControl will make your web controls render an extra span. There's a simple solution to this - just override the Render method in your control, like this, and you're set:

protected override void Render(HtmlTextWriter writer)
{
	RenderContents(writer);
}

Some reminders - naming conventions and id's

When it comes to ASP.NET and naming web controls, things can get messy. You want to name your controls as short as possible, without making the name totally meaningless. You particularly want to name your ContentPlaceHolders in a smart way, to avoid id's like this:

ctl00_ContentPlaceHolderContent_ContentPlaceHolderMain_ContentPlaceHolderWidePageWithoutTopImage_ContentPlaceHolderWidePage_ContentPlaceHolderPageContent_ButtonSend

I regularly prefix my web controls, rpt for Repeater, cph for ContentPlaceHolders and so on.

Another problem in ASP.NET Web Forms is id's. If you use runat="server" with a HTML element, the id might look like in the example above. You must avoid this as much as you can, since the altered id's might break the layout. Some might say you should use CSS classes instead, but that's not the way to go. CSS classes aren't meant to be used instead of id's.

In ASP.NET 4, you can actually choose how your id's are rendered, through the ClientIdMode property. A welcome change!

More reading

Remember this is aimed at ASP.NET Web Forms websites, even though part of the tricks can be used in an MVC environment too!

Use canonical urls to improve SEO

Today there's a lot of talk about duplicate content and SEO. What happens to your blog when a search engine crawls it and discovers the same blog post exists in a specific category archive, and on an own page? What happens to your e-commerce website when you've got products tagged with more than one tag? Duplicate content.

This creates problems for search engines - but there's a simple solution - canonical urls.

Canonical urls to the rescue

Canonical urls, or canonicalization as it also is called, helps you decide what address should be the standard address for specific content on your website. What you want to do is to start using a new link rel attribute: canonical.

Put the new link rel attribute in <head> and provide the default url for the specific content, like this:

<link rel="canonical" href="http://blog.dileno.com/archive/200907/going-english/" />

Read more about canonical urls in Google's webmaster blog.

Great blogs for web people

I run into a lot of great blogs and I thought I'd share some of them with you. Here's my pick of the bunch, blogs related to web design, web development, programming and social media.

Web design and inspiration

Web design

  • Smashing Magazine
    - Because Smashing is a great source for all things web design and inspiration.
  • Think Vitamin
    - Great web stuff from the Carsonified team.
  • Inspect Element
    - Because Tom Kenny is awesome at what he does and shares great things.
  • Veerle's blog
    - Veerle Pieters is certainly one of the greatest female web designers. A must read.

Web development

Web development

  • 456 Berea Street
    - Because Roger Johansson is one of the pioneers of web accessibility in modern time.
  • Robert's talk
    - Because Robert Nyman continues to engage, inspire and create what web developers want.
  • Maxdesign.com.au
    - Great links for light reading from the Sydney based web design bureau Max Design.
  • CSS tricks
    - Awesome CSS resource.
  • W3Avenue
    - Because here you'll find a helpful set of stuff that matters to all modern web developers.
  • net tuts+
    - Great tutorials on all things web development.
  • A List Apart
    - Because this is for people who make websites. A List Apart's been around forever and continues to break barriers.

Programming and technology

Programming

  • Scott Guthrie
    - Because Scott Gu is the Microsoft guy who gives .NET developers all they want.
  • Scott Hanselman
    - Every aspect of Hanselman's blog is of interest to programmers and tech people. Don't miss Hanselminutes, the podcast!
  • Joel on software
    - Because Joel's got a unique talent for programming and business, and the ability to share his thoughts. An absolute must.
  • Coding Horror
    - Because Jeff Atwood is from another planet. He continues to inspire and give you really interesting thoughts on programming.

Social media & marketing

Social media

  • Mashable
    - Mashable's the portal to all social media news worth reading. Pete Cashmore at his finest.
  • Seth Godin
    - Great thoughts on marketing and business from the oracle Seth Godin. Don't miss this.
  • Jesper Åström
    - Brilliant posts on social media and SEO - you'll want to read Jesper's blog.

Submit your website to Bing

Microsoft's search engine Bing has indeed gained some market share since it went live late this spring. Bing's got its own Webmaster Center where webmasters can use the webmaster tools provided. I'll show you how you can submit your website to Bing's search index.

  1. Login to WebMaster Center with your Windows Live ID.
  2. Add your website's web address and the sitemap address (if you have a sitemap XML file):
    Add web and sitemap address to Bing
    You can also specify your email address if you want Bing to be able to contact you.
  3. Authenticate your website ownership through either XML verification or meta tag authentication. You'll have to upload the XML file or any other file to your website.
  4. Wait for Bing to crawl your website.
    Until then, your site summary will look like this:
    Site status for added website

It might take a couple of days for Bing to add your website to its index. Just remember to be patient and you should be fine!

To the top