프론트엔드

[프론트엔드] (해결중) after 요소 height 조절 (참조하는 원 요소가 2줄 이상일 때)

KyuminKim 2024. 1. 9. 21:21

목표

HTML, CSS, Javascript를 이용해 타이핑 효과를 주는 웹사이트를 

https://www.youtube.com/watch?v=e56H5n1SvEs&list=PL-eeIUD86IjSyxTbGT7wY3Hie_HA5bKvg&index=1 

이 영상을 참고해 만들고 있었다.

타이핑 효과

 

이때, 문구가 2줄 이상이 넘어가면 커서 효과도 같이 height가 늘어난다는 것을 알 수 있다.

 

싫다!

나는 문구(Welcome to 1006lem's Blog!)가 2줄이 넘어가면,

커서효과도 마지막 줄(2번째 줄)에만 적용되었으면 좋겠다.

 

즉, 내가 원하는 모습은 다음과 같다.

커서효과 2번째 줄에만

 

 


상황/문제

주요한 html코드는 다음과 같다.

<body>
    <div class="blog">
        <p id = "dynamic" class="cursor"></p>
        <p class="small-text"> 
            <a href="https://github.com/1006lem" target="_blank">1006lem | github </a>
        </p>
    </div>
    <!-- 생략 -->
</body>

 

 

글씨는 <p id=dynamic class="cursor">로 지정했고,

let target = document.querySelector("#dynamic"); 
target.textContent = "Welcome to 1006lem's Blog!"

 

커서효과는 글씨의 가상 classafter로 지정했다.

이를 통해 글씨의 바로 오른쪽에 커서효과가 위치하도록 했다.

커서 효과의 위치, 색을 지정하는 css코드는 다음과 같다.

/* 가상 요소 (class)인 after 생성 */
#dynamic::after{
    content:"";
    display: blockblack;
    position: absolute;
    background-color: white;
    height: 100%;
    right: -10;
    top: 0;
    width: 4px;
}

 

 

자동 줄바꿈

자동 줄바꿈이 일어나는 이유는 뭘까?

#dynamic{
    position: static;
    /*block tag에서 속성 변화*/
    display: inline-block;
}

 

http://www.kunwi.co.kr/style/584 이 블로그가 도움이 되었는데,

해당 코드를

#dynamic{
    position: static;
    /*block tag에서 속성 변화*/
    display: inline-block;
    white-space: nowrap;
}

이렇게 white-space: norwap을 추가하면 자동 줄바꿈이 일어나지 않는다 !

 

나의 경우에는, #dynamic에 크기를 지정하지 않았으므로

(부모인 blog 또한 크기를 지정하지 않았으므로)

잘리진 않고, 전에는 2줄이 되었던 것이 옆으로 길어지기만 한다 ! 

(물론 웹사이트 가로폭보다 길어지면 잘릴 것이다)

white-space: nowrap

 

자동으로 줄바꿈이 일어나는 이유는, 기본값이 normal (줄바꿈)이기 때문이다.

 

 


시도 1

가상요소 after의 height를 글씨 하나의 height만큼으로 고정한다.

 이렇게 했는데, 

시도 1

after 요소 (마우스 커서) 위치가 아래로 내려오지 않는다 !

javascript 코드를 이용해 after 요소(마우스 커서)의 높이(top)를  동적으로 조정해야 한다 생각했다. (-> 시도 2)

 


시도 2 (작동 O)

- 가상요소 after의 height를 글씨 하나의 height만큼으로 고정한다. (시도 1)
- 가상요소 after의 top를 동적으로 변경한다.

after의 top를 변수로 생성해야 한다. 

즉, css코드 안에 존재하는 top 값을 변수로 생성해야 한다!

 

css코드를 다음과 같이 수정하여, --after-height 라는 이름의 custom property를 생성한다

/* 가상 요소 (class)인 after 생성 */
#dynamic::after{
    content:"";
    display: blockback;
    position: absolute;
    background-color: white;
    height: 2rem;
    right: -10;
    top: var(--after-top, 0px);
    padding-top: 0px; 
    width: 4px;
}

 

 

 

jQuery

이때, gpt에게 질문하니.. jQuery 사용을 추천해줬다.

 

- javascript 라이브러리

- DOM객체 접근 가능(css style로, id나 class값을 부여하지 않아도 간단하게 위치 찾을 수 있음), 뛰어난 DOM 구조탐색 

- 크로스 브라우징 (브라우저 간 호환성 보장)

 

등등의 기능이 있다고 한다. 

 

나의 경우에는 DOM 객체에 잘 접근하고, --after-top 변수를 잘 접근하는 용도로 사용했다.

 

한 줄 늘어날 때마다 26 px씩 이동

/* 커서 위치 이동 */
function updateAfterTop() {
    var lineHeight = parseInt(window.getComputedStyle(target).height);
    const oneLineHeight = 2 * parseFloat(getComputedStyle(document.documentElement).fontSize); // 기본 2rem

    // 줄 수 계산
    var numberOfLines = Math.floor(lineHeight / oneLineHeight);
    //console.log(numberOfLines)

    console.log($("#dynamic").css('--after-top'))
    if (numberOfLines >= 2) {
    	// 26 이라는 명확한 숫자 지정 (직접 조절)
        $("#dynamic").css('--after-top', numberOfLines * 26 + 'px');

    } else {
        $("#dynamic").css('--after-top', '0px');
    }
}

잘 작동한다 !

 

(26이라는 숫자는 딱히 중요한 의미를 갖진 않고,

아무 숫자나 넣어봤는데 '2rem의 글씨에 대해 1줄이 늘어날 때마다 26PX을 추가하면 보기 좋다' 라는걸 경험적으로 알게 된 것이다.)

 

 

추가적으로, 웹사이트의 크기를 늘리거나/줄일 때에도 바로바로 커서 위치를 변경시키기 위해

/* 웹사이트 크기 변경 시 커서 위치 변경 */
$(window).resize(function(){
    updateAfterTop();
})

해당 코드도 추가한다.

 

 


시도 3 (작동 O, 해결 중)

시도 2는 분명 동작한다.

하지만 우아하지 않다. 26px이라는 한 줄당 픽셀수를 직접 입력했기 때문이다.

 

그렇다면 26대신 직접 계산해서 넣자.

 

이를 위해 javascript 코드를 조금 수정한다.

 

/* 커서 위치 이동 */
function updateAfterTop() {
    var lineHeight = parseInt(window.getComputedStyle(target).height);
    const oneLineHeight = 2 * parseFloat(getComputedStyle(document.documentElement).fontSize); // 기본 2rem

    // 줄 수 계산
    var numberOfLines = Math.floor(lineHeight / oneLineHeight);

    if (numberOfLines >= 2) {
        $("#dynamic").css('--after-top', oneLineHeight * (numberOfLines-1) + 'px');

    } else {
        $("#dynamic").css('--after-top', '0px');
    }
    // console.log(numberOfLines*3);
}

 

어라, 그런데 다음과 같이 나온다.

 

이유는 줄바꿈이 일어날 때의 추가 픽셀을 고려하지 않았기 때문이다.

 

줄바꿈의 픽셀

.cursor{
    font-size: 2rem;
    font-weight: bold;
    margin-bottom: 5px;
    overflow: hidden;
}

margin-bottom을 보면 5픽셀로 잡혀있다 !!

그래서 자바스크립트 코드를 아래처럼 수정했는데 ... 여전히 올바르지 않다 !!!

if (numberOfLines >= 2) {
	$("#dynamic").css('--after-top', oneLineHeight * (numberOfLines-1) + 5 + 'px');

}

줄바꿈의 픽셀은 좀 더 알아보기로 한다 .....

우선 임의로 줄바꿈의 픽셀은 이것저것 넣어 해결할 수 있다.