28172 sujets

CSS et mise en forme, CSS3

Bonjour,

Je souhaite mettre côte à côte 3 div, jusque là rien d'exceptionnel, mais j'ai quelques exigences qui rendent tout ceci un peu compliqué pour moi :

les 3 div côte à côte :
- doivent occuper tout l'espace disponible (largeur de l'écran)
- ne doivent pas dépasser la largeur de l'écran
- doivent garder la même hauteur, quel que soit le contenu
- doivent rester côte à côte, quelle que soit la largeur de l'écran

div de gauche :
- la largeur doit être fixe

div du centre :
- elle doit occuper tout l'espace disponible pour afficher un maximum de contenu
- si son contenu occupe trop de place pour tenir sur une seule ligne, il doit être tronqué
- son contenu doit (idéalement) être centré par rapport à la page et non par rapport à la div

div de droite :
- elle ne doit en aucun cas masquer une partie de son contenu
- sa largeur doit être identique à celle de son contenu, de façon à libérer un maximum de place pour la div du centre

J'ai passé pas mal de temps à essayer diverses solutions (j'ai même essayé avec display:table), mais je me retrouve toujours bloqué par un point.

À l'heure actuelle, j'en suis là :

<div class="wrapper">
  <div class="wrapmiddle"> 	  
    <div class="middle">contenu centré et non prioritaire</div>
  </div>
  <div class="left">largeur fixe</div>	    
  <div class="right">contenu prioritaire</div> 
</div>


.wrapper{
    width: 100%;
    margin: 0 auto;
}

.wrapmiddle{
    float: left;
    width: 100%;
    background-color: yellow;
}

.middle{
    margin-right:102px;
    margin-left:102px;
    background-color: pink;
    height: 50px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis; 
    text-align: center;
}

.left{
    float: left;
    width: 100px;
    margin-left: -100%;
    background-color: blue;
    height: 50px;
}

.right{
    float: left;
    width: 100px;
    margin-left: -100px;
    background-color: red;
    height: 50px;
    white-space: nowrap;
    overflow: hidden;
}


Mais ma div de droite est fixe ce qui est gênant, car :
- si trop petite, elle n'affiche pas l'intégralité de son contenu
- si trop grande, elle gaspille inutilement l'espace qui devrait être disponible pour le contenu de la div du centre

J'ai fait un Codepen ici si vous voulez voir à quoi cela ressemble.

Je vous remercie beaucoup de votre aide Smiley smile

Blaise
Modérateur
Salut,

Edit :
En fait, j'ai beau me creuser les méninges, je vois pas en tête ce que tu veux faire. Il faudrait que tu nous en dises un peu plus. Pourquoi à droite le contenu doit être prioritaire ? Pourquoi la hauteur doit être la même partout ? Qu'est ce que tu cherches à faire ?

Certaines contraintes sont trop floues :
Smiley biggol
a écrit :

son contenu doit (idéalement) être centré par rapport à la page et non par rapport à la div

a écrit :

sa largeur doit être identique à celle de son contenu, de façon à libérer un maximum de place pour la div du centre


.right{width: 100px;}

Modifié par niuxe (17 Jan 2015 - 14:57)
Modérateur
Saut Victor,

Victor BRITO a écrit :

Regarde du côté du module flexbox et de la propriété text-overflow.


J'ai pensé aussi au model de boite flex. Tu connais le même souci que moi ? Le/s cancre/s ne comprennent pas cette règle (Microsoft (toujours dans l'innovation), on t'aime).


Pour revenir au sujet, Il y a de la contradiction dans ce qu'il dit. Il faudrait en savoir un plus sur le contenu et le comportement.
Modifié par niuxe (17 Jan 2015 - 15:29)
Bonjour,

Avant tout, merci beaucoup du temps que vous me consacrez !

Je suis désolé si j'ai manqué de précision/clarté ; en fait je travaille sur le header d'une application mobile (tablettes et smartphones Android, iPhone, Windows Phone) ce qui fait que j'ai quelques contraintes de largeur d'écran.

Ce header est divisé en 3 zones :
- gauche (le logo de l'appli)
- centre (le titre de la vue)
- droite (un nombre de points)

Si l'écran ne permet pas l'affichage de l'ensemble des informations, c'est le titre qui devra être tronqué (le nombre de points est une information primordiale, et un logo coupé en 2 c'est pas terrible...).

J'ai tenté de nombreuses solutions depuis hier, notamment la solution que tu (niuxe) as pu me proposer avant d'éditer ton message (à base de table), mais je n'arrivais pas à gérer l'overflow.

Je ne connaissais pas flexbox, mais cela me semble être la meilleure solution. Pour me simplifier la tâche, j'ai divisé mon header en 2 (plutôt qu'en 3), j'ai placé le logo en arrière-plan, et j'ai ajouté un margin-left pour ne pas que le texte s'affiche par dessus.

Je suis arrivé à ça :

<div id="container">
  <div id="left"><p>Nom de la vue qui peut être tronqué si l'écran ne permet pas de tout afficher</p></div>
  <div id="right"><p>1234 pts</p></div>
</div>


#container{
  background-color: pink;
  height: 70px;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
}

#left{
  background-color: yellow;
  background-image: url("http://placehold.it/50&text=logo");
  background-size: 50px 50px;
  background-repeat: no-repeat;
  background-position: left center;
  -webkit-flex: 1;
  -ms-flex: 1;
  flex: 1;
}

#right{
  background-color: red;
}

#left p{
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis; 
  margin-left: 60px;
}

#right p{
  white-space: nowrap;
}


Mais à ma grande surprise, cela fonctionne parfaitement dans IE et Chrome et pas dans Firefox...
Si vous voulez tester (en réduisant la largeur de la fenêtre), j'ai fait un Codepen ici.

Je suis preneur :
- d'une meilleure solution
- d'idées pour que cela fonctionne dans Firefox
- de la bonne méthode pour aligner verticalement le contenu de mes div avec flexbox (sinon je peux faire ça avec line-height, mais il me semble que flexbox permet de le faire)

Je vous remercie encore Smiley smile

Blaise.
Modifié par Blaise18 (19 Jan 2015 - 11:40)
niuxe a écrit :
J'ai pensé aussi au model de boite flex. Tu connais le même souci que moi ? Le/s cancre/s ne comprennent pas cette règle (Microsoft (toujours dans l'innovation), on t'aime).

IE 11 le gère très bien, et sans préfixe (contrairement à WebKit), IE 10 aussi (même s'il se base sur la syntaxe de la spec telle qu'elle était en 2012, moyennant préfixe). Quant à IE 9 et 8, un fallback est vite trouvé qui tienne la route.

Bref, ne joue pas au samedÿste voulant jouer les prolongations du vendredÿ. Smiley langue
Bonjour,

Je me réponds à moi-même car je viens de trouver une solution à mon problème.

Le code ci-dessous répond à chacun des points énoncés dans mon premier post :
<table id="topbar">
  <tr>
    <td class="left">Morbi imperdiet neque ut lorem rhoncus fermentum.</td>
    <td class="right">1234 pts</td>
  </tr>
</table>

#topbar {
  height: 70px;
}

#topbar td.left {
    width: 100%;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    background-color:red;
    max-width: 1px;
    background-image: url("http://placehold.it/50&text=logo");
    background-size: 50px 50px;
    background-repeat: no-repeat;
    background-position: left center;
    padding-left: 60px;
    text-align:center;
}

#topbar td.right {
    white-space: nowrap;
    background-color:yellow;
}


Comme d'habitude, un CodePen pour voir ce que ça donne (réduisez la largeur de la fenêtre).

Merci à tous pour votre aide Smiley smile

Blaise.