친절한효자손 취미생활

이태원 참사에 대한 깊은 애도를 표합니다. 타인의 불행을 악용하는 사이버렉카가 되지 않겠습니다.

반응형

지난 시간에 이어 오늘도 연이어서 HTML + CSS로 카카오톡 채팅 대화창을 만들어 보겠습니다. 이전 강의에서는 프로필 아이콘을 만드는 방법에 대해 알아보았습니다. 이번에는 프사 바로 옆에 표시되는 대화창 모양을 만들어볼 것입니다. 그 전에 최종 완성본을 한번 보시고 넘어가겠습니다.

 

미리보기

이렇게 만들 것입니다.

 

See the Pen 카카오톡 채팅창 만들기 by rgy0409 (@rgy0409) on CodePen.

 

프로필 아이콘 만드는 방법은 아래의 카테고리 관련글에도 있지만 혹시 찾기 어렵거나 오류로 인해 링크가 뜨지 않는 경우를 대비해 바로 아래에도 링크를 해두겠습니다. 혹시 프사 만들기 강좌를 못 보셨다면 먼저 보시고나서 만들어 주시기 바랍니다. 내용이 이어지기 때문입니다.

 

HTML + CSS 카카오톡 채팅창 화면 만들기 1장 - 프로필 아이콘 표현하기

 

말풍선 만들기

실제 텍스트가 들어가는 말풍선을 구성하는 HTML 태그 형태는 다음과 같습니다.

 

<div class="chat ch2">
    <div class="icon"><i class="fa-solid fa-user"></i></div>
    <div class="textbox">안녕하세요. 반갑습니다.</div>
</div>

이 중에서 icon 클래스명을 가진 div는 프사 아이콘이 되며 바로 아래에 있는 textbox 클래스명을 가지는 div가 바로 대화창 형태가 됩니다.

 

<div class="textbox">안녕하세요. 반갑습니다.</div>

네. 이 부분으로 말풍선을 만들겁니다. 계획은 이렇습니다.

 

두 개의 블록 요소를 만들어 합칠 것입니다. textbox의 div가 2번이 됩니다. 그러면 1번은 뭘로 표현할 것인지에 대한 의문이 생기실 겁니다. 방법은 두 가지가 있습니다.

 

1. div 태그를 하나 더 심어서 만든다.

2. textbox 클래스명의 div에 가상요소를 만든다.

 

여기서 가장 무난한건 첫번째 방법일겁니다. 즉 textbox 클래스명의 div 앞에 또 하나의 div 태그를 마크업 하는 것입니다. 그러나 개인적으로 태그는 최소화하는게 취향이라 전 두번째 방법으로 만들기로 했습니다.

 

말풍선 기본 만들기

실제 대화인 텍스트가 들어있는 모서리가 둥근 div 박스를 만들어 줍니다. 바로 아래 부분이죠.

 

.wrap .chat .textbox {
    position: relative;
    display: inline-block;
    max-width: calc(100% - 70px);
    padding: 10px;
    margin-top: 7px;
    font-size: 13px;
    border-radius: 10px;
}

.wrap .chat .textbox::before {
    position: absolute;
    display: block;
    top: 0;
    font-size: 1.5rem;
}

이것이 말풍선의 기본 뼈대가 됩니다. 먼저 textbox 클래스명의 div가 위치 기준이 됩니다. 따라서 position: relative를 해줍니다. 또한 말풍선은 텍스트의 양에 따라 달라져야 하기에 display: inline-block 해줍니다. 인라인 속성이면 크기가 사라지기 때문에 상/하에 대한 마진이나 패딩이 먹히지 않으니까요. 또한 div의 기본값인 block 상태면 텍스트의 양과 상관 없이 늘 최대 가로 사이즈가 100%로 적용되기 때문입니다.

 

대화창의 가로 최대 사이즈를 프로필의 가로 크기와 오른쪽 마진 크기를 합친 만큼 빼줍니다. 계산해보면 70px 라는걸 알 수 있습니다. 이렇게 해야 말풍선의 가로 사이즈가 지나치게 커져서 프로필 아이콘 아래로 밀려 내려오는 현상을 막을 수 있습니다. 그렇기 때문에 그냥 width가 아닌, max-width를 사용한 것입니다. 그리고 세로값인 height를 넣지 않은 이유 또한 마찬가지입니다. 텍스트의 양에 따라 대화창의 세로 사이즈가 변해야 하기 때문이죠. 그러므로 고정으로 정할 수 없습니다. 그리고 margin-top을 넣은 이유는 다음과 같습니다.

 

이것 때문입니다. 말풍선이 조금 위쪽으로 향하고 있습니다. 그렇기에 이 부분을 조금 내려서 프로필 아이콘와 중앙정렬을 눈대중으로 얼추 맞추려고 넣은 것입니다. 사실 중앙정렬을 하는 방법은 프로필 아이콘과 말풍선의 부모 요소인 chat 클래스명을 가지는 div에 flex 해주고 세로 중앙 정렬인 align-items: center;를 마크업하면 쉽게 해결됩니다. 하지만 이렇게되면 한가지 문제가 발생합니다.

 

align-items: center를 해버렸기 때문에 텍스트의 양이 늘어나면 세로축을 중심으로 위/아래로 말풍선이 확장됩니다. 제가 원한건 이게 아니고 아래쪽으로만 늘어나는 형태입니다. 그렇기 때문에 align-center를 사용하지 않았습니다. 즉 파란색 라인은 변동이 없고 그 아래로만 텍스트의 양에 따라 말풍선이 확장되는 형태인 것입니다.

 

.wrap .chat .textbox::before 선택자는 잠시 뒤에 설명드릴 가상 요소의 기본 위치 및 크기를 정의합니다. 즉 이 선택자는 말풍선의 꼬리에 대해서 스타일을 지정하고 있습니다.

 

기본 뼈대를 만든 이유

간단합니다. 최종 완성본을 살펴보시면 실제로 대화가 오고가는 형태입니다. 왼쪽 대화, 오른쪽 대화 이런 식으로요. 보시면 왼쪽 대화창은 프사 아이콘이 왼쪽, 말풍선이 오른쪽입니다. 또한 프사가 왼쪽이기에 말풍선 꼬리가 왼쪽에 위치해 있습니다. 오른쪽 대화에는 이게 반대죠. 말풍선이 먼저 나오고 말풍선꼬리가 오른쪽, 그리고 그 오른쪽에 프로필 아이콘이 있습니다.

 

따라서 말풍선 부분에서 변하지 않는 부분은 2번의 textbox 클래스명을 갖는 div입니다. 1번 말풍선 꼬리 삼각형은 대화 상대에 따라서 왼쪽에, 또는 오른쪽에 위치해 있습니다. 최종적으로는 위의 형태처럼 되는것이며 현재 본 글에서는 첫번째 대화인 푸른색 백그라운드 형태만 살펴보기로 합니다. 순서를 바꾸는건 다음 강좌 때 언급하겠습니다. 푸른색의 ch1 클래스명을 갖는 div의 경로를 추가로 살펴보자면 아래처럼 마크업 되어있습니다.

 

.wrap .ch1 .textbox {
    margin-left: 20px;
    background-color: #ddd;
}

.wrap .ch1 .textbox::before {
    left: -15px;
    content: "◀";
    color: #ddd;
}

즉 가상 요소를 사용하되 ch1, ch2 클래스를 마크업하고 각 클래스 경로에 따라 가상요소에 사용되는 콘텐츠를 다른 모양을 사용했습니다. ch1 경로의 textbox 클래스명인 div는 프로필아이콘이 왼쪽에 있으니 margin-left로 삼각형이 들어갈 공간을 확보해 준 것입니다. ch1 경로의 textbox에 ::before 가상요소를 넣어서 absolute 위치를 왼쪽을 기준으로 -15px 만큼 이동시켰습니다. 음수이므로 왼쪽으로 이동하게 됩니다.

 

가상요소로 말꼬리 표현

가상 요소는 말그대로 HTML에 태그로 존재하지 않지만 CSS에서 가상으로 만들어낸 태그(요소)를 의미합니다. 이 부분에 대해서는 이미 자세히 글로 작성한 바 있으니 아래의 글을 참고해주시기 바랍니다.

 

CSS3 ::before ::after 가상요소 활용하여 폰트어썸 아이콘 적용시키는 방법

 

CSS3 ::before ::after 가상요소 활용하여 폰트어썸 아이콘 적용시키는 방법

폰트어썸(Font Awesome) 이라고 하는 아이콘 형태의 폰트가 있습니다. 이것을 이용하면 직관적이며 개성 넘치는 웹페이지를 구현할 수 있습니다. 이미지가 아닌 폰트로 적용되기 때문에 font-size 같

rgy0409.tistory.com

이 방법을 응용해 1번 삼각형을 만들겁니다. 그런데 삼각형은 또 어떻게 표현을 할까요? border를 활용한 삼각형 표현이 가능합니다만 이번에는 정말 쉽게 삼각형을 만들 생각입니다. 위의 CSS에서도 나와있듯 ch1 클래스명 경로에서는 ◀를 사용했고 ch2 클래스명 경로에서는 반대인 ▶를 콘텐츠로 사용했습니다. 클래스명 ch1 경로에 대한 CSS만 합쳐보면 다음과 같이 구성됩니다.

 

.wrap .chat .textbox {
    position: relative;
    display: inline-block;
    max-width: calc(100% - 70px);
    padding: 10px;
    margin-top: 7px;
    margin-left: 20px;
    border-radius: 10px;
    font-size: 13px;
    background-color: #ddd;
}

.wrap .chat .textbox::before {
    position: absolute;
    display: block;
    content: "◀";
    top: 0;
    left: -15px;
    font-size: 1.5rem;
    color: #ddd;
}

그렇습니다. 서로 대화하는 형태를 취해야하다보니 부득이하게 말풍선꼬리며 프로필사진 위치가 반대로 되어야 하는 상황이 발생했고 이로 인해서 절대 변하지 않는 CSS 스타일을 기준으로 마크업하고 변해야만 하는 스타일 코드를 별도로 클래스를 만들고 관리를 하는 방식입니다. 이 부분에 대해서는 다음 강좌 때 좀 더 자세히 말씀드리겠습니다. 이렇게해서 첫번째 말풍선 대화창 스타일이 완성되었습니다. 끝.

공유하기

facebook twitter kakaoTalk kakaostory naver band

댓글