web-dev-qa-db-fra.com

Solution Pure CSS - Des éléments carrés?

Si j'ai un <div> avec une largeur relative (telle que width: 50% ), existe-t-il un moyen simple de lui donner la même largeur que la hauteur sans recourir à JavaScript?

20
Trey Keown

Il est en fait possible d'y parvenir avec cette astuce que j'ai trouvée à ce blog

#square {
   width: 100%;
   height: 0;
   padding-bottom: 100%;
}

J'espère que cela pourra aider

42
Tomasz Kowalczyk

Non et oui (Kinda)

OK, donc la réponse courte est "non", impossible. La réponse longue est "oui", compte tenu de certaines contraintes et de certaines concessions (c.-à-d. Un balisage HTML supplémentaire et des limitations sur ce qui peut être fait).

Étant donné ce CSS:

.square {
    position: relative;
    margin: 20px;
    display: inline-block; /* could be float */
    overflow: auto; /* UPDATE: if content may overflow square */
}
.sq-setter-w {
    width: 100%;
    height: auto;
    visibility: hidden;
}
.sq-setter-h {
    width: auto;
    height: 100%;
    visibility: hidden;
}
.sq-content {
    position: absolute;
    z-index: 1;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
}

Avec ce HTML:

<div class="square" style="width: 200px">
    <img src="http://dummyimage.com/50x50/000/fff.gif&text=50x50" class="sq-setter-w"/>
    <div class="sq-content">Here is content</div>
</div>
<div class="square" style="height: 100px">
    <img src="http://dummyimage.com/50x50/000/fff.gif&text=50x50" class="sq-setter-h"/>
    <div class="sq-content">Here is content</div>
</div>
<div class="extrawrapper">
<div class="square" style="width: 200px">
    <img src="http://dummyimage.com/50x50/000/fff.gif&text=50x50" class="sq-setter-w"/>
    <div class="sq-content">Here is content</div>
</div>
</div>
<div class="extrawrapper">
<div class="square" style="height: 100px">
    <img src="http://dummyimage.com/50x50/000/fff.gif&text=50x50" class="sq-setter-h"/>
    <div class="sq-content">Here is content</div>
</div>
</div>

Vous pouvez le faire faire ce que ce violon montre .

Les clés sont:

  1. L'image utilisée doit être une image carrée, car elle détermine le dimensionnement proportionnel (l'élément img est le seul élément capable d'effectuer ce travail proportionnel car il peut baser sa taille sur la proportion de l'image elle-même).
  2. Vous devez savoir si vous allez définir la width ou la height afin de pouvoir définir la classe d'image correctement pour la redimensionner. Facultatif, définissez la width ou height sur la img elle-même, vous n'avez donc pas à vous soucier de la définition d'une classe avec la valeur 100%. Ma démo supposait que vous définissiez la taille du div de l'emballage (ma classe .square).
  3. Pour que la div disparaisse autour de la img qui commande le dimensionnement proportionnel, vous devez définir display: inline-block ou une float sur la div (comme indiqué dans le css ci-dessus).
  4. En raison de # 3, si vous voulez que div agisse davantage comme un "bloc", vous devez leur donner un wrapper supplémentaire div comme le montrent les troisième et quatrième.

De toute évidence, cette solution implique beaucoup de marge supplémentaire. Ainsi, à bien des égards, il est préférable de dire "utilisez simplement du javascript", mais je voulais prouver que cela pouvait être fait (au moins dans certains cas) uniquement avec HTML et CSS.

Mise à jour: pour montrer la possibilité de dimensionnement flexible

Voir ce violon pour les pourcentages déterminant la taille , avec cet exemple html (width défini sur 30%):

<div class="square" style="width: 30%">
    <img src="http://dummyimage.com/50x50/000/fff.gif&text=50x50" class="sq-setter-w"/>
    <div class="sq-content">Here is content</div>
</div>
12
ScottS

J'avais besoin de réaliser quelque chose de similaire aujourd'hui et j'avais la même idée avec l'image. Je voulais vérifier d'autres possibilités et Google m'a conduit ici.

... vous n'avez pas vraiment besoin d'une image src. vous pouvez simplement utiliser un hash si vous voulez un carré. Il enregistre une demande http.

Si vous souhaitez obtenir un rapport de format différent, vous devez utiliser une variable src cependant. Si vous voulez avoir un ratio de 16: 9, l’image doit être de 16px large et de 9px haut (aussi petite que possible).


Comparer les deux techniques (voir les autres réponses dans ce fil de discussion)

img contre padding-bottom

Voici un violon pour montrer à quel point la version img est plus compatible (peut facilement gérer pxvalue aussi (un intervalle redimensionnera le "carré" chaque seconde)

Si vous utilisez des valeurs en pourcentage, les deux techniques peuvent donner le même résultat mais la version de remplissage ne nécessite pas de balisage supplémentaire (<img src="#"/>).


Conclusion:

En fonction de la mise en œuvre, chaque technique a ses avantages et ses inconvénients.


HTML

<div class="floater">
    <div class="square square_noImg">
        <div class="inner">Hey blue you look totally squared</div>
    </div>
    <div class="square square_img">
        <img src="#"/>
        <div class="inner">Hey red you seem off</div>
    </div>
</div>

CSS

.floater {
    font-size: 0;
}
.square {
    position: relative;
    display: inline-block;
    width: 100px;
    margin: 0 5px; 
}
.square_noImg {
    padding-bottom: 100px;
    background: red;
}
.square_img {    
    background: blue;
}
img{
    width: 100%;
    height: auto;
    border: 0;
    visibility: hidden;
}
.inner {
    position: absolute;
    top: 10%;
    right: 10%;
    bottom: 10%;
    left: 10%;
    background: white;
    font-size: 14px;
    text-align: center;
    overflow: hidden;
    padding: 10px 5px;
}
2
user950658

Cela ne peut pas être fait avec CSS seul. En utilisant jQuery, vous pouvez y parvenir en faisant

var chld = $('.child').width();
$('.child').css({'height':chld+'px'});

Consultez l'exemple de travail sur http://jsfiddle.net/4Jnfq/


Une solution uniquement CSS peut être trouvée ici sur la dernière mise à jour "Redimensionner avec contenu".
Bien qu’il s’applique aux cercles, vous pouvez supprimer le border-radius: 50% pour qu’il fonctionne avec les carrés.

Pas avec des unités relatives comme %, car elles seraient calculées par rapport à un élément conteneur. Mais il est possible de créer un élément carré si vous utilisez des unités telles que px ou em pour définir les deux dimensions.

0
bfavaretto

Une approche JS native en réponse au commentaire @Dave sur @ praveen-kumar answer:

var squareElement = function(el) {
    el.style.height = el.offsetWidth + 'px';
}

et l'utiliser n'importe où

squareElement(document.querySelector('your-selector'));
0
Antoine