계산기 목업 만들기

Kim-DaHam·2023년 2월 16일
0

CSS

목록 보기
4/4
post-thumbnail

🟩 HTML/CSS 계산기 목업 만들기

첫 번째 페어 프로그래밍 과제 결과물이다.
지금껏 배운 html, css를 활용하여 계산기 목업을 만들었다.

평범한 계산기는 재미가 없을 것 같아 공학용 계산기를 골랐다.

만드는 과정에서 고민했던 것들과 해결 방법을 적어보려 한다.

✅ 이 부분을 집중해서 만들어 보자

  • 과도한 div 사용하지 않기 (나의 고질적인 습관, div 감싸고 감싸고 감싸기... 컨테이너의 컨테이너의 컨테이너*구골..의 달인 벗어나기)
  • css 셀렉터 적당히 다양하게 써보기. 특히 nth-~ 지금껏 바보 같이 class="cls1" "cls2"... 이런 식으로 하나하나 입력해서 순서를 골라 썼었다.)
  • 되도록 id 셀렉터 쓰지 않기.
  • 처음보는 css 속성 많이 써보기.
  • animation이나 transition 추가하기.



내가 만들고자 하는 녀석이다. 나의 대학 생활을 아주 조금 함께한 CASIO fx-570ES PLUS...
뚜껑이 탁탁 덮히는 게 귀여운 공학용 계산기.


🟩 와이어 프레임 제작하기

🟣 구조 구상하기

시작부터 작은 고민이 생겼다. 바로 버튼의 배치에 관련 된 일이었다. 만들고자 하는 공학용 계산기 버튼은 일반 계산기처럼 사각형만으로 이루어지지 않았다는 게 문제다.

두 가지 방법이 있었다. 그냥 만들기 쉽게 사각형으로 구역을 나눌 것인가? (like 빨강 구역)
혹은 기능을 넣을 것까지 고려해 버튼의 기능 별로 구역을 나눌 것인가. (like 초록 구역)

난 당연히 기능을 고려하고 싶었고, 당연히 그래야만 했다. 하지만 저 미묘하게 겹치는 부분이 귀찮았다.
지금은 안 만들 거지만 반응형을 고려했을 때 크기 조절도 간편했으면 좋겠는데...

그래서 고민하고 있는데 페어 분께서 대안을 내주셨다. 💡가운데 투명한 비활성 버튼을 2개 만들고 position을 변경해요!

저 빈 부분에 margin을 넣을까 궁리하고 있었는데 투명 버튼이 더 좋은 방법이라 바로 택했다. 감사합니다😊

그리하여 아래와 같은 구조를 만들었다.

🟥 .logo
🟧 .monitor
🟨 .navigation
🟩 .symbol
🟦 .number
🟪 .calculate

클래스는 이렇게 구분 지었다.


🟩 디자인 하기

🟣 .calculation (컨테이너)

계산기의 몸체이자 모든 구성요소들의 컨테이너다.

크기

width 고정값을 주고 height:auto를 선택했는데, 사실 난 저 고정값이라는 게 싫다. 뭐든지 초장부터 유연하게 화면 비율에 맞추자 다짐은 하는데... 어차피 계산기라는 게 화면 가로길이 줄어든다고 끊임없이 같이 줄어들 순 없지 않은가? 반응형을 적용한다면 PC, 태블릿, 모바일 세 개 값만 따로 지정하면 되겠지. 그래서 px 값을 주었다.



⬜ 배경 그라데이션 넣기

되게 흔한 css속성인데, 나는 이번에 처음 써 보았다. 예쁜 색이 자연스럽게 안 나와서 img을 삽입하곤 했었다. 그런데 입체감 주는 연습도 하면 좋을 것 같고, 브라우저가 생성하는 것이기 때문에 이미지보다 용량이 훨씬 적고 화면을 확대해도 보다 선명하게 잘 나오기 때문에 배워둘 필요가 있다.

gradient
'기울어짐'의 정도 or 기온이나 압력의 '변화 비율'
css gradient는 background, background-image 속성을 사용한다.

나는 한 단어 더 적기 귀찮아서 background 속성으로 설정했는데,

사실 background는 여러가지 백그라운드 관련 속성(background-color, background-repeat, background-position 등)을 조합해서 사용하는 값이므로 별도 지정하는 편이 CSS 버그를 방지하는 데 도움이 된다고 한다.

< gradient 의 종류>

  • linear-gradient : 선형 그라데이션
  • radial-gradient : 원형 그라데이션
  • repeating gradient : 반복형 그라데이션

linear-gradient : 선형 그라데이션

background: linear-gradient(direction, color1, color2, … , color5)

< directoin 의 종류>

  • to bottom : 위에서 아래로 내려오는 그라데이션(기본값)
  • to top: 아래에서 위로 올라가는 그라데이션
  • to left: 오른쪽에서 왼쪽으로 이동하는 그라데이션
  • to right: 왼쪽에서 오른쪽으로 이동하는 그라데이션
  • to top right: 상단 오른쪽으로
  • to bottom left: 하단 왼쪽으로
  • ndeg: n도의 방향으로 그라데이션

색깔은 여러 개 입력할 수 있다. 입력한 순서+설정한 방향으로 그라데이션을 만든다.

< 그라데이션 범위 정하기 >
색 뒤에 백분율/픽셀 등을 입력하면 해당 길이"까지" 색을 적용한다.
linear-gradient(to right, yellow 50%, red 60%, purple)


나는 특히 본체 디자인 중 이 부분이 복잡했으므로 아래와 같이 테스트 해봤다.

단순해 보이지만 내가 어려웠던 부분은 광 만들기 였다. -45deg를 하면 지정한 색 순서가 우측 하단부터 시작해서 어찌나 헷갈리던지...

게다가 광 가운데 하얀색 라인이 드러나는 걸 강조하고 싶어서, 그거 조절한다고 노가다 했다.


radial-gradient : 원형 그라데이션

repeating-linear-gradient(ending-shape size at position, color1, color2, color3)

  • ending-shape: 원(circle) or 타원(ellipse) 모양 결정.
  • size: gradient의 끝모양 크기
    * closest-corner: 끝 모양이 gradient 중앙에서 가장 가까운 모서리로 흐려짐
    • closest-side: 끝 모양이 gradient 중앙에서 가장 가까운 변으로 흐려짐
    • farthest-corner: 기본값. gradient 중앙에서 가장 먼 모서리로 흐려짐
    • farthest-side: gradient 중앙에서 가장 먼 변으로 흐려짐
  • position: 중심의 위치. 기본값 center.
  • 0% 는 gradient 중앙, 100%는 gradient 끝.


size가 도저히 이해가 안 가서 구글링 했더니, 아래와 같은 멋진 예시가 있었다. 곰곰히 보고 있긴 한데... 그래서 이걸 어떻게 응용하면 좋을지 당장 머릿속에 잘 안 떠오른다. 간단한 게임 모션에 적용하면 좋을 것 같은데, ...아직 모르겠다.(추후 깨달으면 수정하자)


repeating-gradient : 반복 그라데이션

repeating-linear-gradient(direction, color1, color2, color3)

w3schools 예시를 가져와봤다.
오 이거 완전... blackpink - shutdown 컨셉 화면 만들 수 있을 것 같은 느낌이다. 회색 그라데이션으로 셔터 만들어서 촤라락 올리고 내릴 수 있게!


gradient 지원 불가 브라우저 참고, 표준 문법 첨부

#linear-gradient{

  background-color: skyblue;  /* fallback */
  background: -webkit-linear-gradient(skyblue, white); /* Safari 5.1 ~ 6.0, chrome 10.0~25 */
  background: -o-linear-gradient(skyblue, white); /* Opera 11.1~ 12.0 */
  background: -moz-linear-gradient(skyblue, white); /* Firefox 3.6 ~ 15 */

filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='16진수 색상값', endColorstr='16진수 색상값'); /*IE6~8*/

-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr='16진주', endColorstr='16진수')"; /*IE8+*/

  background: linear-gradient(skyblue, white); /*표준 문법 */
}

🌠 checkpoint. linear-gradient에 transition 효과 설정

참고

일반적인 background-color와 달리 linear-gradient를 사용한 background-color에는 transition 속성의 timing 값이 적용되지 않는다.

ex) 그라데이션 글자의 색상이 다른 색상으로 서서히 바뀌게 하고 싶은데, 서서히 바뀌지 않고 휙 바뀌어 버린다.


해결 방법 => backround-color에 timing을 걸어 바꾸려 하지 말고, 부모 요소와 겹치는 똑같은 요소를 하나 더 만들어 opacity(투명도)를 천천히 바꾼다.



🟣 .monitor

🤍 모니터에 사용할 디자인

  • 입체적인 그림자 효과
  • 화면 위에 광이 지나가는 효과

⬜ animation

.monitor:hover 시 모니터에서 반짝이는 광이 지나가는 모션을 만들어보자.

우선 animation을 사용하려면 그와 짝꿍인 @keyframe에 대해 알아야 한다.


< @keyframes >
@keyframes는 css 애니메이션에서 구간을 정하고 각 구간별로 어떤 스타일을 적용시킬지 정하는 문법이다.

@keyframes를 사용하려면 아래 세 가지를 필수 설정한다.

  • animation-name: 사용자 지정. @keyframes가 적용 될 애니메이션 이름
  • stage: from-to. 0~100%의 구간.
  • css style: 각 구간에 적용시킬 스타일

< animation >

animation 속성은 아래와 같다.

  • animation-name: @keyframes이름
  • animation-duration: 타임 프레임 길이, 키프레임이 동작하는 시간
  • animation-timing-function: 애니메이션 속도 조절
    • ease: 천천히-빠르게-천천히

    • ease-in: 천천히-보통으로

    • ease-out: 보통으로-천천

    • ease-in-out: 천천히-보통으로-천천히

    • linear: 등속

    • step-start: steps(1, start)와 같다.시작하는 지점에 스텝을 끊어준다.

    • step-end: steps(1, end)와 같다. 끝나는 지점에 스텝을 끊어준다.

    • steps(4, end)

    • cubic-bezier: 사용자 커스텀

  • animation-delay: 애니메이션을 시작하기 전 지연시간 설정. 음수 가능
  • animation-iteration-count: 반복 횟수 지정
  • animation-direction: 반복 방향 설정(정방향/역방향/번갈아)
    • normal
    • reverse
    • alternate: 무한반복 애니메이션에 자주 쓰임
    • alternate-reverse
  • animation-fill-mode: 애니메이션 시작/끝 상태 제어
    • none: 아무것도 지정되지 않은 상태
    • forwords: 애니메이션이 키프레임의 100%에 도달했을 때 마지막 키프레임을 유지
    • backwords: 애니메이션의 스타일을 애니메이션이 시작되기 전에 미리 적용
    • both: forwards/backwards 둘 다 적용
  • animation-play-state: 애니메이션 실행/일시중지 지정
    • paused: 일시중지
    • running: 재생

모니터 광은 다음과 같이 만들었다.

우선 중첩 div가 3개다. z-index가 낮은 순서대로 기본 모니터, 광, 광 overflow를 자르기 위한 div.

세 개의 div는 모두 컨테이너 모양이 일치해야한다. 광은 gradient를 투명-흰색-투명 으로 주어서 묘사하였다.

mouse:hover일 때 광이 휙 지나가려면 transition을 통해 left position을 이동시키면 된다.

그러나!! 그러려면 광의 모양이 평행사변형이어야 하고, 광의 시작 위치가 모서리에 걸쳐져선 안 된다.

하지만 난 자연스러운 디테일을 추구하기 때문에.. 광의 고정(시작) 위치는 무조건 모서리에 걸쳐졌으면 했고,

귀찮더라도 animation을 넣어 광을 움직이게 되었다.

(모서리 걸친 광→모니터의 중앙을 지나는 평행사변형 광 으로 변하면서 이동하는 거다.)

광이 끝 지점에서 사라지게 하는 법은 다음과 같다.
z-index가 가장 높은 monitor를 투명하게 만든 뒤 그 자식요소인 광에 대해 overflow:hidden 를 해주면 된다.

그럼 광의 left는 한껏 옆으로 이동해서 모니터를 넘치는데, hidden 되어서 보이지 않게 된다.


이 외에도 예쁘고 다양한 css animation을 참고하여 나만의 독창적인 홈페이지를 만들어보자.

다양한 animation 구경하기 (feat. codepen)

애니메이션과 비슷한 듯 다른 transition에 대해서도 알아보자
transition



🟣 .navigation

🤍 네비게이션 버튼에 사용할 디자인

  • 입체적인 그림자 효과
  • 타원 도형 그리기

⬜ flexbox

네비게이션 버튼의 배열은 다음과 같이 했다.

.navigation {
	display: flex;
    justify-content: space-evenly;

나는 flex를 알기 전에 각 요소들 간의 간격을 늘 margin-right, left로 배치했었다.

그렇게 하면 space-around와 같이 배치 되어서 늘 right left 값을 적절해 빼주곤 했는데

flex와 space-evenly를 알게 되고 각 요소의 width 값을 조절해 여백 간 거리를 자동으로 일정하게 맞출 수 있게 된 점이 제일 뿌듯하다.

과거의 나한테 돌아가서 알려주고 싶다...

⬜ clip-path

네비게이션 버튼의 특징은 모양이 타원형이라는 거다. 나는 지금까지 타원이나 원을 만들 때 늘 border-radius를 될 때까지 조절해 만들었다.

그런데 당연하게도 내가 원하는 타원 모양은 나오지 않았고,

꼼수도 안녕 clip-path를 공부하게 되었다.

clip-path는 도형을 자르는 것이다.

아래 사이트에서 원하는 모양을 만든 후 코드를 복사해 붙여 넣으면 된다. 아주 간단하다^^

CSS clip-path maker

⬜ drop-shadow

문제는 그 다음이다.
clip-path는 말 그대로 사각형 개체 box를 보일 부분만 자른 것이기 때문에 box-shadow를 사용할 시 버튼 주변에 사각형 그림자가 생기게 된다.

이때 사용해야 하는 것이 drop-shadow다.

filter: drop-shadow( x y 번짐정도 색상);

쉼표가 없다. 헷갈리지 말자.

참고로 filter 속성은 하드웨어 가속 된다.(GPU사용) 그래서 애니메이션을 적용했을 때 성능이 훨씬더 좋아진다고 한다.

사파리 브라우저에서는 glitch 버그가 발생하나보다. will-change:transform 을 설정하면 된다고 한다.

🌠 checkpoint. 더 사실감 있는 그림자를 만들어보자.

  • 물체가 바닥에서 멀리 떨어져 있을 수록 그림자의 번짐은 높아지고 물체의 크기는 커진다.
  • 광원은 좌측 상단에 두는 것이 보기 좋다.
  • 좌측 상단에는 inset 그림자를 하얗게 포인트로 넣어주자.


🟣 .symbol

🤍 심볼 버튼에 사용할 디자인

  • 입체적인 그림자 효과
  • 복잡한 수식 기호 입력하기
  • 요소 겹치기

⬜ flexbox

심볼 버튼의 flex 배치는 다음과 같다.

.symbol {
	display: flex;
    flex-wrap: wrap;
    justify-content: space-evenly;
}

⬜ box-shadow

지금까지 그림자는 바깥쪽에, 그것도 한 위치에만 만들 수 있다고 착각한 과거의 나를 반성하며 적는다.

box-shadow: x y blur spread color
box-shadow: inset x y blur spread color

두 개를 섞어쓰고 싶으면 쉼표로 구분해서 계속 추가하면 된다. 여러 위치도 가능하다.

⬜ z-index & position

대망의 투명 버튼 자리를 겹칠 때다.

z-index를 사용해서 네비게이션 버튼 밑에 심볼버튼이 깔려야 하는데, 그냥 z-index를 쓰면 되는 게 아니라 position이 중요하다.

< position 이란?>
요소가 이동할 때의 좌표 기준이다.
top, bottom, left, right을 이동하고 싶을 땐

  1. 기준을 잡고(position: relative;)
  2. 이동한다(top: 50px;)

< position 속성 >

  • static: 기본값. 태그 관계에 의해 자동으로 배치.
  • relative: 자신 위치를 기준으로 배치
  • absolute: 부모 위치를 기준으로 배치
  • fixed: 뷰포트 기준으로 배치. 부모로 부터 완전히 독립되어 브라우저 화면(viewport) 상에서 어디든지 원하는 위치에 자유롭게 배치 가능. 다른 요소들이 상하좌우로 움직일 때, 해당 요소는 움직이지 않음
  • sticky: 스크롤 영역 기준으로 배치. 부모의 스크롤 영역이 끝나면 고정 된다.

fixedsticky 모두 상단 메뉴바 고정에 잘 쓰인다. 둘의 차이는 다음과 같다.

sticky는 부모 position:relative와 자신 top을 설정해야 한다.


< z-indexposition의 관계 >
🔴 z-index를 적용한 영역이 position:static 이어선 안 된다. 태그의 위치에 따라 자동 배치되니까.

하지만 기본값이 static 이므로 position을 지정하지 않으면 z-index 사용은 불가능하다.

겹쳐지는 요소들이 중첩되어 있다면, 서로를 부모 기준 삼아 첫번째 사각형과 같이 겹칠 수 있다.

겹쳐지는 요소들이 중첩되어 있지 않다면 그냥 relativeabsolute 중 아무거나 고른 다음
(아무래도 자신을 기준으로 하는relative가 낫다) top left 등을 조정하면 된다.

⬜ 복잡한 수식 기호

공학용 계산기 수식 심볼은 아래와 같이 html에서 표현 가능하다.

html 수식 글자



🟣 .number & calculate

🤍 숫자&계산 버튼에 사용할 디자인

  • 컨테이너 안의 컨테이너

⬜ flexbox

숫자 패드 flexbox는 다음과 같이 구성되어 있다.

<calculate-body>
	<number></number>
    <calculate></calculate>
</calculate-body>

파랑 박스가 <number>, 보라 박스가 <calculate> 이다. js를 추가할 때를 대비해 기능별로 분류했다. 그리고 저 둘을 모두 합친 컨테이너가 <calculate-body> 이다.

<calculate-body> 안에 row 정렬 flex가 있고, 각각의 버튼 패드가 또 flex 정렬 되어있는 거다.

.calculate-body {
    display: flex;
    flex-wrap: wrap;
    flex-direction: row;
    justify-content: space-evenly;
}
.number {
    max-width: 60%;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-evenly;
}
.calculate {
    max-width: 40%;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-evenly;
}

그런데 calculate-bodyflex-grow를 7:3으로 하면 number패드와 calculate 패드가 자동으로 딱 떨어지게 나뉠 줄 알았는데, 콘텐츠 내용이 그대로 넘쳐버렸다.

그래서 max-width를 60% 40%로 다시 정의했다.

지금 다시 생각해보니까 flex-basis를 0으로 하고 flex-grow를 7:3으로 해야했나?
(=> 내일 그렇게 수정해봐야겠다.)



🟣 배경화면 추가

이미지 사이즈 맞추기




📔 오늘의 후기 (메타인지 ver.)

오늘 동기부여 세션에서 코치님께서 알려주신 메타인지 학습 가이드를 참고하여 후기를 써보자.

구분내용
점검< 오늘 학습 중 새롭게 배운 내용&다른 사람에게 설명할 수 있는 내용 >
1. 안팎 그림자 (inset)
2. clip-path
3. drop-shadow
4. z-index와 position의 관계
5. animation
6. transition
7. flex
조절< 오늘 학습한 내용 중 불확실한 것 >
1. 마우스 hover 이벤트가 얼마나 연속적으로 발생하는지 체크 필요(모니터 광이 무한 반복되어서)
=> 다음주 자바스크립트 배울 때 콘솔로 확인 해보고 제어 방법 떠올리기
2. 숫자패드 max-width 안 쓰고 flex만으로 해결 안 되는지.
=> 내일 css 파일 수정해서 테스트 해보기

추가 느낀점)
배운 내용을 이렇게 꼼꼼하게 블로깅 하려니 보기보다 시간이 엄청 걸린다.
하지만 시간이 걸린 만큼 자동적으로 공부가 되고, 기록을 다 적고 나면 확실하게 머리에 굳혀진 게 느껴진다. 나만의 자료사전을 만든다는 생각으로 실천하니까 절대 대충 기록하지 않게 된다.
작은 거라도 하나하나 꼼꼼히 공부한 뒤 제대로 머리에 집어넣은 것만 적으려 한다.

이전에 흐지부지 보내버린 학교 부트캠프에서는 내가 궁금했던 걸 구글링 하고, 그걸 알려주는 블로그의 링크를 내 블로그에 복붙 해두는 게 전부였다. 그렇게 하니까 절대 다시 그 링크를 열어 볼일도 없을 뿐더러 내 기억속에 남는 것도 없었다.

과거의 나를 단단히 반성하고, 내가 정확히 아는 것만 블로깅 하고 나니 재산이 쌓인 것처럼 든든하고 장기기억으로 이어지는 것 같다.

다시 태어난 것만큼 내게 공부하는 법을 제대로 알려준 코드스테이츠에게 감사합니다ㅜ.ㅜ 한 4년만 일찍 이럴 걸 왜 떠먹여 줘야 깨닫는 건지...🥺

profile
다 하자

0개의 댓글