초기 코드에서는 개별 요소에 호버/포커스 효과를 적용해 전체적인 상호작용이 부자연스러웠습니다.
예: 카드와 아이콘이 별도로 반응해 UX 일관성 저하.
/* 카드와 아이콘을 각각 처리 → 일관성 없는 동작 */
.card-content:hover { border-color: blue; }
.arrow-icon-container:hover { background-color: blue; }
.card-content {
transition: border-color 0.3s ease-in;
}
/* 카드 전체에 호버/포커스 시 하위 요소 제어 */
.card-content:hover .purchase-icon-container,
.card-content:focus-within .purchase-icon-container {
background-color: var(--color-blue-500);
}
.card-content:hover .purchase-icon-container::before {
content: "구매하기"; /* 가상 요소로 텍스트 추가 */
}
:focus-within
을 사용해 자식 요소의 포커스도 캐치.transition
속성은 최종 대상에 직접 적용.이미지가 카드 내에서 수직/수평 중앙 정렬되지 않아 시안과 달랐습니다.
.product-card-image {
padding-top: 10px; /* 임시방편 조정 */
}
.card-content {
display: flex;
justify-content: center; /* 수평 중앙 */
align-items: center; /* 수직 중앙 */
height: 310px; /* 고정 높이 필수 */
}
margin
이나 padding
으로 위치 조정 시 다양한 해상도에서 깨질 수 있음.<span class="btn" aria-label="구매하기">...</span>
→ span
은 클릭 이벤트를 기본 지원하지 않음. role="button"
추가 필요.
<button class="purchase-btn" aria-label="상품 구매하기">
<img src="icon.svg" alt="" aria-hidden="true">
</button>
속성 | 사용 목적 | 예시 |
---|---|---|
aria-label | 요소의 목적 설명 | × |
aria-hidden | 불필요한 중복 콘텐츠 숨김 | ▲ |
role | 요소의 역할 재정의 | ... |
구현 절차
1. 픽셀 단위 측정: Figma에서 padding
, margin
값 정확히 확인.
2. 상대 단위 사용: px
대신 rem
으로 반응형 대응.
3. 변수 활용:
:root {
--button-padding: 8px 16px;
--icon-size: 40px;
}
항목 | 초기 구현 | 개선 후 | 중요도 |
---|---|---|---|
시맨틱 태그 | div 남발 | ul /li 사용 | ★★★★★ |
접근성 | alt="로고 이미지" | alt="쿠팡" | ★★★★☆ |
유지보수성 | nth-child 복잡 구조 | 클래스 기반 스타일링 | ★★★★☆ |
디자인 정확도 | 수동 위치 조정 | Flexbox 중앙 정렬 | ★★★☆☆ |
다음 작업 전에 반드시 확인하세요:
1. [ ] W3C Validator로 HTML 검증
2. [ ] 스크린 리더로 음성 출력 테스트
3. [ ] Figma 시안과 픽셀 단위 비교
4. [ ] nth-child
대신 명시적 클래스 사용 여부 확인
5. [ ] 모든 인터랙티브 요소 키보드 탐색 테스트
"디자인을 코드로 옮기는 것은 단순 변환이 아닌 재해석입니다.
태그 선택에서부터 스타일링까지, 모든 단계에서 '왜?'를 묻는 습관이 전문가와 주니어를 구분합니다."
– 프론트엔드 개발자 마틴 파울러