Не удалось использовать одно и то же имя класса для всех компонентов. Область действия CSS не отображается внутри компонента стиля

#html #css #reactjs #styled-components #css-in-js

#HTML #css #reactjs #styled-components #css-in-js

Вопрос:

Проблема, с которой я сталкиваюсь, похоже, противоречит самой цели CSS в JS. Я использую styled-compomnents . И когда я попытался использовать имя класса, которое используется где-то в дереве реакции внутри стилизованного компонента. Стили верхнего имени класса компонента каким-то образом применяются к имени класса, которое я использовал (очень) в дереве.

Шаги для воспроизведения

Визуализация UpperComponent в любом месте проекта react.

 const StyledContainer = styled.div`
  .title {
    color: red;
    margin-bottom: 32px;
  }
`;

const UpperComponent = () => {
  return (
    <StyledContainer>
      <FirstComponent />
      <h4 className="title"> text inside upper component </h4>
    </StyledContainer>
  );
};


const FirstStyledContainer = styled.div``;

const FirstComponent = () => {
  return (
    <FirstStyledContainer>
      <h4 className="title">text inside first component</h4>
      <SecondComponent />
    </FirstStyledContainer>
  );
};

const SecondComponent = () => {
  return (
    <div>
      <h4 className="title">text inside second component</h4>
      <ThirdComponent />
    </div>
  );
};

const ThirdComponent = () => {
  return (
    <div>
      <h4 className="title">text inside second component </h4>
    </div>
  );
};

  

Ожидаемое поведение

title имя класса в UpperComponent не должно влиять на элементы его потомков с тем же именем класса. Она должна быть ограничена только <h4 className="title"> text inside upper component </h4>

Фактическое поведение

.title { color: red; margin-bottom: 32px; } стили классов применяются ко всем компонентам внутри верхнего компонента. title каким-то образом сводится к ThirdCompoent тому, что вложено в два компонента.

Это ожидаемое поведение или я упускаю что-то базовое (лучшая практика)?

Комментарии:

1. Это ожидаемое поведение… И это не имеет ничего общего со стилизованным компонентом, на самом деле в CSS-in-JS вы не должны использовать имена классов и вместо этого использовать библиотеку

2. Но считаете ли вы, что каждый отдельный элемент должен быть стилизованным компонентом.

3. Попробуйте выяснить, что решает css-in-js, и это именно то, что вы пытаетесь сделать

4. Я разделил css / scss. Критические «над сгибом» css / scss используют стилизованные компоненты, все, что «ниже сгиба», я вставляю в файл css / scss для последующей загрузки. Когда дело доходит до стилизованных компонентов, иногда я создаю компонент в стиле компонента react, а иногда я создаю компонент, специфичный для элемента (но, скорее всего, компонент react). Я также могу включить только мобильный scss / css в стилизованный компонент и поместить содержимое точки останова рабочего стола в файл scss / css, который будет загружен позже.

Ответ №1:

Если вы хотите применить область действия — вы можете удалить имена классов и / или позволить «стилизованному компоненту» назвать их (генерирует случайное имя хэш-класса), создав TitleStyle и прикрепив к заголовку div (имя класса «title» можно удалить). Тогда это должно распространяться только на этот заголовок. Верно?

Другая альтернатива

Да, FirstComponent и SecondComponent (etc) будут перехватывать правило css сверху. Это ожидаемый результат для меня. Это не похоже на то, когда мы делаем это ниже!

 <div style = {{color:"red"}}>Test</div>
  

Это применит встроенный css только к этому div.

Я бы немного изменил имена классов заголовков следующим образом

 const StyledContainer = styled.div`
  .title {
    color: red;
    margin-bottom: 32px;
    amp;.secondary { color: pink; }
    amp;.thirdly { color: yellow; }
  }
`;

const UpperComponent = () => {
  return (
    <StyledContainer>
      <FirstComponent />
      <h4 className="title"> text inside upper component </h4>
    </StyledContainer>
  );
};

const SecondComponent = () => {
  return (
    <div>
      <h4 className="title secondary">text inside second component</h4>
      <ThirdComponent />
    </div>
  );
};

const ThirdComponent = () => {
  return (
    <div>
      <h4 className="title thirdly">text inside second component </h4>
    </div>
  );
};
  

amp; является оператором SCSS и отлично работает со стилизованными компонентами.
CSS более выгодно вести себя таким образом, поскольку передача правил css вниз более эффективна. Работайте с этой эффективностью! Вы хотите создавать шаблоны CSS для всего сайта, старайтесь избегать конкретного таргетинга, если вы не уверены, что это требуется (что должно быть не слишком распространенным).

Что я обычно делаю, так это создаю стилизованный компонент для компонента react, поэтому по одному на каждый компонент react для обработки всех css / scss в этом компоненте react.

Даниэль

Комментарии:

1. Но разве это не противоречит цели определения области видимости в CSS в JS?

2. Посмотрите мой измененный ответ? Дайте мне знать

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

4. Я снова отредактировал ответ, убедитесь, что вы прочитали самый последний ответ. Итак, чтобы было ясно. Если вы хотите, чтобы стилизованный компонент был специфичен для div, вам нужно создать TitleStyle и прикрепить к этому заголовку. Это создает уникальное случайное имя хэш-класса. Это не повлияет на другие заголовки. Но желательно повторно использовать CSS, сделать CSS для всего сайта. Я правильно ответил на ваш вопрос?

Ответ №2:

Это работает так, как должно. Вы выбираете все .title s в этом стилизованном компоненте.

В конце концов, styled-components просто генерирует уникальное имя класса для каждого созданного вами стилизованного компонента. Таким образом, правила CSS все еще работают там.

Вы можете

  1. Вы можете выбрать только прямого потомка .title .
     const StyledContainer = styled.div`
     >.title {
      // rules...
     }
    `
  
  1. Измените имя класса на что-то более конкретное.

  2. Вложите правило CSS в родительский элемент. Поэтому вместо этого,

     const StyledContainer = styled.div`
     .title {
      // rules...
     }
    `
  

Оберните ваш h4 другим элементом и сделайте это

     const StyledContainer = styled.div`
      .wrapperClassName {
         .title {
          // rules...
         }
      }
    `
  

Комментарии:

1. Создание TitleStyle и привязка к заголовку div более практичны. Я бы подумал, что это дополнительный уровень ненужной сложности