[TIL] 2024-05-13 css border에 border-radius 적용해서 gradient 넣기

H Kim·2024년 5월 13일
1

TIL

목록 보기
62/69
post-thumbnail
  • 피그마 디자인

이번에 홈 화면 쪽에 새로운 섹션이 추가될 예정인데,
복지, 레인보우, 무료배송 등등 뱃지가 추가되는 건이 있었다.
아직 백엔드 작업 전이긴 한데 어쨌든 미리 만들어놓자고 하고는 뚝딱뚝딱 만드는 중.

원래 레인보우는 저런 gradient가 아니고 다른 색이랑 같은 빨간색 계열이었는데 기획적으로 뎁스가 달라지면서 디자이너짱이 레인보우 색깔을 진짜 레인보우로 만들어줬다...

사실 바꼈을 때까지는 그냥 하면 하겠지, 싶었는데 의외로 대박 고생해서 기록하기로 결심.


  • 코드펜 예시

Rainbow Gradient Border

<div class="rainbow-box">
  
body {
  background-color: #241d33;
}

.rainbow-box {
  background-color: #302244;
  border: 5px solid transparent;
  border-image: linear-gradient(to bottom right, #b827fc 0%, #2c90fc 25%, #b8fd33 50%, #fec837 75%, #fd1892 100%);
  border-image-slice: 1;
  height: 200px;
  margin: 20px auto;
  width: 200px;
}

border에 gradient 색깔을 넣어서 적용되는 방식이 아니라
border-image로 gradient를 두고 그 가운데를 파서(?) 원하는 것을 얹어놓는 것 같다.
그래서 이 속성으로 커스텀을 한다.

그러나 비보가 있었는데 border-image 속성은 border-radius가 먹지 않는다(왜?!?!).
하지만 디자이너의 디자인은 border-radius가 있어서 다시 머나먼 검색 여정을 시작...


  • with border-radius

Border with gradient and radius

결론적으로는 이 페이지를 참고했다.


  • 내 코드
const BadgeWrapper = styled.div`
  display: flex;
  padding-bottom: 10px;
`;

const Badge = styled.div<{ $color?: string }>`
  position: relative;
  margin-right: 4px;
  margin-top: ${({ $color }) => ($color !== 'rainbow' ? '1px' : null)};
  color: ${({ $color }) => $color || null};
  border: 1px solid ${({ $color }) => ($color === 'rainbow' ? 'transparent' : $color)};
  border-radius: 10px;
  font-size: 10px;
  height: ${({ $color }) => ($color === 'rainbow' ? '19.5px' : '17.5px')};
  padding: ${({ $color }) => ($color === 'rainbow' ? '1px 8px 0px 8px' : '0 8px')};
  background: ${({ $color }) =>
    $color === 'rainbow' ? 'linear-gradient(85deg, #FF6E6E 7.63%, #FFB956 37.96%, #70DC6C 68.3%, #5FC3E2 95.56%)' : null};
  background-clip: ${({ $color }) => ($color === 'rainbow' ? 'text' : null)};
  -webkit-background-clip: ${({ $color }) => ($color === 'rainbow' ? 'text' : null)};
  -webkit-text-fill-color: ${({ $color }) => ($color === 'rainbow' ? 'transparent' : null)};
  :before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 10px;
    padding: ${({ $color }) => ($color === 'rainbow' ? '1px' : null)};
    background: ${({ $color }) =>
      $color === 'rainbow' ? 'linear-gradient(85deg, #ff6e6e 7.63%, #ffb956 37.96%, #70dc6c 68.3%, #5fc3e2 95.56%)' : null};
    -webkit-mask: ${({ $color }) =>
      $color === 'rainbow' ? 'linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)' : null};
    -webkit-mask-composite: xor;
    mask-composite: exclude;
  }
`;

interface BadgeProps {
  badgeType?: BadgeType;
}

const ProductBadge = ({ badgeType }: BadgeProps) => {
  return (
    <BadgeWrapper>
      {badgeType?.welfare ? <Badge $color="#797c80">복지</Badge> : null}
      {badgeType?.brand ? <Badge $color="#ff8787">브랜드몰</Badge> : null}
      {badgeType?.rainbow ? <Badge $color="rainbow">레인보우</Badge> : null}
      {badgeType?.freeShipping ? <Badge $color="#1db53a">무료배송</Badge> : null}
      {badgeType?.abroadShipping ? <Badge $color="#4dabf7">해외배송</Badge> : null}
      {badgeType?.subscription ? <Badge $color="#a487fb">구독</Badge> : null}
    </BadgeWrapper>
  );
};

export default ProductBadge;

데이터가 내려오면 한 번에 되라고 해 놓은 건데 코드가 너무 보기 복잡해서 그냥... 레인보우만 분리하는 게 나을까 생각중...
일단 다 개발하고 생각해야지...

0개의 댓글