强制图像保持尺寸 ::before 填充底部纵横比黑客

时间:2021-04-19 08:29:06

标签: html css reactjs styled-components aspect-ratio

我正在使用 ::beforecontent: ''; padding-bottom: 100% 技巧来尝试在图像上强制使用 1:1 的纵横比。我还添加了 overflow: hidden。但是,正如您从屏幕截图中看到的,图像溢出到我在 ::before 内创建的正方形之外。我根本不希望图像拉伸,因此所有图像都应用了 object-fit: contain

我在宽高比上遵循了 various threadsCSS Tricks article

如何确保图像整齐地放入该方块中并且完全不会溢出?

编辑:Code sandbox

代码如下:

Item.tsx

<StyledItemWrapper
  className={item.animation}
  onClick={() => {
    clickItem(item);
  }}
>
  <picture>
    <img src={item.image} alt={item.title} />
  </picture>
  <StyledItemInfo>
    <p>{item.title}</p>
    <p>{item.description}</p>
    <p>${item.price.toFixed(2)}</p>
  </StyledItemInfo>
  <Button onClick={() => handleAddToCart(item)}>Add To Cart</Button>
</StyledItemWrapper>

Item.styles.ts

export const StyledItemWrapper = styled.div`
  display: flex;
  justify-content: space-between;
  flex-direction: column;
  position: relative;
  border: 1px solid lightblue;
  border-radius: 20px;
  &::before {
    display: block;
    overflow: hidden;
    padding-bottom: 100%;
    content: "";
  }
  picture {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    max-height: 50%;
    img {
      border-radius: 20px 20px 0 0;
      width: 100%;
      height: 100%;
      object-fit: contain;
    }
  }

  button {
    border-radius: 0 0 20px 20px;
  }
`;

export const StyledItemInfo = styled.div`
  font-family: Arial, Helvetica, sans-serif;
  padding: 1rem;
  height: 100%;
`;

enter image description here

1 个答案:

答案 0 :(得分:1)

问题是我将样式应用于包裹整张卡片而不仅仅是图像的 StyledItemWrapper,因此任何填充等都会影响整张卡片的布局。

长宽比的填充和伪选择器技巧仅在您将其应用于专用图像容器时才有效。所以,这就是我所做的:

Item.tsx

const Item: React.FC<Props> = ({ item, handleAddToCart, clickItem }) => (
  <StyledItemWrapper
    className={item.animation}
    onClick={() => {
      clickItem(item);
    }}
  >
    <StyledVisualWrapper> // new styled component
      <picture>
        <img src={item.image} alt={item.title} />
      </picture>
    </StyledVisualWrapper>
    <StyledItemInfo>
      <p>{item.title}</p>
      <p>{item.description}</p>
      <p>${item.price.toFixed(2)}</p>
    </StyledItemInfo>
    <Button onClick={() => handleAddToCart(item)}>Add To Cart</Button>
  </StyledItemWrapper>
);

Item.styles.ts

export const StyledItemWrapper = styled.div`
  display: flex;
  justify-content: space-between;
  flex-direction: column;
  border: 1px solid lightblue;
  border-radius: 20px;

  button {
    border-radius: 0 0 20px 20px;
  }
`;

export const StyledVisualWrapper = styled.div`
  position: relative; // move from StyledItemWrapper to here
  max-height: 50%;
  &::before {
    display: block;
    overflow: hidden;
    padding-bottom: 100%;
    content: "";
  }
  picture {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    img {
      border-radius: 20px 20px 0 0;
      width: 100%;
      height: 100%;
      object-fit: contain;
    }
  }
`;
相关问题