Как сделать так, чтобы все flex-элементы имели одинаковую длину с элементом с самым длинным текстом без переноса текста

Вопрос или проблема

Я пытаюсь сделать все соседние элементы flex одинаковой ширины с тем, у которого самый длинный текст, не позволяя тексту обернуться. То есть, если один элемент имеет текст “Первый”, а другой – гораздо более длинный текст, оба элемента должны иметь одинаковую ширину, не заставляя более длинный текст оборачиваться. Если это невозможно сделать только с помощью CSS и у вас есть решение на React, я готов выслушать. Спасибо!

<div class="container">
  <div class="item">Первый </div>
  <div class="item">Вторая вещь длинная </div>
  <div class="item">Третий </div>
  <div class="item">Четвертый еще длиннее </div>
  <div class="item">Пятый </div>
  <div class="item">Шестой </div>
</div>
.container {
  width: 800px;
  display: flex;
  background: blue;
  overflow: auto; // нормально, если элементы превышают размеры и прокручиваются
  flex-wrap: nowrap;
  height: 130px;
}

.item {
  margin: 10px;
  background: red; // цвет здесь для того, чтобы было легче увидеть, что все элементы имеют одинаковую ширину
  flex-shrink: 0;
  display: flex;
  flex-wrap: nowrap;
  flex-basis: calc(100% / 6); // число 6 здесь будет динамическим, но оно всегда будет равным количеству элементов в контейнере
}

На этой картинке показано, как это выглядит сейчас

Пробел не позволяет тексту перемещаться на вторую строку, а переполнение позволит прокрутку, если любой дочерний текст будет длиннее своей ширины
     .container {  
width: 800px;  
display: flex;  
background: blue; 
overflow: auto;   
flex-wrap: nowrap;  
height: 130px;
}
    .item {  
margin: 10px;  
background: red;    
display: flex;  
flex-wrap: nowrap; 
flex-basis: calc(100% / 6); 
// добавьте ниже в CSS и удалите свойство flex-shrink  
white-space:nowrap; 
overflow:auto;
    }

Ответ или решение

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

Шаг 1: Обновление CSS

Вам нужно настроить CSS для элементов и отключить оборачивание текста:

.container {
  width: 800px;
  display: flex;
  background: blue;
  overflow: auto; /* Включаем прокрутку при переполнении */
  flex-wrap: nowrap; /* Запрещаем оборачивать элементы на новую строку */
  height: 130px; /* Фиксированная высота для контейнера */
}

.item {
  margin: 10px; /* Отступы между элементами */
  background: red; /* Цвет для визуализации */
  white-space: nowrap; /* Запрещаем оборачивание текста */
  overflow: auto; /* Включаем прокрутку внутри элемента при переполнении */
  flex-basis: auto; /* Убираем фиксированную ширину и позволяем элементам занимать ширину */
}

Шаг 2: Использование JavaScript (или React)

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

const items = document.querySelectorAll('.item');
let maxWidth = 0;

// Получаем максимальную ширину среди всех элементов
items.forEach(item => {
  const itemWidth = item.scrollWidth; // Получаем фактическую ширину элемента
  if (itemWidth > maxWidth) {
    maxWidth = itemWidth;
  }
});

// Устанавливаем всем элементам одинаковую ширину
items.forEach(item => {
  item.style.width = `${maxWidth}px`; // Устанавливаем ширину
});

Шаг 3: Интеграция в React

Если вы используете React, вы можете встроить этот код в жизненный цикл компонента или в useEffect:

import React, { useEffect, useRef } from 'react';
import './YourStyles.css'; // Подключите CSS файл

const FlexContainer = () => {
  const itemsRef = useRef([]);

  useEffect(() => {
    let maxWidth = 0;
    itemsRef.current.forEach(item => {
      const itemWidth = item.scrollWidth;
      if (itemWidth > maxWidth) {
        maxWidth = itemWidth;
      }
    });
    itemsRef.current.forEach(item => {
      item.style.width = `${maxWidth}px`;
    });
  }, []);

  return (
    <div className="container">
      {['First', 'Second thing is long', 'Third is', 'Fourth is even longer and longer', 'Fifth', 'Sixth'].map((text, index) => (
        <div className="item" ref={el => itemsRef.current[index] = el} key={index}>
          {text}
        </div>
      ))}
    </div>
  );
};

export default FlexContainer;

Заключение

Таким образом, вы создали гибкий контейнер с элементами одинаковой ширины согласно самому длинному элементу текста, не допуская оборачивания текста. Используя обе технологии – CSS для базового оформления и JavaScript (или React) для достижения требуемого функционала, мы можем успешно решить поставленную задачу.

Оцените материал
Добавить комментарий

Капча загружается...