[css] 동적 문자 수에 따라 글꼴 크기를 반응 적으로 만드는 순수 CSS

나는 이것이 자바 스크립트로 상당히 쉽게 해결할 수 있다는 것을 알고 있지만 순수한 CSS 솔루션에만 관심이 있습니다.

텍스트가 항상 고정 된 div에 맞도록 동적으로 텍스트 크기를 조정하는 방법을 원합니다. 다음은 샘플 마크 업입니다.

<div style="width: 200px; height: 1em; overflow: hidden;">
  <p>Some sample dynamic amount of text here</p>
</div>

컨테이너의 너비를 ems로 지정하고 글꼴 크기를 가져와 해당 값을 상속하면 이것이 가능할 수 있다고 생각했습니다.



답변

방금 VW 장치를 사용하여 이것이 가능하다는 것을 알았습니다. 뷰포트 너비 설정과 관련된 단위입니다. 레거시 브라우저 지원 부족과 같은 몇 가지 단점이 있지만 사용을 진지하게 고려해야 할 사항입니다. 또한 다음과 같이 이전 브라우저에 대체를 제공 할 수 있습니다.

p {
    font-size: 30px;
    font-size: 3.5vw;
}

http://css-tricks.com/viewport-sized-typography/

https://medium.com/design-ux/66bddb327bb1


답변

CSS3 는 뷰 포트와 관련된 새로운 차원을 지원합니다. 그러나 이것은 안드로이드 <4.4에서 작동하지 않습니다

  1. 3.2vw = 뷰포트 너비의 3.2 %
  2. 3.2vh = 뷰포트 높이의 3.2 %
  3. 3.2vmin = 더 작은 3.2vw 또는 3.2vh
  4. 3.2vmax = 더 큰 3.2vw 또는 3.2vh

    body
    {
        font-size: 3.2vw;
    }

css-tricks.com / ….caniuse.com / …을 참조하십시오 .

또는

미디어 쿼리 사용. 가장 간단한 방법은 치수를 % 또는 em로 사용하는 것입니다. 기본 글꼴 크기 만 변경하면 모든 것이 변경됩니다.

@media (max-width: @screen-xs) {
    body{font-size: 10px;}
}

@media (max-width: @screen-sm) {
    body{font-size: 14px;}
}


h5{
    font-size: 1.4em;
}

치수를 % 또는 em로 사용하십시오 . 기본 글꼴 크기 만 변경하면 모든 것이 변경됩니다. 이전 버전에서는 매번 h1이 아닌 body 글꼴을 변경하거나 기본 글꼴 크기를 장치의 기본값으로 설정하고 모두 em

em, px 및 %에 대한 자세한 내용은 kyleschaeffer.com / …. 을 참조하십시오 .


답변

calc접근 방식에 관심이있을 수 있습니다 .

font-size: calc(4vw + 4vh + 2vmin);

끝난. 취향에 맞게 값을 조정할 수 있습니다.

출처 : https://codepen.io/CrocoDillon/pen/fBJxu


답변

유일한 방법은 다른 화면 크기에 대해 다른 너비를 설정하는 것이지만이 방법은 매우 정확하지 않으므로 js 솔루션을 사용해야합니다.

h1 {
    font-size: 20px;
}

@media all and (max-device-width: 720px){
    h1 {
        font-size: 18px;
    }
}

@media all and (max-device-width: 640px){
    h1 {
        font-size: 16px;
    }
}

@media all and (max-device-width: 320px){
    h1 {
        font-size: 12px;
    }
}


답변

나는 오랫동안 죽은 질문을 부활시키고 있다는 것을 알고 있지만 같은 질문이 있었고 무언가를 추가하고 싶었습니다. 이것을 금지하지 마십시오.이 답변을 정당화하는 것이 중요하다고 생각했습니다. 필요한 경우 삭제하겠습니다. @Joseph Silber는 잘못되었습니다. 실제로 모든 가능성을 코딩하는 것이 실제로 가능한 방법입니다. 그 이유는 실제로 무한한 가능성이 없기 때문입니다. 기술적으로는 있지만 방문자의 99 %가 표준 해상도를 사용합니다. 대부분의 모바일 OS가 창 크기를 조정하지 않고 전체 화면으로 앱을 실행하기 때문에 모바일 (응답 성 웹 디자인의 주된 이유)의 경우에는이 점이 사실입니다.

또한 스크롤 막대로 인해 높이는 거의 관련이 없습니다 (1, 4, 5 피트 이상인 웹 페이지는 즉시 떠날 수 있지만 대부분은 사실입니다). 너비 만 걱정하면됩니다. 그리고 실제로 코딩해야 할 폭은 240, 320, 480 (이전 iThings의 경우), 640, 800, 1024, 1280, 1440, 1600, 1920, 2048, 2560입니다. 4k, 이미지가 너무 부풀어 오르고 100 % 너비로 늘어난 2560 크기가 4k 모니터에서 잘 보입니다 (테스트했습니다). 또한 이전 포스터가 제안한대로 720 (720×480)을 신경 쓰지 마십시오. 디지털 카메라에서 거의 독점적으로 사용되는 해상도이며 매우 드문 경우입니다.

누군가가 이국적인 해상도를 사용하고 있다면 지난 15 년 동안 만들어진 거의 모든 렌더러가 반올림되므로 누군가의 화면 너비가 맞다면 말입니다. 1100, 1024 CSS 규칙을로드 할 예정이므로 사이트가 중단되지 않아야합니다. 이것은 반응 형 규칙을 불필요하게 만들려고 시도하여 이국적인 해상도를 설명합니다. 웹 브라우저를 너무 오래 사용하여 사이트를로드하지 않는 한 모든 가능한 설정을 픽셀 단위로 코딩해야한다는 생각은 어리 석습니다. 어쨌든.


답변

참고로 비 CSS 솔루션 :

아래는 컨테이너 내의 텍스트 길이에 따라 글꼴 크기를 조정하는 일부 JS입니다.

약간 수정 된 코드가 있지만 다음과 같은 아이디어가있는 코드 :

function scaleFontSize(element) {
    var container = document.getElementById(element);

    // Reset font-size to 100% to begin
    container.style.fontSize = "100%";

    // Check if the text is wider than its container,
    // if so then reduce font-size
    if (container.scrollWidth > container.clientWidth) {
        container.style.fontSize = "70%";
    }
}

나를 위해 사용자가 드롭 다운에서 선택하면 메뉴의 div가 채워집니다 (이곳에서 동적 텍스트가 발생합니다).

    scaleFontSize("my_container_div");

또한 CSS 줄임표 ( “…”)를 사용하여 더 긴 텍스트도 자릅니다 .

#my_container_div {
    width: 200px; /* width required for text-overflow to work */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

따라서 궁극적으로 :

  • 짧은 텍스트 : 예 : “APPLES”

    완전히 렌더링되고 멋진 큰 글자.

  • 긴 텍스트 : 예 : “애플 및 오렌지”

    위의 JS 스케일링 기능을 통해 70 % 축소됩니다.

  • 매우 긴 텍스트 : 예 : “APPLES & ORANGES & BANAN …”

    CSS 규칙과 함께 위의 JS 스케일링 기능을 통해 70 % 축소되고 “…”타원으로 잘립니다.

CSS 글자 간격을 사용하여 텍스트를 좁히면서 동일한 글꼴 크기를 유지하면서 탐색 할 수도 있습니다.


답변

많은 사람들이 @DMTinter의 게시물에 대한 의견에서 언급했듯이 OP는 문자 수 ( “양”)에 대해 묻고있었습니다. 그는 CSS에 대해서도 질문했지만 @Alexander가 지적했듯이 “CSS로는 불가능합니다”. 내가 알 수있는 한, 그것은 현재로서는 사실처럼 보이므로 사람들이 다음으로 가장 좋은 것을 알고 싶어하는 것이 논리적으로 보입니다.

나는 이것을 자랑스럽게 생각하지 않지만 작동합니다. 그것을 달성하기 위해 과도한 양의 코드처럼 보입니다. 이것이 핵심입니다 :

function fitText(el){
  var text = el.text();
  var fsize = parseInt(el.css('font-size'));
  var measured = measureText(text, fsize);

  if (measured.width > el.width()){
    console.log('reducing');
    while(true){
      fsize = parseInt(el.css('font-size'));
      var m = measureText(text, fsize );
      if(m.width > el.width()){
        el.css('font-size', --fsize + 'px');
      }
      else{
        break;
      }
    }
  }
  else if (measured.width < el.width()){
    console.log('increasing');
    while(true){
      fsize = parseInt(el.css('font-size'));
      var m = measureText(text, fsize);
      if(m.width < el.width()-4){ // not sure why -4 is needed (often)
        el.css('font-size', ++fsize + 'px');
      }
      else{
        break;
      }
    }
  }
}

여기 JS 빈은 다음과 같습니다 http://jsbin.com/pidavon/edit?html,css,js,console,output
(정말 텍스트를 측정하기 위해 캔버스를 사용에 관심이 아니에요 그것은 가능한 개선을 제안하십시오 … 보인다 너무 많은 오버 헤드 (?)를 좋아하십시오.

measureText 함수를위한 @Pete에게 감사합니다 :
https://stackoverflow.com/a/4032497/442665