Building great standards based websites for the big wide world with ASP.NET 4
Tatham OddieSenior ConsultantReadifyASP.NET MVP@tathamoddie
Damian EdwardsProgram ManagerMicrosoft(former ASP.NET MVP)@damianedwards
The ProjectWhat does “done” mean?
• Determine your “done” definition up front• Ours were:– XHTML compliance– WAVE test– Unit tested– Browser support: IE6, IE7, IE8, FF2, FF3, Sa3– Non-JavaScript support
• Develop your own
StandardsXHTML primer
• XHTML is based on HTML 4.01• Adds XML compliance & extensibility• XHTML 1.0– Frameset– Transitional– Strict
• XHTML 1.1• ASP.NET is geared to serving XHTML
StandardsChoosing a standard
• XHTML 1.1 is the latest & most strict• However it deprecates commonly used
elements & attributes– iframe– target
• Choose a base & switch when necessary• HTML5 is backwards compatible so consider
using it
ASP.NET & HTML
demo
REACH
Browsers below the baseline need specific attention
Browsers above the baseline “just work”
HTML 5
XDR
DOM Storage
Selector API
CSS 3 / extensions
CSS 2.1
DOM 1.0 Level 2
PNG
JavaScript
XHTML 1.0, 1.1
CSS 1
HTML 4.01
HTML 3.2
Baseline
IE8Opera 9.5
Safari 3Firefox 3
IE7Firefox 2
IE6
Firefox 3.1
Stan
dard
sEXPERIENCE
REACH
Browsers
Progressive Enhancement
Graceful D
egradation
Safari 2Firefox 1
ChromeSafari 4Firefox 3.6
ReachBuilding usable websites
• Important to have a browser support baseline• CSS layouts: load quicker, easier to maintain,
best support for majority of users• Progressively enhance from a standards
compliant base• Build non-JS functionality first, then layer JS on
top
Reach
demo
AccessibilityGetting started
• WAI – Web Accessibility Initiative– http://www.w3.org/wai
• WCAG 1.0 & 2.0• WAI-ARIA• WebAim.org– WAVE accessibility evaluation tool
MarkupKnow your server controls
• Pop quiz… what HTML gets rendered?– Label control– Panel control– Enabled attribute
• Do you really need the server control?
Using multiple forms
demo
MarkupForm layout
• Forms are fundamental to good websites• Layout affects accessibility, stylability &
maintainability• Choose a consistent form layout model & stick
to it
<fieldset class="customer-details"> <legend>Customer Details</legend> <ol> <li class="first-name"> <label for="firstName">First Name:</label> <input id="firstName" type="text" /> </li> <li class="last-name"> <label for="lastName">Last Name:</label> <input id="lastName" type="text" /> </li> <li class="action save"> <input type="submit" value="Save" /> </li> </ol></fieldset>
<fieldset class="customer-details"> <legend>Customer Details</legend> <ol> <li class="first-name"> <label for="firstName">First Name:</label> <input id="firstName" type="text" /> </li> <li class="last-name"> <label for="lastName">Last Name:</label> <input id="lastName" type="text" /> </li> <li class="action save"> <input type="submit" value="Save" /> </li> </ol></fieldset>
fieldset { float: left; clear: both;} fieldset ol { list-style-type: none; margin: 0; padding: 15px; } fieldset ol li { clear: both; margin: 0 0 4px; } fieldset ol li label { display: block; width: 120px; float: left; } fieldset ol li.action { padding: 0 0 0 120px; }
<fieldset class="customer-details"> <legend>Customer Details</legend> <ol> <li class="first-name"> <label for="firstName">First Name:</label> <input id="firstName" type="text" /> </li> <li class="last-name"> <label for="lastName">Last Name:</label> <input id="lastName" type="text" /> </li> <li class="action save"> <input type="submit" value="Save" /> </li> </ol></fieldset>
fieldset { float: left; clear: both;} fieldset ol { list-style-type: none; margin: 0; padding: 15px; } fieldset ol li { clear: both; margin: 0 0 4px; } fieldset ol li label { display: block; width: 110px; float: left; margin-right: 10px; text-align: right; } fieldset ol li.action { padding: 0 0 0 120px; }
<fieldset class="customer-details"> <legend>Customer Details</legend> <ol> <li class="first-name"> <label for="firstName">First Name:</label> <input id="firstName" type="text" /> </li> <li class="last-name"> <label for="lastName">Last Name:</label> <input id="lastName" type="text" /> </li> <li class="action save"> <input type="submit" value="Save" /> </li> </ol></fieldset>
fieldset { float: left; clear: both;} fieldset ol { list-style-type: none; margin: 0; padding: 15px; } fieldset ol li { clear: both; margin: 0 0 4px; } fieldset ol li label { font-size: 0.8em; color: #444; display: block; } fieldset ol li input[type=text] { width: 200px; } fieldset ol li.action { margin-top: 10px; }
<fieldset class="customer-details"> <legend>Customer Details</legend> <ol> <li class="first-name"> <label for="firstName">First Name:</label> <input id="firstName" type="text" /> </li> <li class="last-name"> <label for="lastName">Last Name:</label> <input id="lastName" type="text" /> </li> <li class="action save"> <input type="submit" value="Save" /> </li> </ol></fieldset>
fieldset { float: left; clear: both;} fieldset ol { list-style-type: none; margin: 0; padding: 15px; } fieldset ol li { float: left; margin: 0 30px 0 0; } fieldset ol li label { display: block; float: left; margin-right: 10px; } fieldset ol li.action { margin: 0; }
Client Performance
• Use YSlow to highlight potential issues• Minimize requests– Combine your CSS during build/deployment– Combine JS with ScriptManager– Use CSS sprites for background images
• GZIP compression
$PSScriptRoot = Split-Path -Parent –Path `(Get-Item -Path $MyInvocation.MyCommand.Path).FullName ;
$YuiAssemblyPath = Join-Path -Path $PSScriptRoot –ChildPath `"Dependencies\YUI Compressor\Yahoo.Yui.Compressor.dll"
[Void][System.Reflection.Assembly]::LoadFrom($YuiAssemblyPath) ;
$AggregateFile = Join-Path -Path $Path -ChildPath "styles.agg" ;Remove-Item -Path $AggregateFile -ErrorAction SilentlyContinue ;
$CssFilesPattern = Join-Path -Path $Path -ChildPath "*.css" ;
Get-ChildItem -Path $CssFilesPattern -Exclude print.css `| Sort-Object -Property Name `| Get-Content `| Add-Content -Path $AggregateFile -Encoding UTF8 ;
[string]$CssContent = Get-Content -Path $AggregateFile[Yahoo.Yui.Compressor.CssCompressor]::Compress($CssContent) `
| Set-Content -Path $AggregateFile ;
QualityBuilding for testability
• Why tests matter• Types of tests– Unit test– Integration test– Functional test– Performance test
QualityWeb Forms MVP
• Additive• Facilitates good architecture• New features
• http://webformsmvp.com
Web Forms MVP
demo
In ConclusionTakeaways
• Web standards make accessibility, reach, quality & maintenance easier
• ASP.NET supports XHTML, but needs tweaking & developer awareness (HTML5 is coming)
• Determine your done criteria early & automate as much as possible
• Ensure quality by using testable patterns, DI, IOC & unit testing
Resources
• http://tath.am• http://damianedwards.com• http://www.w3.org• http://www.webaim.org• http://webformsmvp.com• http://markupsanitizer.codeplex.com • http://www.graysonline.com