首页 > 解决方案 > 相邻兄弟没有获得 CSS 变量值

问题描述

我有一个ReactHeader 组件,我使用styled-components. 我有一个选择器,我用它来选择标题的下一个兄弟并给它一个顶部填充以在标题下保持一个清晰的空间,因为它有position: fixed. 当我为这种样式使用正常值时,它工作得很好,但是一旦我使用 CSS 变量,我就可以使用媒体查询自定义高度,该变量不再在兄弟元素中被解析。这是我的代码:

export const S_Header = styled.header<HeaderProps>`
  --height: 20vw;

  position: fixed;
  top: 0;

  width: 100vw;
  height: var(--height);

  /* Give the next sibling a top padding so text doesn't flow underneath the header */
  + * {
    padding-top: var(--height);
    margin-top: 0;
    border-top: 0;
  }
`;

样式被应用于标题本身(高度正常工作),但兄弟姐妹上的 padding-topvar(--height)在 Chrome 中具有正常值,但当我将其悬停时它不显示任何计算值。

标签: htmlcssreactjsstyled-componentscss-variables

解决方案


正如@DennisMartinez 所说,

“CSS 自定义属性在级联时工作。这意味着它将在声明它的元素和元素后代上工作。兄弟姐妹不是后代,因此你面临这个问题。”

这意味着很难解决这个问题。我相信以下解决方案可能是最好的,因为上面的限制使得很难想出更好的方法。

我最终声明了两次变量,一次在 Header 样式本身内,一次在同级选择器内。如果我愿意,我可以插入这个,这样我仍然可以有一个单一的事实来源。我希望通过媒体查询更改变量,所以我也声明了两次,在与变量相同的位置。如果我愿意,可以将此复制粘贴提取到字符串中并进行插值。

这是代码:

export const S_Header = styled.header<HeaderProps>`
  --height: 20vw;

  position: fixed;
  top: 0;

  width: 100vw;
  height: var(--height);

  @media (${devices.medium}) {
    --height: 10vw;
  }

  @media (${devices.large}) {
    --height: 5vw;
  }

  /* Give the next sibling a top padding so it doesn't start underneath the header */
  + * {
    --height: 20vw;

    padding-top: var(--height);
    margin-top: 0;
    border-top: 0;

    @media (${devices.medium}) {
      --height: 10vw;
    }

    @media (${devices.large}) {
      --height: 5vw;
    }
  }
`;

我还使用上面提到的插值写了这个:

const heightVar = "--height: 20vw;";

const mediaQuery = ` 
  @media (${devices.medium}) {
    --height: 10vw;
  }

  @media (${devices.large}) {
    --height: 5vw;
  }
`;

export const S_Header = styled.header<HeaderProps>`
  ${heightVar}

  position: fixed;
  top: 0;

  width: 100vw;
  height: var(--height);

  z-index: 98;

  transform: ${(props): string =>
    props.visible === false ? "translateY(-100%)" : "none"};

  background-color: ${(props): string =>
    props.atTop ? "transparent" : props.bgColor};

  transition: transform 0.35s, background-color 0.35s ease-in-out;

  ${mediaQuery}

  /* Give the next sibling a top padding so it doesn't start underneath the header */
  + * {
    ${heightVar}

    padding-top: var(--height);
    margin-top: 0;
    border-top: 0;

    ${mediaQuery}
  }
`;

推荐阅读