Как изменить порядок элементов css

Given a template where the HTML cannot be modified because of other requirements, how is it possible to display (rearrange) a div above another div when they are not in that order in the HTML? Both...

I have a much better code, made by me, it is so big, just to show both things… create a 4×4 table and vertical align more than just one cell.

It does not use any IE hack, no vertical-align:middle; at all…

It does not use for vertical centering display-table, display:table-rom; display:table-cell;

It uses the trick of a container that has two divs, one hidden (position is not the correct but makes parent have the correct variable size), one visible just after the hidden but with top:-50%; so it is mover to correct position.

See div classes that make the trick:
BloqueTipoContenedor
BloqueTipoContenedor_VerticalmenteCentrado
BloqueTipoContenido_VerticalmenteCentrado_Oculto
BloqueTipoContenido_VerticalmenteCentrado_Visible

Please sorry for using Spanish on classes names (it is because i speak spanish and this is so tricky that if i use English i get lost).

The full code:

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta http-equiv="Content-Language" content="en" />
<meta name="language" content="en" />
<title>Vertical Centering in CSS2 - Example (IE, FF & Chrome tested) - This is so tricky!!!</title>
<style type="text/css">
 html,body{
  margin:0px;
  padding:0px;
  width:100%;
  height:100%;
 }
 div.BloqueTipoTabla{
  display:table;margin:0px;border:0px;padding:0px;width:100%;height:100%;
 }
 div.BloqueTipoFila_AltoAjustadoAlContenido{
  display:table-row;margin:0px;border:0px;padding:0px;width:100%;height:auto;
 }
 div.BloqueTipoFila_AltoRestante{
  display:table-row;margin:0px;border:0px;padding:0px;width:100%;height:100%;
 }
 div.BloqueTipoCelda_AjustadoAlContenido{
  display:table-cell;margin:0px;border:0px;padding:0px;width:auto;height:auto;
 }
 div.BloqueTipoCelda_RestanteAncho{
  display:table-cell;margin:0px;border:0px;padding:0px;width:100%;height:auto;
 }
 div.BloqueTipoCelda_RestanteAlto{
  display:table-cell;margin:0px;border:0px;padding:0px;width:auto;height:100%;
 }
 div.BloqueTipoCelda_RestanteAnchoAlto{
  display:table-cell;margin:0px;border:0px;padding:0px;width:100%;height:100%;
 }
 div.BloqueTipoContenedor{
  display:block;margin:0px;border:0px;padding:0px;width:100%;height:100%;position:relative;
 }
 div.BloqueTipoContenedor_VerticalmenteCentrado{
  display:block;margin:0px;border:0px;padding:0px;width:100%;height:auto;position:relative;top:50%;
 }
 div.BloqueTipoContenido_VerticalmenteCentrado_Oculto{
  display:block;margin:0px;border:0px;padding:0px;width:100%;height:auto;visibility:hidden;position:relative;top:50%;
 }
 div.BloqueTipoContenido_VerticalmenteCentrado_Visible{
  display:block;margin:0px;border:0px;padding:0px;width:100%;height:auto;visibility:visible;position:absolute;top:-50%;
 }
</style>
</head>
<body>
<h1>Vertical Centering in CSS2 - Example<br />(IE, FF & Chrome tested)<br />This is so tricky!!!</h1>
<div class="BloqueTipoTabla" style="margin:0px 0px 0px 25px;width:75%;height:66%;border:1px solid blue;">
 <div class="BloqueTipoFila_AltoAjustadoAlContenido">
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [1,1]
  </div>
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [1,2]
  </div>
  <div class="BloqueTipoCelda_RestanteAncho">
   [1,3]
  </div>
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [1,4]
  </div>
 </div>
 <div class="BloqueTipoFila_AltoAjustadoAlContenido">
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [2,1]
  </div>
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [2,2]
  </div>
  <div class="BloqueTipoCelda_RestanteAncho">
   [2,3]
  </div>
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [2,4]
  </div>
</div>
 <div class="BloqueTipoFila_AltoRestante">
  <div class="BloqueTipoCelda_RestanteAlto">
   <div class="BloqueTipoContenedor" style="border:1px solid lime;">
    <div class="BloqueTipoContenedor_VerticalmenteCentrado" style="border:1px dotted red;">
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Oculto">
     The cell [3,1]
     <br />
     *&nbsp;*&nbsp;*&nbsp;*
     <br />
     *&nbsp;*&nbsp;*&nbsp;*
     <br />
     *&nbsp;*&nbsp;*&nbsp;*
     <br />
     Now&nbsp;is&nbsp;the&nbsp;highest&nbsp;one
     </div>
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Visible" style="border:1px dotted blue;">
     The cell [3,1]
     <br />
     *&nbsp;*&nbsp;*&nbsp;*
     <br />
     *&nbsp;*&nbsp;*&nbsp;*
     <br />
     *&nbsp;*&nbsp;*&nbsp;*
     <br />
     Now&nbsp;is&nbsp;the&nbsp;highest&nbsp;one
     </div>
    </div>
   </div>
  </div>
  <div class="BloqueTipoCelda_RestanteAlto">
   <div class="BloqueTipoContenedor" style="border:1px solid lime;">
    <div class="BloqueTipoContenedor_VerticalmenteCentrado" style="border:1px dotted red;">
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Oculto">
      This&nbsp;is<br />cell&nbsp;[3,2]
     </div>
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Visible" style="border:1px dotted blue;">
      This&nbsp;is<br />cell&nbsp;[3,2]
     </div>
    </div>
   </div>
  </div>
  <div class="BloqueTipoCelda_RestanteAnchoAlto">
   <div class="BloqueTipoContenedor" style="border:1px solid lime;">
    <div class="BloqueTipoContenedor_VerticalmenteCentrado" style="border:1px dotted red;">
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Oculto">
      This is cell [3,3]
      <br/>
      It is duplicated on source to make the trick to know its variable height
      <br />
      First copy is hidden and second copy is visible
      <br/>
      Other cells of this row are not correctly aligned only on IE!!!
     </div>
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Visible" style="border:1px dotted blue;">
      This is cell [3,3]
      <br/>
      It is duplicated on source to make the trick to know its variable height
      <br />
      First copy is hidden and second copy is visible
      <br/>
      Other cells of this row are not correctly aligned only on IE!!!
     </div>
    </div>
   </div>
  </div>
  <div class="BloqueTipoCelda_RestanteAlto">
   <div class="BloqueTipoContenedor" style="border:1px solid lime;">
    <div class="BloqueTipoContenedor_VerticalmenteCentrado" style="border:1px dotted red;">
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Oculto">
      This&nbsp;other is<br />the cell&nbsp;[3,4]
     </div>
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Visible" style="border:1px dotted blue;">
      This&nbsp;other is<br />the cell&nbsp;[3,4]
     </div>
    </div>
   </div>
  </div>
 </div>
 <div class="BloqueTipoFila_AltoAjustadoAlContenido">
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [4,1]
  </div>
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [4,2]
  </div>
  <div class="BloqueTipoCelda_RestanteAncho">
   [4,3]
  </div>
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [4,4]
  </div>
 </div>
</div>
</body>
</html>

I have a much better code, made by me, it is so big, just to show both things… create a 4×4 table and vertical align more than just one cell.

It does not use any IE hack, no vertical-align:middle; at all…

It does not use for vertical centering display-table, display:table-rom; display:table-cell;

It uses the trick of a container that has two divs, one hidden (position is not the correct but makes parent have the correct variable size), one visible just after the hidden but with top:-50%; so it is mover to correct position.

See div classes that make the trick:
BloqueTipoContenedor
BloqueTipoContenedor_VerticalmenteCentrado
BloqueTipoContenido_VerticalmenteCentrado_Oculto
BloqueTipoContenido_VerticalmenteCentrado_Visible

Please sorry for using Spanish on classes names (it is because i speak spanish and this is so tricky that if i use English i get lost).

The full code:

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta http-equiv="Content-Language" content="en" />
<meta name="language" content="en" />
<title>Vertical Centering in CSS2 - Example (IE, FF & Chrome tested) - This is so tricky!!!</title>
<style type="text/css">
 html,body{
  margin:0px;
  padding:0px;
  width:100%;
  height:100%;
 }
 div.BloqueTipoTabla{
  display:table;margin:0px;border:0px;padding:0px;width:100%;height:100%;
 }
 div.BloqueTipoFila_AltoAjustadoAlContenido{
  display:table-row;margin:0px;border:0px;padding:0px;width:100%;height:auto;
 }
 div.BloqueTipoFila_AltoRestante{
  display:table-row;margin:0px;border:0px;padding:0px;width:100%;height:100%;
 }
 div.BloqueTipoCelda_AjustadoAlContenido{
  display:table-cell;margin:0px;border:0px;padding:0px;width:auto;height:auto;
 }
 div.BloqueTipoCelda_RestanteAncho{
  display:table-cell;margin:0px;border:0px;padding:0px;width:100%;height:auto;
 }
 div.BloqueTipoCelda_RestanteAlto{
  display:table-cell;margin:0px;border:0px;padding:0px;width:auto;height:100%;
 }
 div.BloqueTipoCelda_RestanteAnchoAlto{
  display:table-cell;margin:0px;border:0px;padding:0px;width:100%;height:100%;
 }
 div.BloqueTipoContenedor{
  display:block;margin:0px;border:0px;padding:0px;width:100%;height:100%;position:relative;
 }
 div.BloqueTipoContenedor_VerticalmenteCentrado{
  display:block;margin:0px;border:0px;padding:0px;width:100%;height:auto;position:relative;top:50%;
 }
 div.BloqueTipoContenido_VerticalmenteCentrado_Oculto{
  display:block;margin:0px;border:0px;padding:0px;width:100%;height:auto;visibility:hidden;position:relative;top:50%;
 }
 div.BloqueTipoContenido_VerticalmenteCentrado_Visible{
  display:block;margin:0px;border:0px;padding:0px;width:100%;height:auto;visibility:visible;position:absolute;top:-50%;
 }
</style>
</head>
<body>
<h1>Vertical Centering in CSS2 - Example<br />(IE, FF & Chrome tested)<br />This is so tricky!!!</h1>
<div class="BloqueTipoTabla" style="margin:0px 0px 0px 25px;width:75%;height:66%;border:1px solid blue;">
 <div class="BloqueTipoFila_AltoAjustadoAlContenido">
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [1,1]
  </div>
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [1,2]
  </div>
  <div class="BloqueTipoCelda_RestanteAncho">
   [1,3]
  </div>
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [1,4]
  </div>
 </div>
 <div class="BloqueTipoFila_AltoAjustadoAlContenido">
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [2,1]
  </div>
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [2,2]
  </div>
  <div class="BloqueTipoCelda_RestanteAncho">
   [2,3]
  </div>
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [2,4]
  </div>
</div>
 <div class="BloqueTipoFila_AltoRestante">
  <div class="BloqueTipoCelda_RestanteAlto">
   <div class="BloqueTipoContenedor" style="border:1px solid lime;">
    <div class="BloqueTipoContenedor_VerticalmenteCentrado" style="border:1px dotted red;">
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Oculto">
     The cell [3,1]
     <br />
     *&nbsp;*&nbsp;*&nbsp;*
     <br />
     *&nbsp;*&nbsp;*&nbsp;*
     <br />
     *&nbsp;*&nbsp;*&nbsp;*
     <br />
     Now&nbsp;is&nbsp;the&nbsp;highest&nbsp;one
     </div>
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Visible" style="border:1px dotted blue;">
     The cell [3,1]
     <br />
     *&nbsp;*&nbsp;*&nbsp;*
     <br />
     *&nbsp;*&nbsp;*&nbsp;*
     <br />
     *&nbsp;*&nbsp;*&nbsp;*
     <br />
     Now&nbsp;is&nbsp;the&nbsp;highest&nbsp;one
     </div>
    </div>
   </div>
  </div>
  <div class="BloqueTipoCelda_RestanteAlto">
   <div class="BloqueTipoContenedor" style="border:1px solid lime;">
    <div class="BloqueTipoContenedor_VerticalmenteCentrado" style="border:1px dotted red;">
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Oculto">
      This&nbsp;is<br />cell&nbsp;[3,2]
     </div>
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Visible" style="border:1px dotted blue;">
      This&nbsp;is<br />cell&nbsp;[3,2]
     </div>
    </div>
   </div>
  </div>
  <div class="BloqueTipoCelda_RestanteAnchoAlto">
   <div class="BloqueTipoContenedor" style="border:1px solid lime;">
    <div class="BloqueTipoContenedor_VerticalmenteCentrado" style="border:1px dotted red;">
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Oculto">
      This is cell [3,3]
      <br/>
      It is duplicated on source to make the trick to know its variable height
      <br />
      First copy is hidden and second copy is visible
      <br/>
      Other cells of this row are not correctly aligned only on IE!!!
     </div>
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Visible" style="border:1px dotted blue;">
      This is cell [3,3]
      <br/>
      It is duplicated on source to make the trick to know its variable height
      <br />
      First copy is hidden and second copy is visible
      <br/>
      Other cells of this row are not correctly aligned only on IE!!!
     </div>
    </div>
   </div>
  </div>
  <div class="BloqueTipoCelda_RestanteAlto">
   <div class="BloqueTipoContenedor" style="border:1px solid lime;">
    <div class="BloqueTipoContenedor_VerticalmenteCentrado" style="border:1px dotted red;">
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Oculto">
      This&nbsp;other is<br />the cell&nbsp;[3,4]
     </div>
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Visible" style="border:1px dotted blue;">
      This&nbsp;other is<br />the cell&nbsp;[3,4]
     </div>
    </div>
   </div>
  </div>
 </div>
 <div class="BloqueTipoFila_AltoAjustadoAlContenido">
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [4,1]
  </div>
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [4,2]
  </div>
  <div class="BloqueTipoCelda_RestanteAncho">
   [4,3]
  </div>
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [4,4]
  </div>
 </div>
</div>
</body>
</html>

В этой статье мы рассмотрим несколько различных методов CSS для переупорядочения вывода элементов HTML.

Цель

Наша раскладка очень простая. В частности, на маленьких экранах (меньше 600px) она будет выглядеть так:

Раскладка на маленьких экранах - 4 кнопки выведены в один столбик

На средних экранах и больше (от 600px) кнопки будут выстраиваться в ряд:

Раскладка на больших экранах - 4 кнопки выведены в ряд

Наша главная задача — поменять порядок кнопок на обратный.

Разметка

Разметка будет самая простая: просто элемент div, содержащий четыре кнопки:

<div class="boxes">
  <button>Button 1</button>
  <button>Button 2</button>
  <button>Button 3</button>
  <button>Button 4</button>
</div>

Стили

На маленьком экране у всех кнопок будут одинаковые стили:

.boxes button {
  display: block;
  width: 100%;
  padding: 15px;
  border: none;
  margin-bottom: 5px;
  box-sizing: border-box;
  font-size: 1rem;
  text-align: center;
  text-decoration: none;
  background: gold;
  color: #000;
}
 
.boxes button:nth-of-type(even) {
  background: #e6c200;
}

На больших экранах мы зададим width: 25%, остальные стили будут определяться методом CSS, который мы будем применять для задания обратного порядка кнопок.

@media screen and (min-width: 600px) {
  /* we skip this property in flexbox and grid methods */
  width: 25%;
   
 /* more stuff here */
}

Наконец, у нас будут стили для состояния focus наших кнопок:

.boxes button:focus {
  outline: none;
  color: #fff;
  background: firebrick;
}

Таким образом, если мы будем использовать для навигации клавишу Tab, наши кнопки при фокусировке станут темно-красными.

Стили для фокусировки

Методы упорядочивания колонок

Теперь мы готовы проверить различные подходы CSS для вывода кнопок в реверсивном порядке при превышении областью видимости ширины в 599px.

Метод №1: плавающие блоки

Можно просто добавить блокам float: right, вот полные стили:

@media screen and (min-width: 600px) {
  .boxes button {
    float: right;
    width: 25%;
  }
}

И демо с Codepen:

See the Pen Using Floats for Reverse Column Ordering by Envato Tuts+ (@tutsplus) on CodePen.

Метод №2: позиционирование

Альтернативным вариантом будет задание позиции элементам, относительной или абсолютной.

По первому варианту (с относительным позиционированием) мы зададим кнопкам, плывущим влево свойство position: relative и затем расставим их с помощью свойство left.

Вот CSS:

@media screen and (min-width: 600px) {
  .boxes button {
    position: relative;
    float: left;
    width: 25%;
   }
  
  .boxes button:nth-of-type(1) {
    left: 75%;
  }
 
  .boxes button:nth-of-type(2) {
    left: 25%;
  }
 
  .boxes button:nth-of-type(3) {
    left: -25%;
  }
 
  .boxes button:nth-of-type(4) {
    left: -75%;
  }
}

Демо с Codepen:

See the Pen Using Positioning (relative) for Reverse Column Ordering by Envato Tuts+ (@tutsplus) on CodePen.

Вторым вариантом (с использованием абсолютного позиционирования) мы зададим нашим кнопкам position: absolute, а с помощью свойства left разместим их более точно.

Соответствующий CSS:

@media screen and (min-width: 600px) {
  .boxes {
    position: relative;
  }
   
  .boxes button {
    position: absolute;
    width: 25%;
  }
   
  .boxes button:nth-of-type(1) {
    left: 75%;
  }
   
  .boxes button:nth-of-type(2) {
    left: 50%;
  }
   
  .boxes button:nth-of-type(3) {
    left: 25%;
  }
   
  .boxes button:nth-of-type(4) {
    left: 0;
  }
}

Демо на Codepen:

See the Pen Using Positioning (absolute) for Reverse Column Ordering by Envato Tuts+ (@tutsplus) on CodePen.

Метод №3: свойство direction

Менее очевиден подход на основе свойства direction — оно предназначено для смены направления чтения текста. В нашем случае мы задаем direction: rtl (справа налево) для элемента-обертки, что позволит сменить направление раскладки.

Примечание: для этого примера мы дадим нашим кнопкам поведение элементов таблицы, чтобы создать горизонтальную раскладку.

Вы можете видеть необходимые стили CSS ниже:

@media screen and (min-width: 600px) {
  .boxes {
    display: table;
    width: 100%;
    direction: rtl;
  }
 
  .boxes button {
    display: table-cell;
    width: 25%;
  }
}

Стоит упомянуть, что если по каким-то причинам мы хотим также изменить направление текста в кнопках, мы можем включить специальное правило для того, чтобы направление символов юникода определялось свойством direction.

.boxes button {
  unicode-bidi: bidi-override;
}

Демо на Codepen:

See the Pen Using `direction` for Reverse Column Ordering by Envato Tuts+ (@tutsplus) on CodePen.

Метод №4: трансформация

Изящным решением будет оставить кнопкам float: left; и затем применить transform: scaleX(-1) к ним и их родителю. Задав отрицательные значения мы сделаем так, что трансформируемый элемент не масштабируется, а переворачивается по горизонтальной оси.

Вот CSS:

@media screen and (min-width: 600px) {
  .boxes {
    transform: scaleX(-1);
  }
 
  .boxes button {
    float: left;
    transform: scaleX(-1);
    width: 25%;
  }
}

Демо на Codepen:

See the Pen Using `transform` (scale) for Reverse Column Ordering by Envato Tuts+ (@tutsplus) on CodePen.

Мы также можем использовать для создания нужного порядка функцию трансформации rotate. Все, что нам надо добавить кнопкам и их родителю свойство transform: rotateY(180deg).

CSS для этого решения:

@media screen and (min-width: 600px) {
  .boxes {
    transform: rotateY(180deg);
  }
   
  .boxes button {
    float: left;
    transform: rotateY(180deg);
    width: 25%;
  }
}

Демо на Codepen:

See the Pen Using `transform` (rotate) for Column Ordering by Envato Tuts+ (@tutsplus) on CodePen.

Метод №5: флексбокс

Флексбокс это еще один способ изменения порядка колонок. В нашем примере мы используем два разных свойства флексбокса для создания нашей раскладки.

Первый подход это сделать родительский элемент кнопок флекс-контейнером и затем добавить flex-direction: row-reverse, вот так:

@media screen and (min-width: 600px) {
  .boxes {
    display: flex;
    flex-direction: row-reverse;
  }
}

Демо на Codepen:

See the Pen Using `flexbox` (flex-direction) for Column Ordering by Envato Tuts+ (@tutsplus) on CodePen.

Второй вариант с флексбоксом состоит в использовании свойства order для определения порядка, в котором кнопки должны выводиться.

@media screen and (min-width: 600px) {
  .boxes {
    display: flex;
  }
   
  .boxes button:nth-of-type(1) {
    order: 4;
  }
 
  .boxes button:nth-of-type(2) {
    order: 3;
  }
 
  .boxes button:nth-of-type(3) {
    order: 2;
  }
 
  .boxes button:nth-of-type(4) {
    order: 1;
  }
}

Демо на Codepen:

See the Pen Using `flexbox` (order) for Column Ordering by Envato Tuts+ (@tutsplus) on CodePen.

Метод №6: грид-раскладка

Многообещающим решением для расстановки элементов является раскладка на основе CSS Grid. Несмотря на крайне ограниченную поддержку в браузерах на момент написания статьи ее стоит попробовать. Учитывайте, что наш пример будет работать только в Chrome (по умолчанию эта возможность отключена, но ее легко активировать).

Не погружаясь глубоко в детали я опишу два способа с использованием CSS Grid.

Первый вариант это задание родительскому элементу кнопок свойства display: grid; и использование свойства grid-column для определения порядка вывода кнопок. В дополнение мы обеспечим попадание всех кнопок в один ряд путем прямого указания этого — grid-row: 1.

@media screen and (min-width: 600px) {
  .boxes {
    display: grid;
    grid-template-columns: repeat(4, 1fr); 
  }
   
  .boxes button {
    grid-row: 1;
  }
   
  .boxes button:nth-of-type(1) {
    grid-column: 4;
  }
 
  .boxes button:nth-of-type(2) {
    grid-column: 3;
  }
 
  .boxes button:nth-of-type(3) {
    grid-column: 2;
  }
 
  .boxes button:nth-of-type(4) {
    grid-column: 1;
  }
}

Демо на Codepen:

See the Pen Using CSS `grid` (grid-column) for Column Ordering by Envato Tuts+ (@tutsplus) on CodePen.

Второй вариант использования CSS Grid похож на второй способ использования флексбокса. Мы зададим контейнеру свойство display: grid;, а затем используем свойство order для определения порядка вывода кнопок.

@media screen and (min-width: 600px) {
  .boxes {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
  }
   
  .boxes button:nth-of-type(1) {
    order: 4;
  }
 
  .boxes button:nth-of-type(2) {
    order: 3;
  }
 
  .boxes button:nth-of-type(3) {
    order: 2;
  }
 
  .boxes button:nth-of-type(4) {
    order: 1;
  }
}

Демо на Codepen:

See the Pen Using CSS `grid` (order) for Column Ordering by Envato Tuts+ (@tutsplus) on CodePen.

Напомню, что для тестирования этого метода, вам надо активировать “Experimental Web Platform features” в Chrome.

Порядок исходников и визуальный порядок

Как было показано, мы можем использовать различные подходы CSS для смены порядка наших кнопок. Попробуем пройтись по нашим демо, используя клавиатуру (кликните на пен и нажмите клавишу Tab) для навигации по кнопкам. Вы заметите, что даже, если кнопка с номером 4 выведена первой, фокус сначала появляется на кнопке с номером 1, так как она расположена первой в DOM. То же случится, если мы протестируем наши демо со скринридером (я проводил тесты с NVDA).

Учитывая эту независимость порядка CSS от порядка DOM, нам надо быть крайне осторожными с частями страниц, порядок которых мы изменяем с помощью CSS. Например, свойство флексбокса order это один из наиболее гибких способов для переупорядочения элементов, согласно спецификации:

Авторы должны использовать order только для визуального, а не логического переупорядочивания контента. Попытка использовать order для логического порядка не сработает.

То же самое спецификация говорит о свойстве order CSS Grid.

Также как и с переупорядочиванием флекс-элементов, свойство order может использоваться только, когда визуальный порядок надо рассинхронизировать с порядком зачитывания и навигации — иначе надо менять исходники документа.

Примечание: если вы используете второй способ с флексбоксом в Firefox, то вы заметите, что навигация с клавиатуры работает отлично и фокус на средних экранах появляется сначала на кнопке №4. Такое поведение является багом.

Заключение

В этой статье мы проверили различные методы CSS для переупорядочивания элементов HTML. Конечно, не все из этих методов универсальны и перед тем, как выбрать нужный вам, вы должны учесть несколько вещей:

  • Браузеры, которые вам надо поддерживать. Некоторые из перечисленных подходов не работают в старых версиях Internet Explorer (т.е. < 10).
  • Степень сложности перестановки — это может быть что-то простое, как наш пример или что-то более сложное.
Дополнительные материалы
  • HTML Source Order vs CSS Display Order от Adrian Roselli
  • Flexbox & the keyboard navigation disconnect от Léonie Watson

Приветствую вас на сайте Impuls-Web!

В сегодняшней статье вы узнаете, как можно менять блоки на сайте местами, при этом не внося никаких правок в HTML или PHP код. Для реализации данной задачи мы будем использовать всего несколько CSS-свойств.

Те приемы, которые я вам сегодня покажу, позволяют значительно упростить процесс адаптации вашего сайта под мобильные устройства. Так же эти приемы помогут вам в том случае если вы хотите переставить на вашем сайте какие-то блоки местами, но при этом у вас какая-то сложная тема, и вы понятия не имеете, в каких шаблонах находятся фрагменты кода, отвечающие за вывод того или иного блока.

Меняем блоки местами при помощи float

Итак, давайте рассмотрим конкретный пример. Предположим у нас есть вот такая страница сайта:

Пример страницы

На которой блок с контентом выводится с левой стороны, а сайтбар выводится с правой стороны. Давайте поменяем местами бок сайтбара и блок контента. Сделаем, что бы они у нас располагались наоборот.

Прежде чем приписывать какие-либо CSS-свойства для блоков, нам нужно вычислить класс или идентификатор, который они имеют.

  1. 1.Кликаем правой кнопкой по элементу, выбираем «Исследовать элемент» и далее инспектируем его код, что бы видеть какой класс или идентификатор присваивается этому элементу.

    Инспектируем код

    В данном случае наш элемент имеет два класса, класс content и класс fleft. Скорее всего, класс content имеет не только этот блок, но еще другие блоки на сайте. Поэтому я буду привязываться к классу fleft, потому, как он выглядит более уникалным.

    По инспектированию кода и определению классов и идентификаторов элементов на сайте я делала отдельную статью, с которой вы можете ознакомиться по этой ссылке.

  2. 2.Копируем название этого класса.
  3. 3.Далее, нам нужно будет открыть CSS-файл, в котором прописаны стили для вашего сайта. Сайт на примере, которого я буду показывать эти приемы, работает на CMS WordPress, и здесь этот файл находится в папке с активной темой, и называется он style.css.
  4. 4.Задаём для этого класса обтекание по правому краю.
  5. 5.Теперь мне нужно определить класс или идентификатор блока в котором находится наш сайдбар.

    Определяем класс блока

    Мы видим код этого блока, и видим, что у него есть класс fright. Копируем его, и для него приписываем наоборот, обтекание по левому краю.

  6. 6.Теперь сохраняем изменения в файле, обновляем нашу страницу, и видим, что у нас эти два блока поменялись местами.

    Поменять блоки местами

Вот так мы при помощи буквально нескольких строчек кода, очень быстро поменяли их местами.

Изменяем порядок отображения блоков

Теперь давайте рассмотрим еще один пример. Предположим у нас есть страница с вот такой структурой блоков:

Пример структуры блоков

Если мы захотим поменять местами блок с текстом и блок с изображением, нам достаточно будет использовать свойство float и задать ему значение left или right. Однако если мы будем адаптировать эту страницу под мобильные устройства, то увидим, что на маленьких экранах, после перестроения в одну колонку, у нас эти блоки выглядят не очень красиво.

Перестроение блоков

У нас идет в первом блоке сначала изображение, а потом текст, во втором сначала текст, а потом изображение, в третьем опять наоборот. Было бы на много красивее и аккуратнее, если бы у нас и после перестроения все блоки выглядели одинаково.

Например, чтобы во всех блоках сначала была бы задана картинка, а затем текст.

При помощи CSS-свойства float мы уже ни как не можем повлиять здесь на порядок расположения элементов. Однако у нас есть еще одно CSS-свойство display:flex, которое поможет нам реализовать данную задачу.

CSS cвойство display:flex предназначено для гибкой компоновки дочерних элементов. Оно имеет много интересных возможностей, и очень активно используется в современной верстке. В ближайшее время я сделаю отдельную статью или видео, посвященное интересным возможностям и нюансам использования этого свойства.

Если в предыдущем примере мы задавали или изменяли CSS-свойство float конкретно для тех элементов, которые мы хотим поменять местами. То здесь нам нужно будет еще обращать внимание на родительские блоки этих элементов.

Предположим у нас есть блок, который имеет класс text-row, внутри этого блока находится еще два блока, это блок с изображением, и блок с текстом. Блок с изображением имеет класс image-block, а блок с текстом имеет класс description-block.

Наша задача задать для родительского блока тех элементов, которые мы хотим переставить местами, CSS-свойство display:flex и свойство flex-flow. В нашем случае это будет выглядеть вот таким образом:

.textrow  {

display: flex;

flexflow: wrap;

}

Далее нам нужно для дочерних элементов или для вложенных элементов этого блока задать порядок сортировки. Чтобы блок с изображением располагался на первом месте, а блок с описанием на втором месте.

Зададим для нашего блока с изображением CSS-свойство order, и укажем здесь значение 1. Для блока description-block нам нужно будет задать CSS-свойство order со значением 2.

.imageblock {

order:1;

}

.descriptionblock {

order: 2;

}

После этого наши блоки поменяются местами. Но дело в том, что для конкретного примера нам нужно, чтобы такой порядок расположения блоков у нас был не всегда, а только для маленьких экранов, после перестроения блоков в один столбец.

Для этого нам понадобиться использовать медиазапрос:

@media screen and (maxwidth:780px) {

/**зддесь пишем CSS свойства для перестроения блоков**/

}

В моём примере перестроение происходит на ширине 780 пикселей, у вас это значение может отличаться.

Таким образом, эти CSS-свойства будут срабатывать только для устройств с шириной экрана от 0 до 780 пикселей. На экранах свыше 780 пикселей у нас они работать не будут, и блоки будут отображаться по-прежнему в шахматном порядке.

При помощи CSS-свойств display:flex и order мы можем задавать порядок расположения элементов на сайте причем, как в горизонтальном, так и в вертикальном направлении.

Видеоинструкция

Я надеюсь, что приемы, показанные в этой статье, помогут вам упростить процесс разработки и доработки вашего сайта.

Если эта статья была для вас полезной, оставляйте свои комментарии, подписывайтесь на мою рассылку и делитесь статьей в социальных сетях.

На этом у меня все. До скорых встреч!

С уважением Юлия Гусарь

Марат Таналин
Опубликовано:
2011-06-05
Обновлено:
2017-06-28
Краткое описание
Кросс­браузерный способ полно­ценной вертикальной пере­становки блоков произвольной высоты средствами CSS.

Современные браузеры — Flexbox

Произвольный порядок

В современных браузерах (в том числе Internet Explorer 11 и Edge) управлять визуальным порядком элементов можно с помощью CSS-свойства order, являющегося частью механизма Flexbox. Блоки следуют в порядке возрастания значений свойства order. Значением свойства order должно быть целое число, которое может быть как положительным, так и отрицательным. Значение по умолчанию — 0.

HTML:

<div class="example">
    <div class="a">Первый</div>
    <div class="b">Второй</div>
    <div class="c">Третий</div>
</div>
CSS:

.example {
    display: flex;
    flex-direction: column;
}

.example > .a {order: 3; } /* Отобразится третьим */
.example > .b {order: 2; } /* Отобразится вторым  */
.example > .c {order: 1; } /* Отобразится первым  */

Объявление display: flex включает Flexbox для элемента-контейнера. Объявление flex-direction: column задаёт вывод дочерних элементов контейнера друг под другом вместо горизонтального вывода, используемого во Flexbox по умолчанию.

Вертикальное положение переупорядочиваемых является взаимозависимым: увеличение высоты любого из блоков приводит к автоматическому вертикальному сдвигу визуально следующих за ним блоков, в том числе при динамическом изменении высоты блоков, например, вследствие увеличения размера шрифта средствами браузера.

Обратный порядок

Если требуется просто вывести элементы в обратном порядке, можно использовать объявление flex-direction: column-reverse для содержащего их контейнера без необходимости явно задавать расположение каждого элемента:


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

Устаревшие браузеры — display: table

В браузерах, не поддерживающих Flexbox (IE 10 и ниже), вертикальный порядок следования блоков на HTML-странице можно изменить, придав им табличное представление при помощи CSS-свойств семейства display: table. Вне зависимости от порядка расположения блоков в HTML-коде, «шапка» (display: table-header-group) такой таблицы отображается в её верхней части, «подвал» (table-footer-group) — в нижней, а основная часть таблицы (table-row-group) — между ними.


.example {
    display: table;
    width: 100%;
}

.example > .a {display: table-footer-group; } /* Отобразится внизу псевдотаблицы */
.example > .b {display: table-row-group;    } /* Отобразится посередине */
.example > .c {display: table-header-group; } /* Отобразится вверху */

Описанным образом можно изменять порядок до трёх соседних блоков. Дополнительно можно задействовать display: table-caption (отображение блока в роли подписи к таблице) в сочетании с CSS-свойством caption-side со значением top или bottom.

Метод работает в большинстве распространённых браузеров, в том числе в Internet Explorer начиная с версии 9 (IE8 — с оговорками, см. далее).

Internet Explorer 6, 7 и 8 — DOM

Устаревшие браузеры IE6 и IE7 не поддерживают CSS-свойства семейства display: table*.

Кроме того, в IE8 в некоторых случаях наблюдается динамическая ошибка рендеринга: если перемещаемый блок содержит в себе псевдотабличные элементы (display: table*) (проявление нюанса замечено только в этом случае), возможно спонтанное пропадание некорых ячеек (всегда разных и в разном количестве) псевдотаблицы при первичной отрисовке страницы.

Поэтому для IE8 и ниже можно отменить CSS-правила, придающие блокам табличный вид, и дополнительно переместить блоки в нужные позиции DOM-дерева HTML-документа уже с помощью JavaScript:


/**
 * Перестраивает соседние элементы в DOM-дереве в заданном порядке.
 * @param {Array} elems Соседние элементы в необходимом порядке.
 */
function reorderElements(elems) {
    // http://tanalin.com/articles/css-block-order/
    var count = elems.length;

    if (!count) {
        return;
    }

    var parent = elems[0].parentNode;

    for (var i = count - 1; i >= 0; i--) {
        parent.insertBefore(elems[i], parent.firstChild);
    }
}

Определение возможностей браузера

Использовать разные стили для современных и устаревших браузеров можно путём определения возможностей браузера средствами JavaScript.

Определить, поддерживает ли браузер Flexbox, можно путём проверки существования свойства order объекта, доступного через свойство style корневого элемента документа (<html></html>) — document.documentElement.

Версию Internet Explorer можно определить путём проверки существования нестандартного объекта document.all, доступного только в IE 10 и ниже, в сочетании с существованием или отсутствием одного из стандартных объектов.


if ('order' in document.documentElement.style) {
    // Flexbox-совместимый браузер.
    // Используем `order` или `flex-direction: column-reverse`.
}
else if (document.all && !document.addEventListener) {
    // IE8 или ниже.
    // Изменяем реальный порядок блоков в DOM-дереве средствами JS.
}
else {
    // Браузер без поддержки Flexbox, в том числе IE 9/10.
    // Используем `display: table`.
}

Несколько CSS методов по изменению визуального порядка

От автора: в этом уроке мы разберем несколько CSS методов по изменению порядка HTML элементов.

Наша цель

Мы хотим построить очень простой макет, особенно на маленьких экранах (т.е. <600px). Вот так он будет выглядеть:

На средних и больших экранах (т.е. выше или равно 600px) макет должен быть таким:

Практический курс по верстке адаптивного сайта с нуля!

Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3

Узнать подробнее

Самая сложная задача – найти способ перевернуть порядок кнопок.

Разметка

Разметка будет очень простая, обычный div с четырьмя кнопками внутри:

<div class=«boxes»>

  <button>Button 1</button>

  <button>Button 2</button>

  <button>Button 3</button>

  <button>Button 4</button>

</div>

Базовые стили

На маленьких экранах у всех кнопок общие стили:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

.boxes button {

  display: block;

  width: 100%;

  padding: 15px;

  border: none;

  marginbottom: 5px;

  boxsizing: borderbox;

  fontsize: 1rem;

  textalign: center;

  textdecoration: none;

  background: gold;

  color: #000;

}

.boxes button:nthoftype(even) {

  background: #e6c200;

}

На больших экранах мы лишь добавим к кнопкам свойство width: 25%. Остальные стили будут добавляться в зависимости от CSS метода, который мы используем для инверсии порядка кнопок.

@media screen and (minwidth: 600px) {

  /* в методах с flexbox и сеткой мы пропускаем это свойство */

  width: 25%;

/* тут код */

}

Осталось добавить стили кнопкам в состоянии focus:

.boxes button:focus {

  outline: none;

  color: #fff;

  background: firebrick;

}

Если при помощи клавиши Tab перемещаться по кнопкам, кнопка с фокусом изменит цвет на темно-красный.

Методы с изменением порядка колонок

Теперь мы готовы протестировать несколько способов по изменению порядка кнопок на экранах шириной больше 599px.

Метод №1: обтекания

Один из быстрых способов – добавить кнопкам правое обтекание. Дополнительный CSS код:

@media screen and (minwidth: 600px) {

  .boxes button {

    float: right;

    width: 25%;

  }

}

Метод №2: позиционирование

Можно спозиционировать элементы, относительно или абсолютно. В первом случае мы сдвигаем все кнопки влево при помощи свойства position: relative и при помощи свойства left выстраиваем их в ряд.Для этого нам нужен следующий CSS код:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

@media screen and (minwidth: 600px) {

  .boxes button {

    position: relative;

    float: left;

    width: 25%;

   }

  .boxes button:nthoftype(1) {

    left: 75%;

  }

  .boxes button:nthoftype(2) {

    left: 25%;

  }

  .boxes button:nthoftype(3) {

    left: 25%;

  }

  .boxes button:nthoftype(4) {

    left: 75%;

  }

}

Во втором случае кнопкам можно было бы задать свойство position: absolute и с помощью свойства left более точно настроить их позиционирование.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

@media screen and (minwidth: 600px) {

  .boxes {

    position: relative;

  }

  .boxes button {

    position: absolute;

    width: 25%;

  }

  .boxes button:nthoftype(1) {

    left: 75%;

  }

  .boxes button:nthoftype(2) {

    left: 50%;

  }

  .boxes button:nthoftype(3) {

    left: 25%;

  }

  .boxes button:nthoftype(4) {

    left: 0;

  }

}

Метод №3: свойство direction

Менее очевидный способ – свойство direction. Обычно, в таком случае резервируется некоторое пространство под развернутый текст. В нашем случае мы задаем свойство direction: rtl (справа налево) контейнеру, что мгновенно меняет порядок элементов в макете. Обратите внимание: в этом примере элементам задается поведение ячеек таблицы для того, чтобы выстроить их в один ряд.

@media screen and (minwidth: 600px) {

  .boxes {

    display: table;

    width: 100%;

    direction: rtl;

  }

  .boxes button {

    display: tablecell;

    width: 25%;

  }

}

Также стоит сказать, что если по каким-либо причинам нам захочется сменить направление текста кнопок, можно использовать специальное правило:

Практический курс по верстке адаптивного сайта с нуля!

Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3

Узнать подробнее

.boxes button {

  unicodebidi: bidioverride;

}

Метод №4: трансформации

Изящный метод. Кнопкам необходимо добавить левое обтекание и свойство transform: scaleX(-1). Также данное свойство необходимо прописать для родительского блока. Отрицательное значение не увеличивает элементы. На самом деле, они просто отражаются по горизонтальной оси.

@media screen and (minwidth: 600px) {

  .boxes {

    transform: scaleX(1);

  }

  .boxes button {

    float: left;

    transform: scaleX(1);

    width: 25%;

  }

}

Для достижения нужного эффекта можно даже использовать функцию трансформации rotate. Нужно всего лишь добавить свойство transform: rotateY(180deg) к кнопкам и родительскому блоку.

@media screen and (minwidth: 600px) {

  .boxes {

    transform: rotateY(180deg);

  }

  .boxes button {

    float: left;

    transform: rotateY(180deg);

    width: 25%;

  }

}

Метод №5: flexbox

Изменить порядок колонок можно и с помощью flexbox. В нашем случае мы можем воспользоваться двумя свойствами flexbox для достижения необходимого эффекта. В первом случае родительский блок кнопок необходимо превратить в флекс контейнер и добавить к нему свойство flex-direction: row-reverse.

@media screen and (minwidth: 600px) {

  .boxes {

    display: flex;

    flexdirection: rowreverse;

  }

}

Второй способ – превратить родительский блок в флекс контейнер и с помощью свойство order задавать порядок кнопок.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

@media screen and (minwidth: 600px) {

  .boxes {

    display: flex;

  }

  .boxes button:nthoftype(1) {

    order: 4;

  }

  .boxes button:nthoftype(2) {

    order: 3;

  }

  .boxes button:nthoftype(3) {

    order: 2;

  }

  .boxes button:nthoftype(4) {

    order: 1;

  }

}

Метод №6: CSS сетка

CSS сетка – один из самых лучших способов изменения порядка элементов. Несмотря на скудную поддержку в браузерах на момент написания статьи, давайте попробуем данный способ. Данный пример будет работать только в Chrome, в котором необходимое CSS свойство по умолчанию не поддерживается. Однако при помощи простых шагов мы можем активировать это свойство.

Не вдаваясь в детали, давайте разберем два способа. Первый способ – превратить родительский блок в grid-контейнер и с помощью свойства grid-column задавать порядок расположения кнопок. Также мы добавим свойство grid-row: 1, чтобы все кнопки были на одном ряду.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

@media screen and (minwidth: 600px) {

  .boxes {

    display: grid;

    gridtemplatecolumns: repeat(4, 1fr);

  }

  .boxes button {

    gridrow: 1;

  }

  .boxes button:nthoftype(1) {

    gridcolumn: 4;

  }

  .boxes button:nthoftype(2) {

    gridcolumn: 3;

  }

  .boxes button:nthoftype(3) {

    gridcolumn: 2;

  }

  .boxes button:nthoftype(4) {

    gridcolumn: 1;

  }

}

Второй способ с сетками похож на второй способ с flexbox. Необходимо превратить родительский блок в grid-контейнер и с помощью свойства order задавать порядок отображения кнопок.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

@media screen and (minwidth: 600px) {

  .boxes {

    display: grid;

    gridtemplatecolumns: repeat(4, 1fr);

  }

  .boxes button:nthoftype(1) {

    order: 4;

  }

  .boxes button:nthoftype(2) {

    order: 3;

  }

  .boxes button:nthoftype(3) {

    order: 2;

  }

  .boxes button:nthoftype(4) {

    order: 1;

  }

}

Данное демо работает только с включенным флагом «Experimental Web Platform features» в Chrome.

Исходный порядок или визуальный порядок

Мы показали, что изменить порядок следования кнопок можно разными CSS способами. Давайте еще раз взглянем на все демо и с помощью клавиатуры пройдемся по кнопкам (при помощи клавиши Tab). Вы заметите, что даже если кнопка 4 визуально стоит первой, то первой получит фокус кнопка 1, так как она расположена первой в DOM. То же самое будет, если протестировать демо в скрин ридерах (я тестировал в NVDA).

Учитывая разницу между порядком в DOM и CSS, необходимо крайне осторожно работать с частями сайта, которые были перестроены при помощи CSS. К примеру, flexbox свойство order одно из самых гибких для изменения порядка отображения элементов, однако в спецификации говорится: «Редакторы должны использовать свойство order только для визуального, не логического изменения порядка контента. Стили, в которых свойство order используется для логического изменения порядка, неприемлемы.»

То же самое говорится в спецификации и про свойство order в сетках: «При изменении порядка флекс элементов свойство order должно использоваться только в случаях, когда визуальный порядок не должен совпадать с порядком чтения текста скрин ридерами и порядком меню. В противном случае документ должен быть перестроен.»

Обратите внимание: если вы тестировали второй способ с flexbox в браузере Firefox, вы могли заметить, что навигация с клавиатурой работает, но на средних экранах первый фокус получает кнопка 4. Это баг.

Заключение

В этом уроке мы рассмотрели разные CSS методы по изменению порядка отображения HTML элементов. Не все методы подходят на все случаи. Перед выбором нужно учесть:

Какие браузеры вы будете поддерживать. К примеру, некоторые из вышеупомянутых способов не работают в старых версиях IE (<10).

Сложность перестроения. Перестроение будет простым, как в наших примерах, или что-то посложнее?

Если вы знаете другие методы по изменению порядка кнопок, пишите о них в комментариях.

Редакция: George Martsoukos

Источник: //webdesign.tutsplus.com/

Редакция: Команда webformyself.

Практический курс по верстке адаптивного сайта с нуля!

Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3

Узнать подробнее

PSD to HTML

Практика верстки сайта на CSS Grid с нуля

Смотреть

Russian (Pусский) translation by Anna Goorikova (you can also view the original English article)

В этом руководстве мы рассмотрим несколько различных методов CSS для переупорядочения элементов HTML.

Цель

Макет, который мы хотим сделать, очень прост. В частности, на небольших экранах (то есть <600 пикселей), он должен выглядеть следующим образом:

На средних экранах и больше (то есть больше или равно 600 пикселей), мы хотим, чтобы он выглядел следующим образом:

Наша самая сложная задача — найти способ изменить порядок кнопок.

Разметка

Разметка, которую мы будем использовать, проста; только элемент div, содержащий четыре кнопки:

1
<div class="boxes">
2
  <button>Button 1</button>
3
  <button>Button 2</button>
4
  <button>Button 3</button>
5
  <button>Button 4</button>
6
</div>

Основные стили

На маленьких экранах все кнопки имеют одинаковые стили:

1
.boxes button {
2
  display: block;
3
  width: 100%;
4
  padding: 15px;
5
  border: none;
6
  margin-bottom: 5px;
7
  box-sizing: border-box;
8
  font-size: 1rem;
9
  text-align: center;
10
  text-decoration: none;
11
  background: gold;
12
  color: #000;
13
}
14

15
.boxes button:nth-of-type(even) {
16
  background: #e6c200;
17
}

На больших экранах мы задаем только width: 25% для кнопок. Остальные стили будут заданы в соответствии с тем методом CSS, который мы используем, чтобы изменить порядок кнопок.

1
@media screen and (min-width: 600px) {
2
  /* we skip this property in flexbox and grid methods */
3
  width: 25%;
4
  
5
 /* more stuff here */
6
}

Наконец, мы добавим несколько стилей для focus состояния наших кнопок:

1
.boxes button:focus {
2
  outline: none;
3
  color: #fff;
4
  background: firebrick;
5
}

Итак, если мы используем клавиатуру (клавиша «Tab»), чтобы перемещаться по кнопкам, то каждая кнопка, получающая фокус, будет иметь темно-красный цвет фона.

Методы упорядочения столбцов

На этом этапе мы рассмотрим различные подходы CSS для изменения порядка кнопок, когда область просмотра превышает 599 пикселей.

Метод #1: Floats

Первое постое решение это задать кнопкам свойство float:right. Вот дополнительный CSS:

1
@media screen and (min-width: 600px) {
2
  .boxes button {
3
    float: right;
4
    width: 25%;
5
  }
6
}

Вот демонстрация в Codepen:

Метод #2: Позиционирование

Альтернативным решением является расположение элементов, как относительно, так и абсолютно.

В первом варианте, мы задаем кнопкам float:left, даем им position: relative, а затем используем свойство left, чтобы определить их положение.

Необходимый CSS выглядит следующим образом:

1
@media screen and (min-width: 600px) {
2
  .boxes button {
3
    position: relative;
4
    float: left;
5
    width: 25%;
6
   }
7
 
8
  .boxes button:nth-of-type(1) {
9
    left: 75%;
10
  }
11

12
  .boxes button:nth-of-type(2) {
13
    left: 25%;
14
  }
15

16
  .boxes button:nth-of-type(3) {
17
    left: -25%;
18
  }
19

20
  .boxes button:nth-of-type(4) {
21
    left: -75%;
22
  }
23
}

Вот демонстрация в Codepen:

Во втором варианте мы могли бы также задать нашим кнопкам position: absolute, а затем использовать свойство left для более точного позиционирования.

Соответствующие правила CSS:

1
@media screen and (min-width: 600px) {
2
  .boxes {
3
    position: relative;
4
  }
5
  
6
  .boxes button {
7
    position: absolute;
8
    width: 25%;
9
  }
10
  
11
  .boxes button:nth-of-type(1) {
12
    left: 75%;
13
  }
14
  
15
  .boxes button:nth-of-type(2) {
16
    left: 50%;
17
  }
18
  
19
  .boxes button:nth-of-type(3) {
20
    left: 25%;
21
  }
22
  
23
  .boxes button:nth-of-type(4) {
24
    left: 0;
25
  }
26
}

Демонстрация Codepen:

Метод #3: Свойство direction

Менее очевидным подходом является использование свойства direction, что обычно используется для изменения направления чтения текста. В нашем случае мы задаем direction: rtl (справа налево) элементу обертки, что мгновенно меняет макет.

Примечание: в этом примере мы заставляем наши элементы вести себя как элементы таблицы, для достижения горизонтальной компоновки.

Ниже вы можете увидеть необходимые стили CSS:

1
@media screen and (min-width: 600px) {
2
  .boxes {
3
    display: table;
4
    width: 100%;
5
    direction: rtl;
6
  }
7

8
  .boxes button {
9
    display: table-cell;
10
    width: 25%;
11
  }
12
}

Cтоит отметить, что если (по какой-то причине) мы хотим изменить текстовое направление кнопок, мы можем включить правило двунаправленного переопределения в нашей таблице стилей:

1
.boxes button {
2
  unicode-bidi: bidi-override;
3
}

Codepen демо:

Метод #4: Трансформации

Оптимальным решением будет задать кнопкам float:left, а затем применить transform: scaleX (-1) к ним и их родителям. Из-за установки отрицательного значения преобразованные элементы не масштабируются. На самом деле они перевернуты вдоль горизонтальной оси.

Ниже приведен необходимый CSS:

1
@media screen and (min-width: 600px) {
2
  .boxes {
3
    transform: scaleX(-1);
4
  }
5

6
  .boxes button {
7
    float: left;
8
    transform: scaleX(-1);
9
    width: 25%;
10
  }
11
}

Демо Codepen:

Мы даже можем использовать функцию трансформации rotate для достижения желаемого результата. Все что мы должны сделать, это добавить свойство transform: rotateY(180deg) кнопкам и их родителям.

Вот необходимые CSS для этого способа:

1
@media screen and (min-width: 600px) {
2
  .boxes {
3
    transform: rotateY(180deg);
4
  }
5
  
6
  .boxes button {
7
    float: left;
8
    transform: rotateY(180deg);
9
    width: 25%;
10
  }
11
}

И Codepen демо:

Метод #5: Flexbox

Flexbox является еще одним способом для изменения порядка отображения столбцов. В нашем примере мы можем использовать два разных свойства flexbox для создания желаемого макета.

Первый подход заключается в том, чтобы установить родительскому контейнеру кнопок свойство flex, а затем добавить ему свойство flex-direction: row-reverse.

Ниже приведены соответствующие стили:

1
@media screen and (min-width: 600px) {
2
  .boxes {
3
    display: flex;
4
    flex-direction: row-reverse;
5
  }
6
}

Демонстрация Codepen показана ниже:

Второй вариант с использованием flexbox — установить родительский элемент кнопок в качестве контейнера flex, а затем использовать свойство order, чтобы определить, в каком порядке должны появляться кнопки.

Соответствующий CSS:

1
@media screen and (min-width: 600px) {
2
  .boxes {
3
    display: flex;
4
  }
5
  
6
  .boxes button:nth-of-type(1) {
7
    order: 4;
8
  }
9

10
  .boxes button:nth-of-type(2) {
11
    order: 3;
12
  }
13

14
  .boxes button:nth-of-type(3) {
15
    order: 2;
16
  }
17

18
  .boxes button:nth-of-type(4) {
19
    order: 1;
20
  }
21
}

Codepen демо:

Метод #6: CSS Grid

Многообещающим решением для переупорядочения элементов является использование CSS Grid. Даже если к моменту написания этой статьи у него очень ограниченная поддержка браузерами, давайте все же его попробуем. Имейте в виду, что наш пример будет работать только в Chrome, который по умолчанию не поддерживает эту функцию CSS, но мы можем выполнить несколько простых шагов, чтобы ее включить.

Не вдаваясь в подробности, давайте опишем два способа достижения желаемого результата.

Первый вариант — установить родительскому элементу кнопок свойство контейнера grid, а затем использовать свойство grid-column, чтобы определить, в каком порядке должны отображаться кнопки. Кроме того, мы делаем так, что все кнопки принадлежат одной и той же (первой) строке, добавляя к ней grid-row: 1.

Смотрите нужные стили ниже:

1
@media screen and (min-width: 600px) {
2
  .boxes {
3
    display: grid;
4
    grid-template-columns: repeat(4, 1fr); 
5
  }
6
  
7
  .boxes button {
8
    grid-row: 1;
9
  }
10
  
11
  .boxes button:nth-of-type(1) {
12
    grid-column: 4;
13
  }
14

15
  .boxes button:nth-of-type(2) {
16
    grid-column: 3;
17
  }
18

19
  .boxes button:nth-of-type(3) {
20
    grid-column: 2;
21
  }
22

23
  .boxes button:nth-of-type(4) {
24
    grid-column: 1;
25
  }
26
}

Демонстрация в Codepen:

Второй вариант с grid похож на второе решение с flexbox. Мы устанавливаем родительскому контейнеру кнопок свойство grid, а затем используем свойство order чтобы определить, в каком порядке должны отображаться кнопки.

Вот требуемый CSS:

1
@media screen and (min-width: 600px) {
2
  .boxes {
3
    display: grid;
4
    grid-template-columns: repeat(4, 1fr);
5
  }
6
  
7
  .boxes button:nth-of-type(1) {
8
    order: 4;
9
  }
10

11
  .boxes button:nth-of-type(2) {
12
    order: 3;
13
  }
14

15
  .boxes button:nth-of-type(3) {
16
    order: 2;
17
  }
18

19
  .boxes button:nth-of-type(4) {
20
    order: 1;
21
  }
22
}

Демонстрация в Codepen:

Опять же вам нужно включить “Experimental Web Platform features” в Chrome, чтобы увидеть результат.

Source Order vs. Visual Order

Как мы показали, мы можем использовать разные приемы CSS, чтобы изменить порядок наших кнопок. Итак, теперь мы перейдем к каждому демонстрационному варианту и с помощью клавиатуры (нажимая кнопку Tab) будем перемещаться по кнопкам. Вы заметите, что даже если «Button 4» визуально отображается первой, первая кнопка, которая будет с фокусом это «Button 1», потому что она первой отображается в DOM. То же самое произойдет, если мы протестируем демонстрационные версии с помощью программы чтения с экрана (я сделал свои тесты в NVDA).

Учитывая это различие между порядком DOM и порядком CSS, мы должны быть очень осторожны с частями наших страниц, которые мы перестраиваем с помощью CSS. Например, в то время как свойство flexbox order является одним из самых гибких способов переупорядочения элементов, спецификация говорит:

«Авторы должны использовать order только для визуального, а не логического, переупорядочения контента. Таблицы стилей, которые используют order для выполнения логического переупорядочения, являются несоответствующими.»

Таким же образом, grid спецификация по свойству order говорит:

«Как и при переупорядочивании элементов flex, свойство order должно использоваться только тогда, когда визуальный порядок не должен быть синхронизирован с речевым и навигационным порядком; в противном случае исходный документ должен быть переупорядочен».

Примечание: Если вы проверите второе решение на flexbox (со свойством order) в Firefox, вы заметите, что навигация на клавиатуре работает нормально, а первая кнопка, которая фокусируется на средних экранах и выше это «Button 4». Такое поведение было заявлено как ошибка.

Заключение

В этом руководстве, мы рассмотрели разные CSS методы для переопределения порядка HTML элементов. Конечно, не все эти методы подходят во всех случаях. Прежде чем решить, какой метод использовать, вы должны учесть несколько вещей:

  • Браузеры, которые вы хотите поддерживать. Например, некоторые из вышеупомянутых примеров не работают в более ранних версиях Internet Explorer (например, <10).
  • Сложность вашей перегруппировки. Это будет что-то простое, как то, что мы видели в нашем примере, или что-то более сложное?

Если вы можете придумать какие-либо другие методы для изменения порядка кнопок, обязательно поделитесь ими с нами в комментариях ниже.

Для дальнейшего изучения

  • Исходный порядок в HTML против отображаемого порядка в CSS от Adrian Roselli
  • Flexbox & the keyboard navigation disconnect by Léonie Watson

Like this post? Please share to your friends:
  • Как изменить порядок экранов на андроид
  • Как изменить порядок флекс элементов
  • Как изменить порядок файлов на шкале времени
  • Как изменить порядок файлов на флешке
  • Как изменить порядок уплаты алиментов на твердую денежную сумму