web-dev-qa-db-fra.com

Permuter la position DIV avec CSS uniquement

J'essaie d'échanger deux emplacements de divs pour un design réactif (le site a une apparence différente en fonction de la largeur du navigateur/convient aux mobiles).

En ce moment j'ai quelque chose comme ça:

<div id="first_div"></div>
<div id="second_div"></div>

Mais serait-il possible d'échanger leurs emplacements pour que cela ressemble à second_div est le premier, en utilisant uniquement CSS? Le HTML reste le même. J'ai essayé d'utiliser des flotteurs et d'autres choses, mais cela ne semble pas fonctionner comme je le souhaite. Je ne veux pas utiliser le positionnement absolu car les hauteurs de divs changent constamment. Y a-t-il des solutions ou n'y a-t-il aucun moyen de le faire?

68
Dragonfly

Quelqu'un m'a mis en relation ceci: Quelle est la meilleure façon de déplacer un élément qui se situe du haut vers le bas dans le design réactif .

La solution dans cela a parfaitement fonctionné. Bien qu’il ne prenne pas en charge les anciens IE, cela n’a aucune importance pour moi, car j’utilise le responsive design pour mobile. Et cela fonctionne pour la plupart des navigateurs mobiles.

En gros, j'avais ceci:

@media (max-width: 30em) {
  .container {
    display: -webkit-box;
    display: -moz-box;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;
    -webkit-box-orient: vertical;
    -moz-box-orient: vertical;
    -webkit-flex-direction: column;
    -ms-flex-direction: column;
    flex-direction: column;
    /* optional */
    -webkit-box-align: start;
    -moz-box-align: start;
    -ms-flex-align: start;
    -webkit-align-items: flex-start;
    align-items: flex-start;
  }

  .container .first_div {
    -webkit-box-ordinal-group: 2;
    -moz-box-ordinal-group: 2;
    -ms-flex-order: 2;
    -webkit-order: 2;
    order: 2;
  }

  .container .second_div {
    -webkit-box-ordinal-group: 1;
    -moz-box-ordinal-group: 1;
    -ms-flex-order: 1;
    -webkit-order: 1;
    order: 1;
  }
}

Cela fonctionnait mieux que les flotteurs pour moi, car j'avais besoin de les empiler les uns sur les autres et j'avais environ cinq divs différents que je devais échanger la position.

112
Dragonfly

Cette question a déjà une excellente réponse, mais dans l’esprit d’explorer toutes les possibilités, voici une autre technique permettant de réorganiser les éléments dom tout en leur permettant de prendre de la place, contrairement à la méthode de positionnement absolu.

Cette méthode fonctionne dans tous les navigateurs modernes et IE9 + (essentiellement tout navigateur prenant en charge display: table). Elle présente toutefois l’inconvénient de ne pouvoir être utilisée que sur un maximum de 3 frères et sœurs.

//the html    
<div class='container'>
    <div class='div1'>1</div>
    <div class='div2'>2</div>
    <div class='div3'>3</div>
</div>

//the css
.container {
   display:table;    
}
.div1 {
    display:table-footer-group;
}
.div2 {
    display:table-header-group;
}
.div3 {
    display:table-row-group;
}

Cela va réorganiser les éléments de 1,2,3 à 2,3,1. Fondamentalement, tout ce qui a l’affichage réglé sur table-en-tête-groupe sera positionné en haut et le groupe de bas de page en bas. Naturellement, groupe-ligne-groupe place un élément au milieu.

Cette méthode est rapide avec un bon support et nécessite beaucoup moins de CSS que l’approche flexbox), donc si vous cherchez seulement à échanger quelques éléments contre une mise en page mobile, par exemple, n’excluez pas cette technique.

Vous pouvez visionner une démonstration en direct sur codepen: http://codepen.io/thepixelninja/pen/eZVgLx

29
Ed Fryed

La réponse acceptée a fonctionné pour la plupart des navigateurs, mais pour une raison quelconque, sur iOS Chrome et les navigateurs Safari, le contenu qui aurait dû apparaître en deuxième position était masqué. et finalement, j'ai essayé la solution suivante qui m'a donné l'effet recherché (changer l'ordre d'affichage du contenu sur les écrans mobiles), sans bugs de contenu empilé ou caché:

.container {
  display:flex;
  flex-direction: column-reverse;
}

.section1,
.section2 {
  height: auto;
}
23
Jason Awbrey

Utilisation de CSS uniquement:

#blockContainer {
display: -webkit-box;
display: -moz-box;
display: box;

-webkit-box-orient: vertical;
-moz-box-orient: vertical;
box-orient: vertical;
}
#blockA {
-webkit-box-ordinal-group: 2;
-moz-box-ordinal-group: 2;
box-ordinal-group: 2;
}
#blockB {
-webkit-box-ordinal-group: 3;
-moz-box-ordinal-group: 3;
box-ordinal-group: 3;

}

<div id="blockContainer">
 <div id="blockA">Block A</div>
 <div id="blockB">Block B</div>
 <div id="blockC">Block C</div>
</div>

http://jsfiddle.net/thirtydot/hLUHL/

7
Dmitriy Yusupov

En supposant que rien ne les suit

Si ces deux éléments div sont essentiellement vos éléments de mise en page principaux et que rien ne les suit dans le code HTML, il existe une solution pure HMTL/CSS qui prend l’ordre normal indiqué dans ce violon et est capable de retournez-le verticalement comme indiqué dans ce violon en utilisant un wrapper supplémentaire div comme ceci:

[~ # ~] html [~ # ~]

<div class="wrapper flipit">
   <div id="first_div">first div</div>
   <div id="second_div">second div</div>
</div>

[~ # ~] css [~ # ~]

.flipit {
    position: relative;
}
.flipit #first_div {
    position: absolute;
    top: 100%;
    width: 100%;
}

Cela ne fonctionnerait pas si les éléments suivaient ces div, comme ce violon illustre le problème si les éléments suivants ne sont pas encapsulés (ils se chevauchent avec #first_div), et ce violon illustre le problème si les éléments suivants sont également encapsulés (le #first_div change de position avec les deux le #second_div et les éléments suivants). C’est pourquoi, selon votre cas d’utilisation, cette méthode peut ne pas fonctionner.

Pour un schéma de présentation global, où tous les autres éléments existent à l'intérieur des deux div, cela peut fonctionner. Pour les autres scénarios, cela ne fonctionnera pas.

5
ScottS

Dans certains cas, vous pouvez simplement utiliser le flex-box propriété order.

Très simple:

.flex-item {
    order: 2;
}

Voir: https://css-tricks.com/almanac/properties/o/order/

4
Boris Yakubchik

Cette solution a fonctionné pour moi:

Utiliser un élément parent comme:

.parent-div {
    display:flex;
    flex-direction: column-reverse;
}

Dans mon cas, je n'ai pas eu à changer le css des éléments que je devais changer.

0
pfmDev