지난주에 만들었던 계산기를 리팩토링하면서 어딘가 어색하다는 생각이 들었다.
종이 위에서 톡(!) 튀어나온 것 같은 계산기를 만들고 싶었는데, figma 디자인과 임의로 작성한 코드가 섞이다 보니 기획과는 동떨어진 결과물이 나왔다. 요소마다 그림자의 색과 방향이 다른 것도 마음에 들지 않았다.
보다 자연스럽게 구현하기 위해 유튜브에서 WEB CIFAR의 How To Create Neumorphism Effect With CSS 영상을 들었다. 아래는 강의를 보며 정리한 내용과 의문점, 직접 실험해 본 내용을 담았다.
.button {
height: 50px;
width: 50px;
background: #dde1e7;
box-shadow: -3px -3px 7px #ffffff73, 3px 3px 5px rgba(94, 104, 121, .288);
border-radius: 5px;
}
.button-clicked {
height: 50px;
width: 50px;
background: #dde1e7;
box-shadow: inset -3px -3px 7px #ffffff73, inset 3px 3px 5px rgba(94, 104, 121, .288);
border-radius: 5px;
}
클릭된 버튼 효과를 만들기 위해서는 기존 box-shadow 속성값에 inset을 부여하면 된다. 영상의 코드에는 position: absolute;
와 position: relative;
속성도 있었으나 어떤 용도인지 확실하지 않고, 그 값이 없을 때에도 같은 결과가 나오기 때문에 코드에서 제거했다.
테두리는 볼록 튀어나오고, 버튼 내부는 들어간 형태의 버튼이다.
버튼 내부에 또 하나의 원을 만들기 위해서는 ::after
를 사용해야 한다.
::after
내용의 앞에 content를 추가하는 가상 요소이다.
가상 요소란 꾸미기 위해서 의미 없는 태그를 추가해야 할 때, 태그 대신 실제로 존재하지 않는 가상의 요소를 만들어서 스타일을 꾸밀 수 있도록 해주는 css 기능이다.
추가하는 content의 내용은content
속성으로 처리한다.::after
를 사용할 때에는 이 속성을 무조건 사용해야 한다. 따라서 추가할 내용이 없는 경우에는 아래 예시 코드와 같이 빈 문자열을 값으로 주면 된다.
코드는 다음과 같다.
.circle {
display: flex;
justify-content: center;
align-items: center;
height: 50px;
width: 50px;
background: #dde1e7;
box-shadow: inset -3px -3px 7px #ffffff73, inset 3px 3px 5px rgba(94, 104, 121, .288);
border-radius: 50%;
}
.circle::after {
content: '';
height: 80%;
width: 80%;
box-shadow: inset -3px -3px 7px #ffffff73, inset 3px 3px 5px rgba(94, 104, 121, .288);
border-radius: 50%;
}
나처럼 position: absolute;
와 position: relative;
속성한 것에 의문을 가진 사람이 있는지 확인하기 위해 영상 댓글을 읽던 중 흥미로운 의견을 발견했다.
이 댓글에서 말하는 neumorphisum-3은 내부에 굴곡이 있는 버튼(unclicked)이다.
제안처럼 가상 요소를 사용하지 않고 구현할 수 있겠다는 생각이 들어 직접 실험해 보았다.
.button {
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
height: 50px;
width: 50px;
background: #dde1e7;
box-shadow: -3px -3px 7px #ffffff73, 3px 3px 5px rgba(94, 104, 121, .288), inset -3px -3px 7px #ffffff73, inset 3px 3px 5px rgba(94, 104, 121, .288);
border: 5px solid transparent;
border-radius: 50%;
}
가상 요소를 사용하는 대신 border: 5px solid transparent;
속성을 추가했다.
또한 border를 기준으로 원 안쪽에 그림자 효과를 주기 위해 .circle::after
의 box-shadow 속성값을 가져왔다.
border 속성을 활용하면 훨씬 짧은 코드로 구현할 수 있지만 치명적인 단점이 있다. 바로 clicked 버전을 구현할 수 없다는 것... 😅
clicked 효과를 주지 않을 거라면 border를 활용해도 좋겠다.
하지만 버튼은 클릭을 전제로 만들어지는 엘리먼트이다. 뉴모피즘의 단점인 낮은 접근성을 개선하기 위해서라도 clicked 효과를 염두에 두고 처음부터 가상 요소를 활용하면 좋을 것 같다.