생활코딩 html, css, javasript를 공부하고 Google 홈페이지를 만들어 보기로 했다.
생활코딩의 강의만 듣고 검색의 힘을 빌려하는 클론코딩이기 때문에 부족한 점이 많고 오류도 많다.
코드 작성 전 아래처럼 큰 틀을 정했다.


검색창의 돋보기 모양 아이콘 뒤부터 타이핑이 가능, 검색창의 지우기 아이콘 앞까지 타이핑이 가능
검색창에 마우스 포인팅, 포커스 했을 때 검색창 주변에 그림자 효과
검색창에 타이핑할 때 지우기 아이콘과 경계선 생성
검색창의 지우기 아이콘을 누르면 지워짐
검색창 밑 박스들에 마우스 포인팅 시 테두리 생성
큰 틀을 토대로 HTML 코드만 작성한 결과는 아래와 같다.
아이콘은 모두 font awesome 사이트를 이용했다.

<header>
<ul>
<li><a href="https://mail.google.com/">Gmail</a></li>
<li><a href="https://www.google.co.kr/imghp?hl=ko&ogbl">이미지</a></li>
<li><button class="google-app"><i class="fas fa-th"></i></button></li>
<li><button><img class="profile-image" src="images/profile.jpg"></button></li>
</ul>
</header>
이 부분은 정말 고민을 많이 했다. 4개의 요소를 나열하기 위해 li 태그의 display 속성을 inline-block으로 설정했으나 margin을 조정해도 자꾸 프로필만 삐져나왔다.

css inline-block vertical align 으로 검색을 해봤고 vertical-align 속성이 있다는 걸 알게 됐다.
vertical-align의 속성값으로 middle을 적용해 해결할 수 있었지만 뭔가 다른 방법은 없나 검색하던 중 flex를 알게 됐다.
flex의 개념과 여러가지 사용방법은 https://studiomeal.com/archives/197 이 곳의 도움을 굉장히 많이 받았다.
header ul {
display: flex;
align-items: center;
}
ul 태그에 flex를 적용하고 4개의 요소들 간격은 margin값을 조정해 일렬로 정렬할 수 있었다.

margin, padding 값들을 조정하면서 배운 것은 margin-top, margin-left 등 따로 선언해 조정하지 않아도 아래처럼 한 번에 설정할 수 있다는 것이다. 상, 우, 하, 좌 시계 방향 순서로 적용된다.
아래처럼 2개의 값만 설정하면
padding: 10px 11px;

위 사진처럼 적용된다.
header에 있는 4개의 요소들은 항상 우측 상단에 고정되어 있다.
css placing right top corner 로 검색해봤고 position의 속성값을 absolute로 설정하면 우측 상단에 고정할 수 있다는 것을 알게 됐다.
모든 태그의 default는 static이고 여러 태그가 있을 때 왼쪽에서 오른쪽, 위에서 아래로 요소들이 쌓인다.
absolute 속성은 static 속성을 가지고 있지 않은 부모를 기준으로 움직이는데 relative, absolute, fixed를 속성값으로 가지고 있는 부모가 없다면 body 태그를 기준으로 움직인다.
position의 속성값을 absolute로 설정하고 top, left, bottom, right 값을 조정해 위치를 잡으면 된다. 내가 하고 싶은 건 우측 상단에 고정이기 때문에 아래처럼 값을 조정했다.
우측 상단으로 붙어야 하니까 top, right를 0으로 설정하면 된다.
header ul {
position: absolute;
top: 0;
right: 0;
margin: 0;
list-style: none;
}

ul {
list-style: none;
}
위처럼 list-style의 속성값을 none으로 설정하면 점이 사라진다.
어떤 사진이 적용되든 프로필은 항상 원형태이기 때문에 css image circle crop 로 검색했고 border-radius 속성을 알게 됐다. border-radius 사용방법은 https://developer.mozilla.org/ko/docs/Web/CSS/border-radius 이 곳의 도움을 받았다.
header .profile-image {
border-radius: 50%;
}

아무런 동작이 없을 때는 텍스트만 존재하고 마우스 포인터가 Gmail, 이미지 텍스트에 올라갔을 때 underline이 생성되어야 한다.
header a { /* 아무런 동작이 없을 때 */
text-decoration: none;
}
header a:hover { /* 마우스 포인터가 올라갔을 때 */
text-decoration: underline;
}
:hover는 가상 클래스로 선택자에 추가하는 키워드이다.
header a:hover에 마우스 포인터가 올라갔을 때 추가하고 싶은 속성을 적용하면 된다.
link, visited, active, focus 등 많은 가상 클래스가 존재한다. 우선순위가 존재하기 때문에 신경써야 하는데 나중에 등장하는 클래스가 우선순위가 더 높다.
만약 hover 뒤에 visited를 작성하면 방문한 링크에는 hover가 적용되지 않는다.
이 부분도 hover 가상 클래스를 사용해 해결했다.
background-color 속성을 이용해 색을 설정했는데 background-color의 영역이 어디까진지 궁금했다. padding 혹은 border 영역까지 색을 채우는 지 검색해봤다.
background-clip 속성을 찾았는데 이 속성은 요소의 배경이 어디까지 차지할 지 지정하는 속성이다.
default는 border-box이고 paddiing-box, content-box, text 속성값이 존재한다.
https://developer.mozilla.org/ko/docs/Web/CSS/background-clip 이 곳의 도움을 받았다.
google app 아이콘, 프로필 사진은 모두 border 값이 0이고 padding 값을 설정해 회색원의 크기를 설정했다. default가 border-box이기 때문에 background-clip 속성을 따로 설정할 필요는 없었다.
프로필 사진은 원 형태라 이미 border-radius가 설정된 상태고 google-app에도 추가로 border-radius를 설정했다. 따라서 hover에는 background-color 속성만 추가하면 된다.
header .google-app {
font-size: 17px;
color: rgb(95,99,104); /* 아이콘의 색 */
padding: 10px 11px; /* hover에서 뒷배경 사이즈, 가로 세로 비율 맞추려고 10, 11 */
border-radius: 50%; /* hover에서 뒷배경 원 설정 */
}
header .profile-image {
border-radius: 50%;
width: 35px;
padding: 4px; /* hover에서 뒷배경 사이즈 */
margin-right: 10px;
}
header .google-app:hover {
background-color: rgb(240,240,240);
}
header .profile-image:hover {
background-color: rgb(240,240,240);
}
최대한 색을 같게 하고 싶어서 Edge 확장 프로그램 기능을 사용했다. chrome 스토어에서 ColorZilla라는 프로그램을 가져와 색을 추출할 수 있었다.
<section class="middle">
<div class="google-logo">
<img class="logo-image" src="images/logo.png">
</div>
<div class="search-box">
<span class="search-icon"><i class="fas fa-search"></i></span>
<span class="keyboard-icon"><i class="far fa-keyboard"></i></span>
<span class="microphone-icon"><i class="fas fa-microphone"></i></span>
<button class="clear-btn"><i class="fas fa-times"></i></button>
<input class="search-bar" type="text">
</div>
<div class="additional-box">
<a href="#" class="additional-search">Google 검색</a>
<a href="https://www.google.com/doodles" class="additional-lucky">I'm Feeling Lucky</a>
</div>
</section>
검색창 요소 자체에 width, padding 값을 조정해서 구현할 수 있었다.
.png)
.png)
width, padding 값을 조정해 파란 영역에만 타이핑이 가능하도록 했다.
이 부분도 가상 클래스인 hover, focus를 사용해서 해결했다. 그림자 효과를 적용하기 위해 css shadow effect 로 검색했고 box-shadow 속성을 알게 됐다.
https://developer.mozilla.org/ko/docs/Web/CSS/box-shadow 사용방법은 이 곳에서 도움을 받았다.
.middle .search-bar:hover {
box-shadow: 0 0 5px 1px rgb(225, 225, 226);
}
.middle .search-bar:focus {
box-shadow: 0 0 5px 1px rgb(225, 225, 226);
}
순서대로 offset-x, offset-y, blur-radius, spread-radius, color에 적용된다.
offset-x, offset-y는 수평 거리, 수직 거리를 의미하고 그림자의 위치를 설정하는 2개의 length 값인데 모두 0이면 그림자가 요소 바로 뒤쪽에 위치한다. 검색창 테두리에 모두 그림자 효과가 적용되어야 해서 0으로 설정했다.
blur-radius는 크면 클수록 그림자 테두리가 흐려져 크기는 커지고 색은 밝아진다.
spread-radius가 양수값이면 그림자가 더 커지고 확산, 음수값이면 그림자가 줄어든다.
color는 색 추출 기능을 사용해 최대한 비슷하게 맞췄다.

실제 구현한 결과이다.
X 아이콘은 font awesome을 사용했고 경계선은 border-right 값을 주어 만들었다.

.middle .clear-btn {
visibility: hidden;
border: 0;
border-right: 1px solid rgb(123,123,123);
padding-right: 17px;
background-color: transparent;
position: absolute;
margin: 12px 450px;
font-size: 20px;
color: rgb(123,123,123);
}
기본적으로는 숨겨져 있는 상태이기 때문에 visibility의 속성값을 hidden으로 하고 JS를 통해서 타이핑 시 지우기 아이콘과 경계선이 생성되도록 했다.
const clearBtn = document.querySelector(".clear-btn");
const searchBar = document.querySelector(".search-bar");
searchBar.addEventListener("keyup", function() {
if(searchBar.value && clearBtn.style.visibility != "visible"){
clearBtn.style.visibility = "visible"
} else if(!searchBar.value) {
clearBtn.style.visibility = "hidden"
}
});
const searchBar = document.querySelector(".search-bar");
searchBar.addEventListener("keyup", function() {});
searchBar를 querySelector로 element를 받아와 addEventListener를 사용해 이벤트리스너를 등록해준다. 이벤트명, 실행될 함수 순으로 매개변수를 지정한다.
지우기 아이콘이 나타나거나(타이핑) 사라지려면(백스페이스로 모든 텍스트 지움) 키보드 이벤트가 필요하니까 이벤트명은 keyup으로 지정했다.
if(searchBar.value && clearBtn.style.visibility != "visible"){
clearBtn.style.visibility = "visible"
}
만약 검색창에 텍스트가 존재하고 지우기 아이콘이 보이지 않는 상태면 지우기 아이콘 visibility의 속성값을 visible로 설정해 나타나게 한다.
else if(!searchBar.value) {
clearBtn.style.visibility = "hidden"
}
만약 검색창에 아무 텍스트도 없다면 지우기 아이콘 visibility의 속성값을 hidden으로 설정해 사라지게 한다.
clearBtn.addEventListener("click", function() {
searchBar.value = "";
clearBtn.style.visibility = "hidden";
});
이 부분도 똑같이 이벤트리스너를 등록한다. 지우기 버튼을 클릭하면 검색창의 모든 텍스트를 지우고("") 지우기 아이콘 visibility의 속성값을 hidden으로 설정해 사라지게 한다.
이 부분도 가상 클래스 hover를 사용했다. 단순하게 마우스 포인터가 박스들에 올라가면 border 값을 주는 것으로 구현했다.
.additional-box a:hover {
border: 1px solid rgb(225, 225, 226);
}
지금 하고 있는 클론 코딩에서 button과 a 태그를 혼용해서 썼다. 눌러서 무언가 작용하는 것은 똑같지만 쓰이는 곳은 다를 거라고 생각했다.
눌러서 페이지의 이동이 있다면 -> a 태그
위의 경우가 아니라면 -> button 태그
위처럼 코딩하는게 올바르다고 한다. 따라서 google app 아이콘, 프로필 이미지, 지우기 아이콘은 button을 사용했고 검색창 밑 박스들은 a 태그를 사용했다.
dark, light 모드로 전환할 수 있는 버튼을 페이지 좌측 상단에 위치하게 했다.
<header>
<input type="button" class="dark-light-btn" value="dark" onclick="darkLightHandler(this)">
</header>




버튼 역시 마우스 포인팅 시 테두리 색이 변하도록 했다.
colors.js를 생성해 darkLightHandler 함수를 구현했다. Body, Logo, Header, AdditionalBox, Footer 객체를 생성하고 각 메소드를 작성해 darkLightHandler 함수에서 객체의 메소드가 실행되게 했다.
clone google 홈페이지 확인
위 링크를 통해 구현 결과를 확인할 수 있다.
코드는 아래 링크에서 확인할 수 있다.
clone google 홈페이지 github 확인