Billets dans la catégorie « Bonnes pratiques » ↓

Structure de page

Voici la structure de page par défaut que j’emploie actuellement :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=iso-8859-15" />
        <title>&hellip;</title>
        <link rel="stylesheet" type="text/css" media="screen" title="Affichage par d&eacute;faut" href="css/lib/reset.clean.css" />
        <link rel="stylesheet" type="text/css" media="screen" title="Affichage par d&eacute;faut" href="css/screen.css" />
        <script type="text/javascript" src="js/lib/init.min.js"></script>
    </head>
    <body>
        <!--[if IE]><div class="msie"><![endif]--><!--[if gt IE 6]><div class="msie7"><![endif]-->
        <!--[if IE 6]><div class="msie6"><![endif]--><!--[if lt IE 6]><div class="msie5"><![endif]-->
        <div id="page">
            <div id="tete">
                &hellip;
            </div>
            <hr class="masquer" />
            <div id="corps">
                &hellip;
            </div>
            <hr class="masquer" />
            <div id="pied">
                &hellip;
            </div>
        </div>
        <!--[if IE]></div></div><![endif]-->
        <script type="text/javascript" src="js/lib/jquery.min.js"></script>
        <script type="text/javascript" src="js/behaviour.js"></script>
    </body>
</html>

Ainsi que la feuille de style associée (ici, non compressée):

/* YUI reset
------------------------------------------------------------------------------*/
html
{
    color:#000;
    background-color:#FFF;
    background-position:0 0;
    background-repeat:no-repeat
}
body, div, p,
dl, dt, dd, ul, ol, li,
h1, h2, h3, h4, h5, h6,
pre, code, blockquote,
form, fieldset, legend, input, textarea,
th, td, a, span
{
    margin:0;
    padding:0;
    background-position:0 0;
    background-repeat:no-repeat
}
table
{
    border-collapse:collapse;
    border-spacing:0;
    background-position:0 0;
    background-repeat:no-repeat
}
fieldset, img
{
    border:none
}
address, caption, cite, code, dfn, em, strong, th, var
{
    font-style:normal;
    font-weight:normal;
    background-position:0 0;
    background-repeat:no-repeat
}
li
{
    list-style:none
}
caption, th
{
    text-align:left;
    background-position:0 0;
    background-repeat:no-repeat
}
h1, h2, h3, h4, h5, h6
{
    font-size:100%;
    font-weight:normal;
    background-position:0 0;
    background-repeat:no-repeat
}
q:before, q:after
{
    content:""
}
abbr, acronym
{
    border:0;
    font-variant:normal
}
sup
{
    vertical-align:text-top
}
sub
{
    vertical-align:text-bottom
}
input, textarea, select
{
    font-family:inherit;
    font-size:inherit;
    font-weight:inherit;
    background-position:0 0;
    background-repeat:no-repeat
}
legend
{
    color:#000;
    background-color:inherit;
    background-position:0 0;
    background-repeat:no-repeat
}
legend span
{
    display:block
}
/* YUI font
------------------------------------------------------------------------------*/
body
{
    font:13px/1.231 sans-serif
}
table
{
    font-size:inherit
}
pre, code, kbd, samp, tt
{
    font-family:monospace;
    line-height:100%
}
/* YUI base
------------------------------------------------------------------------------*/
h1
{
    font-size:138.5%
}
h2
{
    font-size:123.1%
}
h3
{
    font-size:108%
}
h1, h2, h3
{
    margin:1em 0
}
h1, h2, h3, h4, h5, h6, strong
{
    font-weight:bold
}
abbr, acronym
{
    border-bottom:1px dotted
} 
em
{
    font-style:italic
}
blockquote, ul, ol, dl
{
    margin:1em
}
ol, ul, dl
{
    margin-left:2em
}
ol li
{
    list-style:decimal outside
}
ul li
{
    list-style:disc outside
}
dl dd
{
    margin-left:1em
}
th, td
{
    border:1px solid;
    padding:.5em
}
th
{
    font-weight:bold;
    text-align:center
}
caption
{
    margin-bottom:.5em;
    text-align:center
}
p, fieldset, table, pre
{
    margin-bottom:1em
}
input[type=text],
input[type=password],
textarea
{
    width:12.25em
}
label
{
    cursor:pointer
}
select,
input,
textarea
{
    font-size:100%
}
/* YUI font for IE
------------------------------------------------------------------------------*/
.msie body
{
    font-size:small
}
.msie pre, .msie code, .msie kbd, .msie samp, .msie tt
{
    font-size:108%
}
.msie table
{
    font-size:100%
}
/* YUI base for IE
------------------------------------------------------------------------------*/
.msie input[type=text],
.msie input[type=password],
.msie textarea
{
    width:11.9em
}
/* classes utiles
------------------------------------------------------------------------------*/
.masquer
{
    position:absolute;
    top:-999em;left:-999em;
    display:block;
    height:0;width:0;
    overflow:hidden;
    text-indent:-999em
}
.cacher
{
    display:none
}
.liste
{
    float:left;
    margin:0
}
.liste li
{
    display:block;
    float:left;
    list-style-type:none
}
/* EOF
------------------------------------------------------------------------------*/

Et le petit bout de JS (là encore, à l’état brut) :

/* 
------------------------------------------------------------------------------*/
var BrowserDetect = {
    init: function () {
            this.browser = this.searchString(this.dataBrowser) 
                || "An unknown browser";
            this.version = this.searchVersion(navigator.userAgent)
                || this.searchVersion(navigator.appVersion)
                || "an unknown version";
            this.OS = this.searchString(this.dataOS)
                || "an unknown OS";
        },
        searchString: function (data) {
            for (var i=0;i<data.length;i++) {
                var dataString = data[i].string;
                var dataProp = data[i].prop;
                this.versionSearchString = data[i].versionSearch || data[i].identity;
                if (dataString) {
                    if (dataString.indexOf(data[i].subString) != -1)
                        return data[i].identity;
                    }
                    else if (dataProp)
                        return data[i].identity;
            }
        },
        searchVersion: function (dataString) {
        var index = dataString.indexOf(this.versionSearchString);
        if (index == -1) return;
        return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
    },
    dataBrowser: [
        {
            string: navigator.vendor,
            subString: "Apple",
            identity: "Safari"
        },
        {
            prop: window.opera,
            identity: "Opera"
        },
        {
            string: navigator.userAgent,
            subString: "Firefox",
            identity: "Firefox"
        },
        {
            string: navigator.userAgent,
            subString: "MSIE",
            identity: "Explorer",
            versionSearch: "MSIE"
        }
    ],
    dataOS : [
        {
            string: navigator.platform,
            subString: "Win",
            identity: "Windows"
        },
        {
            string: navigator.platform,
            subString: "Mac",
            identity: "Mac"
        },
        {
            string: navigator.platform,
            subString: "Linux",
            identity: "Linux"
        }
    ]
};
BrowserDetect.init();
/* 
------------------------------------------------------------------------------*/
var browser = "js";
var addclass = "class";
/* OSDetect
------------------------------------------------------------------------------*/
if(BrowserDetect.OS == "Mac")           browser += " mac";
if(BrowserDetect.OS == "Linux")         browser += " linux";
if(BrowserDetect.OS == "Windows")       browser += " win";
/* BrowserDetect
------------------------------------------------------------------------------*/
if(BrowserDetect.browser == "Firefox")  browser += " firefox";
if(BrowserDetect.browser == "Opera" )   browser += " opera";
if(BrowserDetect.browser == "Safari")   browser += " safari";
if(BrowserDetect.browser == "Explorer")addclass = "className";
/* 
------------------------------------------------------------------------------*/
document.getElementsByTagName("HTML")[0].setAttribute(addclass, browser);
/* EOF
------------------------------------------------------------------------------*/

Oui je sais, c’est un peu long… mais vous avez maintenant toutes les cartes en main.

Techniques employées

Je n’ai au final pas inventé grand chose, mais au contraire tenté de combiner aux mieux différentes techniques :

Objectifs

J’ai tenté via cette structure de combiner plusieurs avantages :

  • l’utilisation d’un reset CSS robuste est éprouvé ;
  • la remise à niveau des principaux styles pour éviter de tout devoir redéfinir ;
  • la possibilité de cibler facilement (et sans hack) des élements de la page et ce en fonction du navigateur et du système d’exploitation (.mac .safari #id, .js .classe, etc) ;
  • un chargement de la page optimisé (en suivant principalement quelques-unes des recommandations fournies par Yahoo!) ;
  • une validation (sans erreur ni avertissement) des fichiers HTML et CSS ;
  • fournir un gabarit générique de page pas trop complexe, et couvrant la plupart des cas de montage ;
  • l’inclusion par défaut de JQuery, la bibliothèque JS que j’utilise ;
  • et proposer quelques classes génériques utiles.

Les buts de ce billet maintenant ?

  • Partager avec vous cette structure.
  • Y trouver d’éventuelles critiques et améliorations.
  • La comparer avec vos structures respectives ?

N’hésitez pas !