JavaScript를 사용하여 텍스트를 부모 크기에 맞게 만들기
텍스트를 부모 컨테이너로 자동 조정하는 것은 CSS만 사용하려면 거의 불가능한 작업일 수 있습니다.
이 질문의 "선호도"를 반영하기 위해 이 질문들을 살펴보면 거의 동일한 결과를 얻을 수 있습니다.
일부 도구는 자동으로 텍스트 크기를 조절할 수 있다
다행히도, 많은 일을 도와줄 수 있는 자원과 도구가 있습니다.
우리끼리 해보자.
나는 네 가지 용례를 만났는데, 나는 잠재적인 실현을 보여주고, 하나하나에 대해 추가적인 해석을 하고 싶다.
만약 당신이 어찌할 바를 모르거나, 내가 사용하는 단축키가 잘 설명되지 않은 것을 발견한다면, 개선할 수 있도록 평론을 남겨 주십시오.가장 좋은 것은 온라인 편집기, 예를 들어 jsFiddle이나CodePen이 있는데, 이 편집기를 켜서 setep을 상호작용으로 추적하는 것이다.
제가 소개하고 싶은 용례는요.
1. 높이와 폭이 고정된 용기
For this use case we simply have to check, whether the text-wrapping element (a <span>
) overflows on the height and while not, simple increase font-size by 1px.
Consider the following two panels:
<div class="parent">
<div class="text-container" data-id=1>
<span class="text">
This Text is a bit longer
and should be wrapped correctly
</span>
</div>
</div>
<div class="parent">
<div class="text-container" data-id=2>
<span class="text">
This text
</span>
</div>
</div>
Consider the following CSS for them:
.parent {
margin: 2%;
width: 300px;
height: 50px;
padding: 15px;
background: grey;
color: white;
display: block;
}
.text-container {
width: 100%;
height: 100%;
}
.text {
font-size: 12px;
display: block;
}
The default sized texts in the panels currently looks like this:
우리는 텍스트를 이용하여 용기 ((
text-container
클래스가 있는div) 의 '넘침' 을 사용할 수 있습니다.CSS를 조금 더 시각적으로 표시하려면 다음과 같이 하십시오..text-container {
border: 1px solid;
width: 100%;
height: 100%;
}
.text {
font-size: 32px;
display: block;
}
body {
background: #33A;
}
텍스트가 컨테이너에서 뚜렷하게 오버플로우되었습니다.오버플로우 계산
DOM 요소의 오버플로우를 계산할 수 있는 경우 이를 더 활용할 수 있습니다.
const isOverflown = ({ clientHeight, scrollHeight }) => scrollHeight > clientHeight
이 경우 텍스트 크기 조정 기능을 위한 알고리즘 로직을 설계할 수 있습니다.글꼴 크기를 1픽셀씩 늘린 다음 요소가 부모 요소를 넘치는지 다시 테스트할 수 있습니다.
만약 원소가 넘친다면, 이전 단계 (픽셀 하나 부족) 는 넘치지 않았기 때문에, 우리의 가장 좋은 일치입니다.
첫번째 실현
상기 논리는 원소와 부원소를 받아들여 최소값(12, 대
12px
에서 최대값(예를 들어 128)으로 교체하고 style.fontSize
속성을 현재 교체 인덱스로 설정하여 넘침이 발생할 때까지 하는 함수를 의미한다.그리고 마지막으로 교체된 색인을 다시 분배합니다.간단한 구현은 다음과 같습니다.
const resizeText = ({ element, parent }) => {
let i = 12 // let's start with 12px
let overflow = false
const maxSize = 128 // very huge text size
while (!overflow && i < maxSize) {
element.style.fontSize = `${i}px`
overflow = isOverflown(parent)
if (!overflow) i++
}
// revert to last state where no overflow happened:
element.style.fontSize = `${i - 1}px`
}
첫 번째text
요소 및 상위 요소에 대해 이 함수를 호출하면 공정한 결과가 생성됩니다.resizeText({
element: document.querySelector('.text'),
parent: document.querySelector('.text-container')
})
추가 옵션 추가
물론, 우리는 유연성을 통해 기능을 더욱 구성할 수 있기를 희망한다.
1
와는 다른 단계를 사용할 수 있음px
const isOverflown = ({ clientHeight, scrollHeight }) => scrollHeight > clientHeight
const resizeText = ({ element, elements, minSize = 10, maxSize = 512, step = 1, unit = 'px' }) => {
(elements || [element]).forEach(el => {
let i = minSize
let overflow = false
const parent = el.parentNode
while (!overflow && i < maxSize) {
el.style.fontSize = `${i}${unit}`
overflow = isOverflown(parent)
if (!overflow) i += step
}
// revert to last state where no overflow happened
el.style.fontSize = `${i - step}${unit}`
})
}
모든 .text
요소를 호출하고 정밀도를 높이기 위해 0.5
절차를 사용합니다.resizeText({
elements: document.querySelectorAll('.text'),
step: 0.5
})
그것은 최종적으로 두 가지 요소에 적용된다.2. 고정 너비와 자동 높이가 있는 용기
Consider the same html but a differnt CSS now:
body {
background: #A33;
}
.parent {
margin: 2%;
width: 150px;
height: auto;
min-height: 50px;
padding: 15px;
background: grey;
color: white;
display: block;
}
.text-container {
width: 100%;
height: 100%;
border: 1px solid;
}
.text {
font-size: 12px;
display: block;
}
The containers now have a fixed width, a minimal height but can grow dynamically ( height: auto
) if the content overflows. The yet untouched text looks like this:
우리가 수동으로 글꼴 크기를 늘리면 어떻게 되는지 봅시다.
.text {
font-size: 48px;
display: block;
}
수평 오버플로우 검사 추가
고도로 성장했지만, 우리가 지금 얻은 폭은 넘쳐흐른다.
다행히도, 우리는 조금만 수정하면 이전의 코드를 사용할 수 있다.현재 수직 오버플로우(높이 값 사용)만 확인하고 수평 오버플로우 체크만 추가하면 됩니다.
const isOverflown = ({ clientWidth, clientHeight, scrollWidth, scrollHeight }) => (scrollWidth > clientWidth) || (scrollHeight > clientHeight)
그렇습니다.결과도 지금 보기 좋다.resizeText({
elements: document.querySelectorAll('.text'),
step: 0.25
})
3. 고정 높이와 자동 너비가 있는 용기
For this case we only need to change our CSS, the functions already do their work for use here.
The default looks like so:
body {
background: #3A3;
}
.parent {
margin: 2%;
width: auto;
min-width: 50px;
height: 50px;
min-height: 50px;
padding: 15px;
background: grey;
color: white;
display: inline-block;
}
.text-container {
width: 100%;
height: 100%;
border: 1px solid;
}
.text {
font-size: 12px;
display: block;
}
글꼴 크기를 수동으로 변경하면 다음과 같은 결과가 발생합니다.
.text {
font-size: 48px;
display: block;
}
우리의 기능을 사용하여 우리는 마침내 해냈다.
resizeText({
elements: document.querySelectorAll('.text'),
step: 0.25
})
여기에는 별도의 코드가 필요 없다.🎉
4. 사용자가 크기를 조절할 수 있는 컨테이너
This is the trickiest part, but thanks to CSS3 and new web standards we can tackle it with just a few lines of extra code. Consider the following CSS:
body {
background: #333;
}
.parent {
margin: 2%;
width: 150px;
height: 150px;
padding: 15px;
background: grey;
color: white;
overflow: auto;
resize: both;
}
.text-container {
width: 100%;
height: 100%;
border: 1px solid;
display: block;
}
.text {
font-size: 12px;
display: block;
}
The resize
property allows us to resize the most upper-level parent containers:
크기 조정 기능은 본기implemented by (most) modern browsers와 용기 오른쪽 아래에 표시된 손잡이입니다.
이제 컨테이너의 크기를 자유롭게 조절할 수 있으므로 우리의 논리에 몇 가지 변화가 생겼습니다.
MutationObserver를 사용하여 변경 내용 살펴보기
관찰 부분에서 우리는 현지인Mutation Observer implementation 즉all modern browsers do support을 사용했다.
그러나 우리는
.text
에서 변화를 관찰할 수 없고 가장 바깥쪽의 용기에서만 변화를 관찰할 수 있다. 이것이 바로 우리의 예.parent
이다.또한 MutationObserver
단일 노드를 관찰해야 하기 때문에 우리는 여러 요소를 지원하기 위해 모든 .parent
용기를 교체해야 한다.const allParents = document.querySelectorAll('.parent')
allParents.forEach(parent => {
// create a new observer for each parent container
const observer = new MutationObserver(function (mutationList, observer) {
mutationList.forEach( (mutation) => {
// get the text element, see the html markup
// at the top for reference
const parent = mutation.target
const textContainer = parent.firstElementChild
const text = textContainer.firstElementChild
// resize the text
resizeText({ element: text, step: 0.5 })
});
})
// let's observe only our required attributes
observer.observe(parent, {
attributeFilter: ['style']
})
})
이것은 당시에 매우 잘했다.조심해!큰 시간을 조정하는 데 아직도 몇 가지 작은 문제가 존재한다.
서로 다른
overflow
CSS 속성을 적용하면 99.9%의 문제를 실제로 해결할 수 있습니다..parent {
margin: 2%;
width: 150px;
height: 150px;
padding: 15px;
background: grey;
color: white;
overflow-x: auto;
overflow-y: hidden;
resize: both;
}
100% 장애를 해결할 수 있는 더 좋은 방법이 있다면 다음과 같이 설명합니다. -)옵션: 스로틀 추가
전체 기능이 완성되면 throttle functionality를 추가하여
resizeText
방법에 대한 호출 횟수를 줄일 수 있습니다.const throttle = (func, timeFrame) => {
let lastTime = 0
return (...args) => {
const now = new Date()
if (now - lastTime >= timeFrame) {
func(...args)
lastTime = now
}
}
}
const throttledResize = throttle(resizeText, 25)
관찰자 중에서resizetText
:// ...
const parent = mutation.target
const textContainer = parent.firstElementChild
const text = textContainer.firstElementChild
throttledResize({ element: text, step: 0.5 })
// ...
요약
나는 텍스트의 크기를 동태적으로 조정하는 데 있어서의 첫 경험을 반영했고 사람들이 주제를 깊이 있게 이해하고 메커니즘을 이해하여 기존의 라이브러리를 평가하는 데 도움을 줄 수 있기를 바란다.
지금까지 이것은 아직 충분히 통용되는 방법이 아니어서 일률적인 해결 방안이 될 수 없다.그러나 이 글은 제3자 코드가 필요하지 않아도 실현할 수 있다는 것을 보여준다. 현대 브라우저는 이미 충분한 기능을 제공했기 때문에 약 50줄의 코드로 자신의 크기 조정 도구를 구축할 수 있다.
어떤 개선 건의도 매우 환영을 받는다. 나는 독자들이 본문에서 얻은 것이 있기를 바란다.
저자가 본문에서 사용한 자원
Reference
이 문제에 관하여(JavaScript를 사용하여 텍스트를 부모 크기에 맞게 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/jankapunkt/make-text-fit-it-s-parent-size-using-javascript-m40텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)