Как достучаться до элемента CSS

Есть вот такая разметка:

<Grid item xs={5}>
    {ourTeam.map(item => (
      <div className={styles.Crewman} key={item.id}>
        <div className={styles.Person}>
          <div className={styles.PersonPhoto}>
            <img src={item.img} alt="#" />
          </div>
          <div>
            <Typography variant="subtitle1">{item.name}</Typography>
            <Typography variant="subtitle2">{item.post}</Typography>
          </div>
        </div>
        <Box p={2}>
          <Typography>{item.desc}</Typography>
        </Box>
      </div>
    ))}
  </Grid>

Нужно каждый второй элемент <div className={styles.Person}> сделать float: right.

С помощью nth-child(even)

Что то 30 мин уже сижу и не могу достучаться до него.

SCSS:

.Crewman {
  margin: 5px 0;
  margin: 16px 0px;

  background: $colorWhite;
  box-shadow: 0 1px 4px rgba($colorBlack, 0.3),
    0 0 40px rgba($colorBlack, 0.1) inset;
  box-shadow: 0 15px 10px -10px rgba($colorBlack, 0.5),
    0 1px 4px rgba($colorBlack, 0.3), 0 0 40px rgba($colorBlack, 0.1) inset;

  h6 {
    color: $mainBlue;
  }

  h6 + h6 {
    color: $colorOrange;
  }

  .Person {
    display: flex;
    float: left;

    padding: 16px 16px 0px 16px;

    .PersonPhoto {
      overflow: hidden;

      max-width: 60px;
      max-height: 60px;
      margin-right: 16px;

      border-radius: 50%;

      img {
        width: 100%;
        height: 100%;

        object-fit: cover;
      }
    }
  }
}

Ответы (3 шт):

Автор решения: Евгений Иванов

.el:nth-childe(2n+2) или .el:nth-childe(even)

Подробнее вот тут http://htmlbook.ru/css/nth-child

Не забывайте что есть еще :nth-of-type

→ Ссылка
Автор решения: Denis Bubnov

Предлагаю вариант без nth-child, который пригодится в будущем. Все достаточно просто. Колбэк функция метода map, создающая элемент в новом массиве, принимает три аргумента:

  1. currentValue - текущий обрабатываемый элемент массива
  2. index - индекс текущего обрабатываемого элемента в массиве
  3. array - массив, по которому осуществляется проход.

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

В качестве бонуса, точнее полезной плюшки, я рекомендую установить пакет classNames - это простая утилита JavaScript для условного объединения нескольких className воедино. Если у тэга может быть несколько стилей, да еще и некоторые из них условны - то она будет незаменима.

Добавим CSS класс для нашего кейса (грубый пример):

.PersonRight {
  float: right !important;
}

Перейдем к вашему коду, добавим несколько условий:

<Grid item xs={5}>
  {ourTeam.map((item, index) => {
      const isSecond = ((index + 1) % 2) === 0; 
      return (
        <div className={styles.Crewman} key={item.id}>
          <div className={classNames(styles.Person, { [styles.PersonRight]: isSecond })}>
            <div className={styles.PersonPhoto}>
              <img src={item.img} alt="#" />
            </div>
            <div>
              <Typography variant="subtitle1">{item.name}</Typography>
              <Typography variant="subtitle2">{item.post}</Typography>
            </div>
          </div>
          <Box p={2}>
            <Typography>{item.desc}</Typography>
          </Box>
        </div>
      );
    }
  )}
</Grid>

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

const isSecond = ((index + 1) % 2) === 0;

Здесь мы прибавляем к индесу единицу, так как нумерация идет с нуля, и смотрим остаток от деления на цифру два. Все четные цифры вернут в этом случае ноль. Такой просто способ определения каждого второго элемента. Далее условное объединения через classNames:

classNames(styles.Person, { [styles.PersonRight]: isSecond })

В этой строке кода всегда будет стиль styles.Person, а вот стиль styles.PersonRight будет только в случае истиного значения true в переменной isSecond. Выше по тексту я прикрепил ссылку на утилиту classNames - и там есть несколько примеров того, как это работает.

Также, рекомендую ознакомиться с условным рендерингом (conditional rendering) - это похожая тема, которая будет полезной.


И наглядный пример (без использования classNames):

const names = ['Denis', 'John', 'Tony', 'Mike', 'Sergey', 'Nik', 'Anton'];

class App extends React.Component {

  render() {
    return (
      <ul>
        {
          names.map((item, index) => {
            const isSecond = ((index + 1) % 2) === 0; 
            return !isSecond
              ? (<li className="person">{item}</li>)
              : (<li className="person person-even">{item}</li>)
          }
        )}
      </ul>
    );
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('container')
);
.person {
  background: red;
}
  
.person-even {
  background: green !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="container">
  <!-- This element's contents will be replaced with your component. -->
</div>

→ Ссылка
Автор решения: Denis Bubnov

Псевдокласс :nth-child используется для добавления стиля к элементам на основе нумерации в дереве элементов. Синтаксис:

элемент:nth-child(odd | even | <число> | <выражение>) {...}

Значения:

  • odd - все нечетные номера элементов
  • even - все четные номера элементов
  • число - порядковый номер дочернего элемента относительно своего родителя. Нумерация начинается с 1, это будет первый элемент в списке
  • выражение - задается в виде an+b, где a и b целые числа, а n — счетчик, который автоматически принимает значение 0, 1, 2...

Пример смены фона у каждого второго элемента с классом person в списке:

const names = ['Denis', 'John', 'Tony', 'Mike', 'Sergey', 'Nik', 'Anton'];

class App extends React.Component {

  render() {
    return (
      <ul>
        {names.map(item => (
          <li className="person">{item}</li>
        ))}
      </ul>
    );
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('container')
);
.person {
  background: red;
}
  
.person:nth-child(even) {
  background: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="container">
  <!-- This element's contents will be replaced with your component. -->
</div>

По сути получается два класса (точнее один, просто у него есть описание с псевдоклассом):

.person {
  background: red;
}

.person:nth-child(even) {
  background: green;
}

Где .person - это общий класс для всех элементов, а .person:nth-child(even) - это класс для каждого четного элемента. Псевдокласс :nth-child добавит стиль, если его нет, либо перезапишет, если он есть. Для наглядности:

перезапись

Ссылка для ознакомления: CSS псевдокласс :nth-child

→ Ссылка