[프론트엔드] (해결중) after 요소 height 조절 (참조하는 원 요소가 2줄 이상일 때)
목표
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번째 줄)에만 적용되었으면 좋겠다.
즉, 내가 원하는 모습은 다음과 같다.
상황/문제
주요한 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!"
커서효과는 글씨의 가상 class인 after로 지정했다.
이를 통해 글씨의 바로 오른쪽에 커서효과가 위치하도록 했다.
커서 효과의 위치, 색을 지정하는 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줄이 되었던 것이 옆으로 길어지기만 한다 !
(물론 웹사이트 가로폭보다 길어지면 잘릴 것이다)
자동으로 줄바꿈이 일어나는 이유는, 기본값이 normal (줄바꿈)이기 때문이다.
시도 1
가상요소 after의 height를 글씨 하나의 height만큼으로 고정한다.
이렇게 했는데,
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');
}
줄바꿈의 픽셀은 좀 더 알아보기로 한다 .....
우선 임의로 줄바꿈의 픽셀은 이것저것 넣어 해결할 수 있다.