среда, 28 ноября 2012 г.

Detecting device size & orientation in CSS

Gone are the days when we could safely assume that most our site visitors would have at least a 1024px-wide screen resolution. With smartphones and tablet computers on the rise, you visitors could also be browsing the web with screen widths ranging from 320px upwards. Does your site look good on a 768px-wide canvas? That’s how people will see it using a portrait-oriented iPad.
Time to revisit that old stylesheet of yours and give it a face-lift. Let’s jump straight into examples:
@media only screen and (max-width: 999px) {
  /* rules that only apply for canvases narrower than 1000px */

@media only screen and (device-width: 768px) and (orientation: landscape) {
  /* rules for iPad in landscape orientation */

@media only screen and (min-device-width: 320px) and (max-device-width: 480px) {
  /* iPhone, Android rules here */
While at first this looks like proprietary markup, these are in fact CSS3 media queries implemented in Firefox, Safari (including Mobile) and Google Chrome. (I didn’t test other browsers or mobile WebKits.) Mozilla has some nicereference documentation with this very important detail:
As the user resizes the window, Firefox will switch style sheets as appropriate based on media queries using thewidth and height media features.
You can see this in effect on my “iPhone vs. Droid ads” page which was originally designed as a gorgeous, whitespace-rich two-column layout comparing two companies' types of marketing. Obviously, I couldn’t preserve the multicolumn layout on narrower displays, so using media queries I had made 3 different layouts:
  1. widths up to 480px (iPhone, Android): tight spacing, single-column;
  2. up to 980px (iPad in portrait): fluid columns only on top section, single-column elsewhere;
  3. wider than 980px: fixed, two-column centered layout.
Try resizing your browser to see how the layout of that page changes at narrower sizes.
As an additional detail, I’ve bumped up font sizes for the iPad to improve readability on its high pixel density display.
Once you’ve made sure your layout fits on smaller displays, you need this tag to satisfy mobile WebKits:
 name="viewport" content="initial-scale=1.0">
See full documentation for “viewport” directive. What Mobile Safari does by default (i.e. without this directive) is display a zoomed-out, 980px-wide version of the page even if the layout itself is narrower. As content authors, with this directive we’re saying “trust me, zoom to natural scale and I’ll make sure it fits”. From the documentation:
[…] if you set the scale to 1.0, Safari assumes the width is device-width in portrait and device-height in landscape orientation.
Finally, some tips from Apple’s technical note about preparing for the iPad:
Since touching and holding in Safari on iPhone OS will invoke the Cut/Copy/Paste dialog, you may also choose to disable selection on user interface elements such as menus and buttons using -webkit-user-select: none. It is important to only disable selection as needed on a per-element basis. Selection in webpages should never be globally disabled.
You should be aware that orientation media query, although supported on the iPad, doesn’t work on the iPhone(tested with v3.1.3). Fortunately, size queries like width and device-width work, so layout-switching is possiblewithout JavaScript with some combination of those.
Update: with the advent of Retina display devices, you might want to target them specifically to serve high-resolution graphics. There is an article over on the WebKit blog covering how to do this called High DPI Web Sites, and the answer is the -webkit-device-pixel-ratio media query:
 rel="stylesheet" media="only screen and -webkit-min-device-pixel-ratio: 2" href="highres.css">

Accessing an IIS Express site from a remote computer

Sometimes (waaaay to often) I have to check that a site I’m working on looks like it should in Internet Explorer 6, Safari on Mac or some other browser that I can’t run in Windows 7. In this case I wanted to access it from IE6 running in XP Mode.  I could of course deploy it to IIS and make it publicly available, but since I’m now using IIS Express for running my sites from Visual Studio instead of the built-in web server Cassini, it almost simple to let other computers on my network access the site.
This post by Scott Hanselman almost describes how to do it, but since I had to make some adjustments I thought I might write a shorter post with just the steps you need for this.

1 – Bind your application to your public IP address

Normally when you run an application in IIS Express, it’s only accessible on http://localhost:[someport]. In order to access it from another machine, it needs to be bound to your public IP address as well. Open D:\Users\[YourName]\Documents\IISExpress\config\applicationhost.config and find your site. You will find something like this:
<site name="Alpha.Web" id="2">
    <application path="/">
        <virtualDirectory path="/" physicalPath="C:\Users\Johan\HgReps\Alpha\Alpha.Web" />
        <binding protocol="http" bindingInformation="*:58938:localhost" />
In , add another row:
 (But with your IP, and port number, of course)

2 - Allow incoming connections

If you’re running Windows 7, pretty much all incoming connections are locked down, so you need to specifically allow incoming connections to your application. First, start an administrative command prompt. Second, run these commands, replacing with whatever IP and port you are using:
> netsh http add urlacl url= user=everyone
This just tells http.sys that it’s ok to talk to this url.
> netsh advfirewall firewall add rule name="IISExpressWeb" dir=in protocol=tcp localport=58938 profile=private remoteip=localsubnet action=allow
This adds a rule in the Windows Firewall, allowing incoming connections to port 58938 for computers on your local subnet.
And there you go, you can now press Ctrl-F5 in Visual Studio, and browse you site from another computer!

суббота, 17 ноября 2012 г.

Html.ActionLink as Image

Late response but you could just keep it simple and apply a CSS class to the htmlAttributes object.
<%= Html.ActionLink("Button Name", "Index", null, new { @class="classname" }) %>
and then create a class in your stylesheet
    background: url(../Images/image.gif) no-repeat top left;
     display: block;
     width: 150px;
     height: 150px;
     text-indent: -9999px; /* hides the link text */