11484 sujets

JavaScript, DOM et API Web HTML5

Bonjour !

J'ai commencé a me créer il y a quelques temps mon site en html et css mais il y a une question sur laquelle je bute :
comment changer de feuille de style en fonction de la largeur utile du navigateur ?

je ne parle pas des largeurs en pourcentage qui s'adaptent automatiquement (incompatible avec mon site car il contient surtout de l'image comme c'est un portfolio), mais d'avoir deux feuilles de style différentes suivant si la largeur du navigateur est supérieure ou inférieure à une certaines barre.

J'ai un exemple bien précis avec le site abduzeedo. Sur la home les actualités sont sur 4 colonnes sur les écrans "larges" et sur seulement 3 colonnes pour les largeurs d'écrans plus faibles.

J'ai beau eu chercher mais je n'ai rien trouvé à ce sujet... Merci d'avance pour le coup de main !

(j'ai posté dans cette section car je suppose qu'il va falloir un peu de javascript mais a vrai dire je n'en sais rien du tout... Smiley sweatdrop )
Modifié par hangmaniak (26 Aug 2010 - 14:53)
Bonjour,

Le site donné en exemple utilise peut-être JavaScript, mais je n'ai pas cherché exactement.
Il y a des techniques qui consistent à mesurer la largeur du viewport au chargement de la page, et soit charger une feuille de styles spécifique (en créant un élément LINK dans le DOM, par exemple), soit simplement à rajouter une classe sur un élément tel que BODY. C'est un peu prise de tête pour trouver un code qui prenne tous les navigateurs en compte, et l'exécution du script peut arriver un peu tard dans le chargement de la page et entrainer un changement perceptible de la mise en page.

Mais JavaScript, c'est la solution historique. La solution moderne, ce sont les Media Queries en CSS3. Exemple rapide:
body {
  padding: 0 40px;
}
@media screen and (max-width: 600px) {
  body {padding: 0 10px;}
}

Supporté dans tous les navigateurs un peu récents, sauf IE8 (il faudra attendre IE9...).
Bonjour et merci d'avoir répondu rapidement !

Cependant si j'ai bien compris cette histoire de media queries en css3, ca ne marche que sur les versions récentes des navigateurs et pas du tout sur ie ? J'ai peur que ca ne fasse pas beaucoup de monde au final !

sinon j'ai continué à chercher de mon coté et je suis tombé sur ce blog :
http://www.blog.manit4c.com/2010/04/12/appliquer-une-feuille-de-style-selon-la-resolution-de-lecran/
ca décrit exactement ce que je souhaite en utilisant dojo mais j'arrive pas à faire fonctionner le bignou ! (désolé mais je suis graphiste à la base donc la prog pour moi se limite à un peu d'html, css voire actionscript ^^)

j'ai créé un ptit fichier pour tester et voila mon code html (avec une partie reprise d'un tuto du site Smiley cligne ) :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Document sans nom</title>

<script src="http://o.aolcdn.com/dojo/1.5/dojo/dojo.xd.js" type="text/javascript"></script>

<link rel="stylesheet" href="800-600.css" title="800*600" media="jamais"/>


</head>
<body>


<div id="conteneur"> 
    <div id="header"> 
        <!-- Ceci est mon haut de page --> 
    </div> 
    <div id="sidebar"> 
        <!-- Ceci est ma colonne latérale --> 
    </div> 
    <div id="contenu"> 
        <!-- Ceci est mon contenu principal --> 
    </div> 
    <div id="footer"> 
        <!-- Ceci est mon pied de page --> 
    </div> 
</div>

<script language="javascript">
function loadCss800600() {
var viewport = dijit.getViewport();
var viewport_width = viewport.w;
if(viewport_width<800) {
var monCss=(dojo.query('link[title="800*600"]'));
monCss[0].media="screen";
}
}
dojo.addOnLoad(loadCss800600);
</script>

</body>
</html>


et la feuille de style css qui est sensée se charger :

@charset "utf-8";
/* CSS Document */

#header
{
	width: 800px;
	height: 50px;
	background-color: red;
}

#sidebar
{
	position:absolute;
	margin-left: 600px;
	width: 200px;
	height: 300px;
	background-color: yellow;
}

#contenu
{
	width: 500px;
	height: 500px;
	background-color: blue;
}

#footer
{
	width: 800px;
	height: 50px;
	background-color: gray;
}


kékivapa ?
Modérateur
Salut,

Dans ton code, la valeur de l'attribut media est "jamais" au lieu de "screen".
Oui c'est normal, d'après le tuto on doit récupérer la largeur de l'écran et lorsque celle ci est en dessous de 800px le valeur de l'attribut doit être remplacée par screen pour charger la feuille de style... mais bon j'ai beau redimensionner ma page rien ne se passe !
Modérateur
Ah... Yep ! J'ai répondu un peu vite sans avoir regardé l'article. Smiley langue

Bon bah c'est parce que dans le tuto, il a oublié de préciser qu'il fallait ajouter :
dojo.require("dijit._base.place");
avant ta fonction car la fonction getViewport n'est pas disponible sans, ce qui te générait une erreur visible avec la console de Firebug.
du coup j'ai ajouté ta ligne de code mais ca fonctionne toujours pas... je l'ai bien mise au bon endroit ??

<script language="javascript">
dojo.require("dijit._base.place");
function loadCss800600() {
var viewport = dijit.getViewport();
var viewport_width = viewport.w;
if(viewport_width<800) {
var monCss=(dojo.query('link[title="800*600"]'));
monCss[0].media="screen";
}
}
dojo.addOnLoad(loadCss800600);
</script>
Modérateur
Salut,

oui, tout à fait et chez moi, ça fonctionne correctement dès lors, qu'au chargement de la page, l'espace occupé par la fenêtre est inférieur à 800px de large.

Là où ça ne fonctionne pas, c'est si on redimensionne la fenêtre après chargement de la page... et pour cause, le code ici présent ne prévoit pas ce cas.
Salut, merci pour cette petite précision, en effet ca marche beaucoup mieux !
J'avoue que c'est pas exactement ce que j'espérais mais je peux m'en contenter pour le moment c'est un bon début.
En revanche je pensais (naïvement visiblement...) qu'il me suffirait de rajouter une déclaration de feuille de style puis un autre script pour pouvoir choisir entre 2 feuilles de style (ce qui est bien l'intérêt de la chose à mon avis !) mais cela ne fonctionne pas non plus...

du coup pour les feuilles de styles j'ai :

<link rel="stylesheet" href="1024-768.css" title="1024*768" media="jamais"/>
<link rel="stylesheet" href="800-600.css" title="800*600" media="jamais"/>


et pour le javascript en bas de page j'ai :

]
<script language="javascript">
dojo.require("dijit._base.place");
function loadCss800600() {
var viewport = dijit.getViewport();
var viewport_width = viewport.w;
if(viewport_width<800) {
var monCss1=(dojo.query('link[title="800*600"]'));
monCss1[0].media="screen";
}
}
dojo.addOnLoad(loadCss800600);
</script>

<script language="javascript">
dojo.require("dijit._base.place");
function loadCss1024768() {
var viewport = dijit.getViewport();
var viewport_width = viewport.w;
if(viewport_width>800) {
var monCss=(dojo.query('link[title="1024*768"]'));
monCss[0].media="screen";
}
}
dojo.addOnLoad(loadCss1024768);
</script>


Mais ca ne fonctionne qu'avec le première feuille de style déclarée (donc dans le cas présent avec 1024-768.css).
Modérateur
Ah... Visiblement, tu ne pipes pas un mot au script. Smiley rolleyes

Ce que tu peux faire, c'est ne laisser qu'un seul appel du type :
<link rel="stylesheet" href="800-600.css" title="custom" media="jamais"/>
puis modifier le script de la sorte :
dojo.require("dijit._base.place");

function loadCss() { 
	var viewport_width = dijit.getViewport().w;
	var monCss = (dojo.query('link[title="custom"]'));
	if(viewport_width < 800) {
		monCss[0].media = "screen"; 
	}
	else if(viewport_width < 1024) {
		monCss[0].media = "screen";
		monCss[0].href = "1024-768.css";
	}
}
 
dojo.addOnLoad(loadCss);
En somme, la première ligne récupère la largeur de la page, la seconde ligne cible l'élément link ayant pour titre "custom" puis suivant la valeur de "viewport_width", on modifie (ou non) les attributs de la balise link en conséquence.
Ca se voit tant que ca...? Smiley confused
Comme je disais plus haut je suis graphiste mais j'aime tout de même programmer un peu et c'est toujours frustrant de pas pouvoir faire exactement ce qu'on a en tête !

Pour en revenir à ton code c'est nickel ! Merci beaucoup de prendre du temps pour aider des personnes comme moi qui débutent !
Modérateur
Nan mais je te rassure, on est tous passé par là, moi compris. Smiley ravi C'est juste que dans le code que tu m'as présenté, tu as dupliqué le tout (y compris le chargement de la librairie appelée avec la méthode require) au lieu de tenter de modifier la fonction pour arriver à tes fins... ce qui n'est effectivement pas un réflexe de programmeur. Smiley cligne