Не удалось использовать одно и то же имя класса для разных компонентов. CSS не ограничивается компонентом стиля

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

Действия по воспроизведению

Визуализируйте 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; } стили классов применяются ко всем компонентам внутри UpperComponent. title каким-то образом сводится к ThirdCompoent, который вложен в два компонента.

Это ожидаемое поведение или мне не хватает чего-то базового (передовой практики)?


person Abreham    schedule 06.11.2020    source источник
comment
Это ожидаемое поведение ... И ничего общего со стилизованным компонентом, на самом деле в CSS-in-JS вы не должны использовать classNames и вместо этого использовать библиотеку   -  person Dennis Vash    schedule 06.11.2020
comment
Но как вы думаете, каждый отдельный элемент должен быть стилизованным компонентом.   -  person Abreham    schedule 06.11.2020
comment
Попробуйте узнать, что решает css-in-js, и это именно то, что вы пытаетесь сделать.   -  person Dennis Vash    schedule 06.11.2020
comment
Я разделил css / scss. Критично над сгибом css / scss использовать стилизованные компоненты, все, что ниже сгиба, я вставляю в файл css / scss для последующей загрузки. Когда дело доходит до стилизованных компонентов, иногда я создаю компонент в стиле реагирующего компонента, а иногда я делаю компонент специфичным для элемента (но чаще всего это реагирующий компонент). Я также могу включить мобильный scss / css только в стилизованный компонент и поместить информацию о точках останова рабочего стола в файл scss / css, чтобы их можно было загрузить позже.   -  person GaddMaster    schedule 06.11.2020


Ответы (2)


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

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

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

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

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

Я бы немного изменил названия классов заголовков вот так

const StyledContainer = styled.div`
  .title {
    color: red;
    margin-bottom: 32px;
    &.secondary { color: pink; }
    &.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>
  );
};

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

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

Даниэль

person GaddMaster    schedule 06.11.2020
comment
Но разве это не противоречит цели определения области видимости в CSS в JS? - person Abreham; 06.11.2020
comment
Проверить мой измененный ответ? Дайте мне знать - person GaddMaster; 06.11.2020
comment
Да, это в значительной степени работает. Но меня беспокоит то, что неявные стили исходят от компонента с родительским стилем. Что может выйти из-под контроля, потому что большинство имен классов являются общими. - person Abreham; 06.11.2020
comment
Я снова отредактировал ответ, убедитесь, что вы прочитали самый последний ответ. Итак, чтобы было ясно. Если вы хотите, чтобы стилизованный компонент был специфичным для div, вам нужно создать TitleStyle и прикрепить его к этому заголовку. Это делает уникальное случайное имя хеш-класса. Это не повлияет на другие названия. Но желательно повторно использовать CSS, сделать css для всего сайта. Я правильно ответил на твой вопрос? - person GaddMaster; 06.11.2020

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

В конце концов, стилизованные компоненты просто генерируют уникальное имя класса для каждого стилизованного компонента, который вы создали. Так что правила 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...
         }
      }
    `
person Nathnael Dejene    schedule 06.11.2020
comment
Создание TitleStyle и присоединение к заголовку div более практично. Я бы подумал, что это дополнительный слой ненужной сложности. - person GaddMaster; 06.11.2020