28173 sujets

CSS et mise en forme, CSS3

Bonjour,
je bute sur un petit problème :

Je souhaite placer une légende sous une image de telle sorte que cette légende ne dépasse jamais la largeur de son image (retour à la ligne auto).
Quelqu'un aurait-il un modèle ou un exemple sur le net ?

Est-il possible de faire cela avec des comportements CSS sachant que je ne peux pas spécifier la largeur des blocs contenant légende et photo (mes pages sont générées dynamiquement, à chaque création d'article la largeur de l'image comme celle de la légende peuvent être différentes et je n'ai pas prévu de règle pour récupérer la largeur d'une image).

Si ce n'est pas possible dans une mise en page CSS/DIV quelqu'un sait-il si c'est possible avec des tableaux ?

merci d'avance si vous avez une idée sur la question
voici en complément le code, j'ai mis volontairement une légende très longue pour souligner le mauvais comportement, la légende dépasse de la photo

<div id="article">
<div class="photo">
  <img src="photo.jpg" alt="" width="300" height="200" />
     <span class="credits">Crédit photo et légende, Crédit photo et
légende, Crédit photo et légende</span>
</div>
<p>Ici le corps de l'article : le texte de l'article doit venir s'aligner à droite
le long de la photo puis sous cette photo. Ici le corps de l'article : le texte
de l'article doit venir s'aligner à droite le long de la photo puis sous cette
photo. Ici le corps de l'article : le texte de l'article doit venir s'aligner à
droite le long de la photo puis sous cette photo.</p>
</div>


et les styles :

#article  { 
padding-bottom:15px;
}

.photo
border:0;
display:block;
float:left;
margin: 0px 5px 5px 0px;
}
.credits
border:0;
text-decoration:none;
display:block;
padding: 2px 0px 0px;
margin:0;
font-family:Arial, Helvetica, sans-serif;
font-size:0.6em;
color:#666666;
clear:left;
}
Ca parait assez complexe ce que tu veux.

Si j'ai bien compris, tu veux que quelque soit la largeur d'une image, le texte en dessous soit de la même largeur ?

Je vois pas de solution si tu peux pas spécifier la largeur et un tableau n'y changera rien.
Tu es obligé de spécifier la largeur d'un bloc contenu de ton image et de ta légende.

Mais là je vois des dimensions à ton image dans le code que tu donnes, je croyais que tu pouvais pas connaitre la largeur ?
Oui, c'est exactement ça, j'ai des images (largeur variable) et une légende par image (nbre de caractères variable), la légende doit se placer en dessous de l'image (comme par exemple sur les sites de presse où tu trouves les crédits photo en dessous de chaque image) et le bloc (span à priori) qui contient la légende ne doit pas élargir le bloc (div) qui contient l'image, ces deux blocs sont en effets imbriqués comme tu as pu le voir dans le code. Je pense que ça doit être un problème classique dans les CMS qui permettent l'insertion de légende ou crédits photos (légende = principe édito de base ET crédits photo = obligation légale)

Pour la largeur de l'image je me suis mal exprimé, elle est bien spécifiée sur la balise Img mais ce que je n'ai pas c'est une règle qui permette de récupérer cette largeur et la coller sur le bloc contenant la légende.

Merci pour ta réponse rapide, il me semblait bien que HTML/CSS ne permet pas un tel comportement mais je n'en était pas tout à fait certain. Je vais donc faire une règle php pour récupérer la largeur de mes images et l'utiliser comme propriété de mes blocs "légende"

problème résolu
PHP ???

Pas besoin de PHP !
Tu récupère la valeur de l'attribut width de l'image (via JS) et tu applique cette valeur au width de ton bloc parent et ça roule (eventuellement avec un peu de padding)

Typiquement ça donnerai ça :

function getImgWidth() {
  var photos = document.getElementsByTagName('div');
  for (var i = 0; i < photos.length; ++i) {
    if (photos[ i].getAttribute('class').split(' ').inArray('photo')) {
      var myPic = photos[ i].getElementsByTagName('img')[0];
      photos[ i].style.width = myPic.getAttribute('width');
    }
  }
}

Array.prototype.inArray = function(val) {
	for(var a2 = 0; a2 < this.length; ++a2) {
		if(this[a2] == val){
		return true;
		}
	}
	return false;
};


J'ai pas testé, mais ça doit fonctionner.
Au pire tu redemandes si ça merdouille et je test chez moi.
Modifié par Olivier (10 May 2005 - 11:20)
Voilà, j'ai corrigé, parceque ça merdouillais !

		function getImgWidth() {
			var photos = document.getElementsByTagName('div');
			for (var i = 0; i < photos.length; ++i) {
				if (photos[ i].getAttribute('class') && photos[ i].getAttribute('class').split(' ').inArray('photo')) {
					var myPic = photos[ i].getElementsByTagName('img')[0];
					photos[ i].style.width = myPic.getAttribute('width') + 'px';
				}
			}
		}
		
		Array.prototype.inArray = function(val) {
			for(var a2 = 0; a2 < this.length; ++a2) {
				if(this[a2] == val){
				return true;
				}
			}
			return false;
		};
		
		window.onload = getImgWidth;


Faudra pas que t'oubli d'enlever les espace dans les [ i] je les ai mis pour inhiber le BBcode

Exemple en ligne :
http://elmoustikoblog.net/aide/widthPhoto/
Modifié par Olivier (10 May 2005 - 11:35)
il y a un "hic" : j'ai une contrainte d'accesibilité très poussée, si je ne me trompe pas 7% environ des internautes utilisent des materiels où javascript est désactivé (source : openweb), le CMS sur lequel je bosse devra notamment produire des pages optimisées pour les materiels handicapés (navigateurs adaptés/synthèses vocales/plages brailles/etc.) ... alors je bosse côté serveur
tous mes alt seront bien remplis, c'est promis Smiley smile
je pousse même le zèle jusqu'à mettre une petite étoile (*) pour les alt des images non signifiantes (comme on dit) (puces personnalisées par une image par exemple) afin que les 0,003% de visiteurs aveugles de mon site n'aient pas leur synthèse vocale qui leur dise "puce" à chaque puce ...
Bonjour loubnei Smiley smile

Concernant l'accessibilité, il y a deux options :

- La balise "alt" dans laquelle tu peux récupérer le contenu d'une variable (80 caractères maximum).
-"Longdesc" qui te permet de placer un descriptif sur une page texte, le lien s'affichera à la place du graphisme.

J'ai le sentiment que tu cherches à réunir le tout sur une seule page au lieu d'utiliser les éléments recommandés ???

Quel CMS utilises-tu ? stp Smiley cligne
Modifié par dominique (10 May 2005 - 11:46)
Ehh bien ça n'a rien d'accessible JS inactif... tu auras juste la mise en forme en moins et c'est pas bien grave.

Et navigateur spécialisé pour handicap quelconque, ça veut pas dire non plus JS inactif.

Enfin tu fais comme tu veux, tu surcharge inutilement le serveur pour une action côté client... m'enfin

Sinon, au niveau du code HTML.

<span> => <p>
Ou même utiliser les listes de définitions qui sont très adaptées à ce genre de situation.
Olivier :
dans mon cas ça relève de quasimet de l'accessibilité, si javascript est désactivè je risque de me retrouver avec des cas extrêmes où une légende trop longue repousse l'article (qui est aligné sur la droite de l'image) de sorte que seuls les mots de quelques lettres s'afficheront à droite de l'image et le reste de l'article descendra sous l'image, j'ai fait le tests et c'est pas génial pour la lisibilité (le cas n'est pas hypothétique car le CMS sera utilisé par un grand nombre de contributeurs)
pour ma part si j'avais le dernier mot sur l'usage de javascript dans le projet sur lequel je bosse alors je pense que je l'aurai utilisé
merci en tous cas pour les lignes de code, je les garde au chaud en cas de projet soumis à moins de contraintes

Dominique :
Je travaille sur un CMS développé en interne pour l'administration (php/mysql) pour des besoins très spécifiques auxquels les CMS libres ne répondaient pas à l'époque où le projet a été lancé, pour ma part je ne bosse que sur le Front (ergonomie/graphisme/accessibilité)
J'ai pas trop capté le problème, m'enfin bref, tu dois savoir de quoi tu parles.

Par contre, pour le code HTML utilisé, faudrait revoir comme je te le disais.
Si je peux me permettre...
Si on génére un truc comme ca (avec php):


<div class="imgGauche"><img alt="texte Alt" src="toto.jpg" />
<p style="width: $width;">texte Alt</p>
</div>


En allant prendre $width soit dans le tag img (si elle est définie) soit avec getimagesize() sur le fichier image original, et en affichant comme légende le contenu Alt c'est bien?...

Pour l'accessibilité, c'est pas trop grave d'avoir deux fois le même texte??
Modifié par Nathan- (15 Nov 2005 - 21:50)
Voici le petit bout de code que j'ai dans mon script php pour ajouter automatiquement des légendes aux images (tirées des atributs "alt").

en gros, ca remplace dans un contenu tiré d'une base de données
($contenuXX) toutes les occurences <img src="toto.jpg" alt="blabla" /> par un <div> contenant l'image et un paragraphe légende de la largeur de l'image :
<div><img src="toto.jpg" alt="blabla" ></img>
<p style="width: $width;">blabla</p>
</div>


//TRAITEMENT DES IMAGES
//Dans le cms, on peut définir deux classes d'images : .imgGauche et .imgDroite
//On va mettre en légende le contenu de la balise alt
//Il faut détecter toutes les balises <img> ,
//<img width="164" height="200" class="imgDroite" src="/images/Image/braille-board_Opt.jpg" alt="Une tablette braille" longdesc="déscription longue test" />
//- La classe de l'image va être transferée au div
//- Si la largeur n'est pas définie dans l'image, on va tenter de la trouver à l'aide de getimagesize
//- La largeur sera également attribuée au paragraphe légende afin qu'il ne dépasse pas.

//on va remplacer l'image par un div de ce style...
//<div class="$class"><img width="$width" height="$height" alt="$texteAlt" longdesc="$longDesc" src="$src" />
//<p style="width: $width;">$texteAlt</p>
//</div>
			
function rechercheValeur($aTrouverXX,$tagXX){
//Cette fonction recherche la valeur d'un parametre $aTrouver se trouvant dans un tag
//et la retourne (false si le parametre n'est pas trouvé.)
//ex : rechercheValeur('width','<img class="test" width="300" src="toto.jpg">') va retourner 300

$aTrouverXX.="="; //on ajoute = ... y'a moins de chances de trouver width= que width dans le alt (ce qui serait chiant)
if($posXX=strpos($tagXX,$aTrouverXX){		
	$tempXX=substr($tagXX,$posXX+strlen($aTrouverXX)+1,strlen($tagXX)); //on vire le début
	$tempXX=substr($tempXX,0,strpos($tempXX,'"')); //on vire la fin
	return $tempXX;
}else{
	return false;
}	
}// fin rechercheValeur
			
//On recherche la première image
$nextPosImg=strpos($contenuXX,"<img");
while(($nextPosImg!==false)){
	$imgXX=substr($contenuXX,$nextPosImg,strlen($contenuXX)); //on vire le début
	$imgXX=substr($imgXX,0,strpos($imgXX,"/>")+2); //on vire la fin
if($nextPosImg!==false){ 
	//on recherche $src
	$srcXX=rechercheValeur("src",$imgXX);
	//on recherche $alt
	$altXX=rechercheValeur("alt",$imgXX);
	//on recherche $longdesc
	$longdescXX=rechercheValeur("longdesc",$imgXX);
	//on recherche $class
	$classXX=rechercheValeur("class",$imgXX);
	//on recherche $width
	$widthXX=rechercheValeur("width",$imgXX);
	//on recherche $height
	$heightXX=rechercheValeur("height",$imgXX);
}
//on calcule le div (on met TEMP à la place d'<img pour ne pas faire une boucle infinie...)
$divXX='<div class="'.$classXX.'"><TEMP src="'.$srcXX.'"';
//si alt existe
if($altXX){
	$divXX.=' alt="'.$altXX.'"';
}
//si longdesc existe
if($longdescXX){
	$divXX.=' longdesc="'.$longdescXX.'"';
}
//si width..
if($widthXX){
	$divXX.=' width="'.$widthXX.'"';
}
//si height..
	if($heightXX){
$divXX.=' height="'.$heightXX.'"';
}
//fin tag </img> début de la légende
//evidement, si y'avait des autres valeurs, elles vont gicler...
$divXX.='></img><p';
//si la largeur est définie dans l'image, on l'utilise... sinon, on va chercher la largeur de l'image avec getimagesize()
if(!$widthXX){
//ATTENTION, VA SUREMENT MERDER SI PHP TROUVE PAS L'IMAGE... ADAPTER LE CHEMIN...
	$getImageSizeXX=getimagesize("../".$srcXX);
	$widthXX=$getImageSizeXX[0];
}
//si la largeur est définie, on l'attribue au style du paragraphe pour que la légende ne dépasse pas.
if($widthXX){
	$divXX.=' style="width:'.$widthXX.'px;"';
}
//contenu et fin de la légende, fin du div
$divXX.='>'.$altXX.'</p></div>';
//on remplace l'<img dans le contenu par le <div qu'on vient de calculer...
$contenuXX=str_replace($imgXX,$divXX,$contenuXX);		
//position de l'image suivante
$nextPosImg=strpos($contenuXX,"<img");
}//end while y'a des <img
						
//on remet les <img à la place des <TEMP
$contenuXX=str_replace("<TEMP","<img",$contenuXX);
			
//et hop et voila... plus qu'a retourner...
echo($contenuXX);
//on peut styler .imgGauche et .imgDroite ainsi que .imgGauche img, .imgGauche p, etc...
			


Heu... voila... je sais pas si ça peut servir... ni si c'est compréhensible... et en plus, le contenu alt est dupliqué et peut-être détourné de son utilisation originale...

Vous pouvez voir ce que ca donne sur le site :
www.coeur.ch
Il y a des images un peu partout qui sont "légendées" avec cette méthode.
Modifié par Nathan- (28 Jan 2006 - 15:44)