ASP.NET, Css condizionali e Themes

Si non sono sparito... solo un pò assente. Btw, in questi giorni mi sono dovuto/voluto scontrare di persona con il problema della compatibilità dei broswer e i css... tra IE7 e IE8 le cose cambiano molto e se non si vuole ricorrere al metà tag “X-UA-Compatible = IE=EmulateIE7” un’alternativa potrebbe essere quella di usare i “Microsoft Conditional Comments” e lasciare che la pagina risolva client-side il corretto css da usare. Tutto questo è in contrasto con l’uso dei Themes dove tutti i css presenti nella cartella vengono inseriti nella pagina senza distinzione... ovviamente le buone e pratiche osservazioni, “Themes prevent the use of Microsoft's CSS Conditional Comments”, vengono chiuse e catalogate come come “Won't Fix”.

In rete ho trovato diverse idee... anche sovracomplesse; una soluzione decisamente interessante è questa "How to take control of style sheets in ASP.NET Themes with the StylePlaceholder and Style control". Perchè interessante? Perchè mi ha dato l’idea su come muovermi su qualcosa di più semplice e pratico. In fondo è un problema semplice e mi piacerebbe risolverlo con un metodo semplice. Ecco come mi sono mosso.

Ho stabilito che il nome del mio css deve contenere anche la regola che indica se deve essere incluso o scartato per la richiesta corrente in accordo con le caratteristiche del browser. Ho voluto definire solo due regole semplici:

  • <nome>@<broswertype>.css: il css è da usare esclusimanente per uno specifico browertype
  • <nome>@!<broswertype>.css: il css NON è da usare per uno specifico browertype

Si potrebbero aggiungere regole più complicate ma attualmente queste coprono tutti i casi d’uso a me necessari. Ho quindi definito uno user control che incluso nella pagina va ad escludere i css aggiunti ma che non sono concordi con il browser che sta facendo richiesta. Ecco il codice che ne è uscito.

[ToolboxData("<{0}:ConditionalCssThemeControl runat=\"server\"></{0}:ConditionalCssThemeControl>")]
public class ConditionalCssThemeControl: WebControl
{
    const char CONDITIONAL_CHAR = '@';

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        this.Page.LoadComplete += new EventHandler(Page_LoadComplete);
    }

    void Page_LoadComplete(object sender, EventArgs e)
    {
        string browserType = this.Page.Request.Browser.Type;

        var removeCandidate = Page.Header.Controls.OfType<HtmlLink>()
            .Where(link => !IsValidCss(link.Href, browserType)).ToList();

        removeCandidate.ForEach(Page.Header.Controls.Remove);
    }

    protected override void Render(HtmlTextWriter writer)
    {
        //il controllo agisce solo server side
    }

    private bool IsValidCss(string href, string browserType)
    {
        if (href.Contains(CONDITIONAL_CHAR))
        {
            string[] segments = href.Split(new char[] { CONDITIONAL_CHAR }, 2);
            string condition = segments[1];
            bool matchBrowser = condition.EndsWith(string.Concat(browserType, ".css"),
                    StringComparison.InvariantCultureIgnoreCase);

            if (condition[0] == '!')
            {
                //il css è da escludere per lo specifico browser
                return !matchBrowser;
            }
            else
            {
                //il css è indicato per lo specifico browser
                return matchBrowser;
            }
        }
        else
        {
            //il css non ha condizioni di utilizzo
            return true;
        }
    }
}

Quindi nell’head della Page o della MasterPage aggiungo un’istanza del controllo.

<mb:ConditionalCssThemeControl runat="server" id="condCssTheme" />

La mia cartella del Theme risulta come segue.

image

Quello che mi piace di questa soluzione è che posso indicare le condizioni semplicemente e non ho dovuto mettere riferimenti al path del Themes nel codice... come molti esempi viene fatto.

oO0( ... altre possibilità? )

posted @ giovedì 2 luglio 2009 15:52

Print

Comments on this entry:

# re: ASP.NET, Css condizionali e Themes

Left by markino at 02/07/2009 17:43
Gravatar
CSS e Skin hanno scopi diversi... i temi hanno un altro scopo ancora. Skin e Css sono una parte dei Themes. XHTML+CSS sono solo il risultato dell'uso dei temi e degli skin.... impara bene ad usare i themes e vedrai che potrai avere lo stesso risultato. Sono solo punto di vista e un modo di lavorare diversi. E' ovvio che quanto ho scritto vale per chi fa la scelta di lavorare usando i Themes. Purtroppo le vecchie versione versione di IE... hanno troppa licenza poetica in merito all'interpretazione dei CSS per cui creare in maniera veloce un css valido per ogni browser al momento non è pensabile. (my 2 cents)

# re: ASP.NET, Css condizionali e Themes

Left by M.rkino at 23/08/2009 18:47
Gravatar
si andrea, ma come ho scritto lo use control "va ad escludere i css aggiunti ma che non sono concordi con il browser che sta facendo richiesta". Infatti se vedi il codice dello user control nel LoadComplete si legge.

removeCandidate.ForEach(Page.Header.Controls.Remove);

Lascio quindi che i css vengano inclusi ma poi escludo quelli non concordi con le regole... sarebbe bello agire per "regole di inclusione" ma non sembra che la cosa sia possibile.

Comments have been closed on this topic.
«aprile»
domlunmarmergiovensab
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011