On our DotNetNuke module demo site, we have a little selector (pictured above) in the upper right hand corner that lets you pick how wide you would like the site to appear. This is based on a similar mechanism on the DNN site. Folks have been asking about it, so feel free to register on our site and grab it for yourself (for free). It is a DNN skin object and compatible with DNN 4.5.1 and up. This is something we've developed for internal use, so it may or may not work for every circumstance. The basics are that it allows your users to define how they want to site to look by defining a CSS file with a cookie value.
The package you get has a .dll (to put in your website's bin folder) and an .ascx control to use on your DNN site as a skin object. Once you have everything in the right place, you can start using the skin object in your skin. It's still a pretty manual process, though it shouldn't take too much work to register is as a skin object on your site and use it that way. For our site, we do something that looks a little like this:
<%@ Register TagPrefix="engage" TagName="CssSelector" src="/Portals/_default/Skins/DNN-Blue/CssSelector.ascx" %>
<engage:CssSelector runat="server" ImageFileName="images/narrow.gif" SelectedImageFileName="images/narrow_sel.gif"
AlternateText="Narrow" PropertyName="Width" Value="Narrow" />
<engage:CssSelector runat="server" ImageFileName="images/wide.gif" SelectedImageFileName="images/wide_sel.gif"
CssFileName="wide.css" AlternateText="Wide" PropertyName="Width" Value="Wide" />
<engage:CssSelector runat="server" ImageFileName="images/full-width.gif" SelectedImageFileName="images/full-width_sel.gif"
CssFileName="full-width.css" AlternateText="Full-Width" PropertyName="Width" Value="Full-Width" />
We first register the skin object (that first, yellow line). Then we put the selector on the page for each option we want to present. Each instance sets a number of properties to get it setup. Firstly, there's the SelectedImageFileName and ImageFileName, which is a local, relative path to the image to display when that option is selected or not. Next is the AlternateText, set to the alternate text of the image. You'll notice that only two of the three options here specify the CssFileName property. The instance without a CssFileName specified is considered the "default" value, and appears selected if the user hasn't selected any of the options. Once the user selects an option, the page reloads, and the specified CSS file (typically containing an override of one or two styles) is also loaded. The user's selection is stored in a cookie, which is where the PropertyName and Value properties come into play. The PropertyName is the name of the cookie, and the Value is the cookie's value. This allows you to setup multiple different sets of buttons (like at DotNetNuke) for different types of properties.
Please visit our support forums if you have any issues, or if you want to let us know what you think.