🥇

Dev.to 지구의날 프론트엔드 챌린지 Winner

Created
May 1, 2024 01:47 AM
설명
해외 개발자 커뮤니티의 프론트엔드 챌린지 부분에 우승자가 되었습니다. 어떤 결과물을 만들었을까요?
Status
작성 완료
Tags
Javascript
FrontEnd
Select
Dev Log

Dev.to FrontEnd 챌린지

notion image
제가 자주 눈팅하는 해외 개발자 커뮤니티가 있는데요 dev.to 여기에서 지구의날을 기념해 개발 챌린지를 진행해서 참여하게 되었습니다.
간단한 챌린지였지만 우승자로 선정되니 기분이 좋았습니다!
관련 링크들을 아래에서 확인이 가능합니다.

Winners

Demo Page

Git

Dev-to-FE-challenge-Earth-Day
dev-dong-suUpdated Apr 28, 2024

Post

챌린지의 룰

프론트엔드 부분은 css art, landing page 두 부분이 있었고 룰은 간단했습니다.
CSS Art: js 사용 금지 html과 css 만 사용해 만들기.
Landing Page: html이 주어지고 html은 상용구를 제외한 수정 불가. js 통해야만 수정 가능. css 사용 가능.
저는 Landing Page 부분에 참가했습니다.

아이디어

아무래도 간단하게 개발하고 참여할 수 있는 가벼운 느낌의 챌린지였기 때문이기도 하고 모든 참여자가 동일한 HTML을 가지고 제작하기 때문에 아이디어가 가장 좋은 사람이 높을 점수를 받을 수 있다고 생각했습니다.
당신의 제출물은 우리가 제공한 HTML보다 더 재미있고 상호작용적이어야 하지만, 동시에 사용 가능하고 접근성이 있어야 합니다. -챌린지 설명 문구
챌린지의 설명을 읽고 상호작용적인 무언가를 생각했을 때 애니메이션은 기본으로 들어가야 한다고 생각했고 무언가 더 재미난 요소를 추가하고 싶었습니다.
그러다 스크롤을 내리면 사람이 별똥별처럼 내려와 지구를 껴안으면 재밌지 않을까? 라는 생각이 들어 개발을 시작했습니다.

디자인 컨셉

사람이 별똥별처럼 내려와 지구를 껴안는 모습은 재밌으면서도 메시지를 잘 전달할 수 있다고 생각했습니다.
이런 모습은 장난스러운 느낌이 드는데요, 여기서 영감을 받아 어린아이가 그린것 같은 느낌을 주고 싶었습니다.

그림 그리기

개발하기 전에 필요한 에셋을 직접 그렸습니다.
외부 리소스를 사용하면 안된다는 규칙은 없지만 그냥 처음부터 끝까지 제 손으로 만들고 싶었습니다.
그리는건 생각보다 쉬웠는데요. figma의 펜툴로 그렸고 참고 사진을 불투명하게 깔아두고 그렸습니다.
notion image
저의 서투른 그림 실력은 오히려 어린아이가 낙서한 것 같은 느낌을 주었고 “오히려 좋아” 였습니다!

폰트 선정

어린아이가 그린 웹사이트 같은 느낌이 나면 좋겠다고 생각했기 때문에 폰트도 이런 무드에 맞추어 선정했습니다.
notion image
가독성이 괜찮으면서도 손으로 쓴것 같고 둥글둥글한 적절한 폰트를 찾을 수 있었습니다!

개발 시작

👀
코드는 크게 볼만한게 없지만 Github에 올려 두었습니다.

HTML을 직접 수정하는건 불가능

이 챌린지를 가장 재밌게 만들어준 부분이었는데요.
HTML을 JS나 css를 통해 수정하지 않는 이상 직접적인 수정이 불가능하지만, 다시 말해 JS로 HTML을 어떻게 수정 하든 상관없다는 말이었습니다.
필요한 요소들은 다음과 같이 생성할 수 있었고, 순차적인 애니메이션 효과를 주기 위해 문자를 잘라 <span> 태그로 감싸주기도 했습니다.
const createHuman = () => { const humanDiv = document.createElement("div"); ... const createEarth = () => { const earthDiv = document.createElement("div"); ... const bounce = (query) => { ... text.split(" ").forEach((word, index) => { const wordSpan = document.createElement("span"); wordSpan.className = "char"; // 애니메이션용 클래스 wordSpan.style.animationDelay = `${index * 0.1}s`; wordSpan.textContent = word + (index < text.split(" ").length - 1 ? " " : ""); // 공백 추가 title.appendChild(wordSpan); }); ...

접근성

notion image
챌린지가 끝나기 전 제출하고 유저분들이 피드백을 해주셨는데요.
칭찬과 함께 심사 기준에 접근성도 있었기 때문에 이 부분의 보안을 추천받았습니다.
가장 신경쓴 부분은 aria 태그 였는데요. MacVoice Over 를 켜고 직접 어떻게 화면이 읽히는지 확인하며 작업을 진행했습니다.
 
가장 먼저 각 본문의 내용은 타이틀과 본문이 연결되어 잘 읽히도록 태그를 추가했습니다.
const sections = document.querySelectorAll("section > article"); sections.forEach((section, idx) => { const h2 = section.querySelector("h2"); if (h2) { const id = `header-${idx}`; h2.id = id; section.setAttribute("aria-labelledby", id); } });
 
좀 꼼수를 부린 부분이 있는데요. Header와 Footer의 제목에는 bounce 애니메이션이 순차적으로 작동하기 위해 글자를 분해해 따로따로 span 태그로 감싼뒤 딜레이를 주었습니다.
notion image
notion image
문제는 Voice Over에서 확인했을 때 이런식으로 읽어 주었는데요..
웰컴 스페이스 투 스페이스 아우어 스페이스 어스 스페이스 데이 스페이스 셀레브레이션
그래서 이 부분을 해소하기 위해 애니메이션이 적용된 태그는 Voice Over에 숨기고 사용자 눈에는 보이지 않는 컨텐츠를 추가해 해결했습니다.
notion image
const bounce = (query) => { const title = document.querySelector(query); const text = title.innerText; // 원래 텍스트를 숨겨서 접근성을 유지 const accessibleSpan = document.createElement("span"); accessibleSpan.innerText = text; accessibleSpan.style.position = "absolute"; accessibleSpan.style.left = "-9999px"; accessibleSpan.style.width = "1px"; accessibleSpan.style.height = "1px"; title.innerHTML = ""; // 기존 내용을 삭제 title.appendChild(accessibleSpan); // 접근성을 위한 span 추가 // 애니메이션을 위한 span들 추가 text.split(" ").forEach((word, index) => { const wordSpan = document.createElement("span"); wordSpan.className = "char"; // 애니메이션용 클래스 wordSpan.style.animationDelay = `${index * 0.1}s`; wordSpan.textContent = word + (index < text.split(" ").length - 1 ? " " : ""); // 공백 추가 wordSpan.setAttribute("aria-hidden", "true"); // 스크린 리더에서 이 span들을 무시하도록 설정 title.appendChild(wordSpan); }); };

결과

이 외에 다른 피드백도 적극 수용하며 코드를 수정하고 챌린지 결과를 기다렸습니다.
결과는 제목에서 보신대로 운좋게도 우승자로 선정이 되었습니다!
평소에도 이런 챌린지에 관심이 많았는데 이번에 참여해보니 확실히 즐거웠습니다.
상품은 Dev.to 챌린지 우승자 뱃지와 shop에서 사용 가능한 35$ 쿠폰을 받았습니다.