Tỷ lệ phông chữ dựa trên chiều rộng của container


1187

Tôi đang có một thời gian khó khăn để có được đầu của tôi xung quanh tỷ lệ phông chữ.

Tôi hiện có trang web này với cơ thể font-size100%. 100% những gì mặc dù? Điều này dường như tính toán ở 16 pixel.

Tôi có ấn tượng rằng 100% bằng cách nào đó sẽ đề cập đến kích thước của cửa sổ trình duyệt, nhưng dường như không phải vì nó luôn luôn là 16 pixel cho dù cửa sổ được thay đổi kích thước xuống chiều rộng di động hay màn hình rộng toàn màn hình.

Làm cách nào tôi có thể tạo văn bản trên quy mô trang web của mình liên quan đến vùng chứa của nó? Tôi đã thử sử dụng em, nhưng điều này cũng không có quy mô.

Lập luận của tôi là những thứ như trình đơn của tôi trở nên squished khi bạn thay đổi kích thước, vì vậy tôi cần phải giảm px font-sizecủa .menuItemcác yếu tố khác liên quan đến độ rộng của thùng sơn. (Ví dụ: trong menu trên máy tính để bàn lớn, 22pxhoạt động hoàn hảo. Di chuyển xuống chiều rộng của máy tính bảng và 16pxphù hợp hơn.)

Tôi biết tôi có thể thêm các điểm dừng, nhưng tôi thực sự muốn văn bản mở rộng cũng như có thêm các điểm dừng, nếu không, tôi sẽ kết thúc với hàng trăm điểm dừng cho mỗi 100 pixel giảm chiều rộng để kiểm soát văn bản.


34
font-size: 100%;có nghĩa là 100% kích thước văn bản sẽ có (nghĩa là văn bản mà nó thừa hưởng từ cha mẹ của nó). Theo mặc định đó là 16px. Vì vậy, nếu bạn đã sử dụng 50%, nó sẽ có kích thước phông chữ: 8px
Andy

31
Những gì bạn đang tìm kiếm được gọi là kiểu chữ đáp ứng hoặc kích thước khung nhìn. css-tricks.com/viewport-sized-typography
gearsdigital

8
Cung cấp cho FitText một cái nhìn.
Patsy Issa

12
@Andy: Trên thực tế, "theo mặc định" là bất cứ điều gì người dùng có kích thước văn bản trình duyệt của họ được đặt thành, có thể không nhất thiết phải giải quyết thành 16px.
ScottS

1
hãy xem câu trả lời này stackoverflow.com/a/28485608/4251431
Basheer AL-MOMANI

Câu trả lời:


1496

EDIT: Nếu vùng chứa không phải là Thủ thuật CSS cơ thể sẽ bao gồm tất cả các tùy chọn của bạn trong Ghép văn bản vào vùng chứa .

Nếu vùng chứa là phần thân, thứ bạn đang tìm kiếm là độ dài phần trăm Viewport :

Các độ dài viewport-tỷ lệ có liên quan đến kích thước của khối chứa ban đầu . Khi chiều cao hoặc chiều rộng của khối chứa ban đầu bị thay đổi, chúng được chia tỷ lệ tương ứng. Tuy nhiên, khi giá trị tràn trên phần tử gốc là tự động, mọi thanh cuộn được cho là không tồn tại.

Các giá trị là:

  • vw (% chiều rộng của khung nhìn)
  • vh (% chiều cao của khung nhìn)
  • vi (1% kích thước khung nhìn theo hướng trục nội tuyến của phần tử gốc)
  • vb (1% kích thước khung nhìn theo hướng trục khối của phần tử gốc)
  • vmin(nhỏ hơn vwhoặc vh)
  • vmax(lớn hơn hoặc vwhoặc vh)

1 v * bằng 1% khối chứa ban đầu.

Sử dụng nó trông như thế này:

p {
    font-size: 4vw;
}

Như bạn có thể thấy, khi chiều rộng khung nhìn tăng, thì cũng vậy font-size, không cần sử dụng truy vấn phương tiện.

Các giá trị này là một đơn vị kích thước, giống như pxhoặc em, vì vậy chúng có thể được sử dụng để định kích thước cho các phần tử khác, chẳng hạn như chiều rộng, lề hoặc phần đệm.

Hỗ trợ trình duyệt khá tốt, nhưng bạn có thể sẽ cần một dự phòng, chẳng hạn như:

p {
    font-size: 16px;
    font-size: 4vw;
}

Kiểm tra số liệu thống kê hỗ trợ: http://caniuse.com/#feat=viewport-units .

Ngoài ra, hãy kiểm tra CSS-Tricks để có cái nhìn rộng hơn: Kiểu chữ có kích thước Viewport

Đây là một bài viết hay về cách đặt kích thước tối thiểu / tối đa và thực hiện kiểm soát nhiều hơn một chút đối với kích thước: Kiểm soát chính xác đối với kiểu chữ đáp ứng

Và đây là một bài viết về cài đặt kích thước của bạn bằng calc () để văn bản lấp đầy khung nhìn: http://codepen.io/CrocoDillon/pen/fBJxu

Ngoài ra, vui lòng xem bài viết này, sử dụng một kỹ thuật được gọi là "nóng chảy hàng đầu" để điều chỉnh chiều cao của dòng. Molten dẫn đầu về CSS


547
Nhưng nếu container không phải là khung nhìn (cơ thể) thì sao?
Alex

12
@Alex, đó là lãnh thổ JS. Hãy thử FitText.jsphương án được cung cấp ở cuối bài viết @jbenjohnson được cung cấp.
Robbert

10
Đây là nơi mà các truy vấn phần tử được gọi là xuất hiện. Không giống như các truy vấn phương tiện, các truy vấn phần tử sẽ kích thước mọi thứ dựa trên khối chứa của nó, chứ không phải khung nhìn, sẽ rất tuyệt vời! Nhưng thật không may, nó không tồn tại. Tuy nhiên, một số polyfill và bằng chứng khái niệm tồn tại nếu bạn quan tâm: mã hóa.smashingmagazine.com / 2013/06/25 / Giảfilamentgroup.com/lab/element_query_workaround
jbenjohnson

139
Hạ cấp vì điều này không trả lời câu hỏi. Anh hỏi về container chứ không phải khung nhìn. Trường hợp sử dụng hoàn toàn khác nhau.
SongBox

6
"Khối chứa ban đầu" đề cập đến phần tử gốc. Đây không phải là câu trả lời chính xác cho câu hỏi.
Glyph

320

Nhưng nếu container không phải là khung nhìn (cơ thể) thì sao?

Câu hỏi này được hỏi trong một bình luận của Alex dưới câu trả lời được chấp nhận .

Thực tế đó không có nghĩa là vwkhông thể được sử dụng ở một mức độ nào đó cho kích thước của container đó. Bây giờ để xem bất kỳ biến thể nào, tất cả đều phải giả định rằng container theo một cách nào đó có kích thước linh hoạt. Cho dù thông qua một tỷ lệ phần trăm trực tiếp widthhoặc thông qua việc trừ 100% lợi nhuận. Điểm sẽ trở thành "moot" nếu thùng chứa luôn được đặt thành, giả sử, 200pxrộng - sau đó chỉ cần đặt một giá trị font-sizehoạt động cho chiều rộng đó.

ví dụ 1

Tuy nhiên, với một container có chiều rộng linh hoạt, phải nhận ra rằng theo một cách nào đó, container vẫn có kích thước ngoài khung nhìn . Do đó, vấn đề là điều chỉnh vwcài đặt dựa trên sự khác biệt kích thước phần trăm đó cho chế độ xem, có nghĩa là có tính đến kích thước của trình bao bọc cha mẹ. Lấy ví dụ này :

div {
    width: 50%;
    border: 1px solid black;
    margin: 20px;
    font-size: 16px;
    /* 100 = viewport width, as 1vw = 1/100th of that
       So if the container is 50% of viewport (as here)
       then factor that into how you want it to size.
       Let's say you like 5vw if it were the whole width,
       then for this container, size it at 2.5vw (5 * .5 [i.e. 50%])
    */
    font-size: 2.5vw;
}

Giả sử ở đây divlà một đứa con của body, nó 50%100%chiều rộng đó, là kích thước khung nhìn trong trường hợp cơ bản này. Về cơ bản, bạn muốn thiết lập một vwcái nhìn sẽ tốt cho bạn. Như bạn có thể thấy trong nhận xét của tôi trong nội dung CSS ở trên, bạn có thể "nghĩ" thông qua đó về mặt toán học đối với kích thước khung nhìn đầy đủ, nhưng bạn không cần phải làm điều đó. Văn bản sẽ "uốn cong" với vùng chứa vì vùng chứa bị uốn cong với thay đổi kích thước khung nhìn. CẬP NHẬT: đây là một ví dụ về hai container có kích thước khác nhau .

Ví dụ 2

Bạn có thể giúp đảm bảo kích thước khung nhìn bằng cách buộc tính toán dựa trên đó. Xem xét ví dụ này :

html {width: 100%;} /* Force 'html' to be viewport width */
body {width: 150%; } /* Overflow the body */

div {
    width: 50%;
    border: 1px solid black;
    margin: 20px;
    font-size: 16px;
    /* 100 = viewport width, as 1vw = 1/100th of that
       Here, the body is 150% of viewport, but the container is 50%
       of viewport, so both parents factor  into how you want it to size.
       Let's say you like 5vw if it were the whole width,
       then for this container, size it at 3.75vw
       (5 * 1.5 [i.e. 150%]) * .5 [i.e. 50%]
    */
    font-size: 3.75vw;
}

Kích thước vẫn dựa trên chế độ xem, nhưng về bản chất được thiết lập dựa trên kích thước thùng chứa.

Nên thay đổi kích thước của container một cách linh hoạt ...

Nếu kích thước của phần tử container kết thúc thay đổi linh hoạt mối quan hệ tỷ lệ phần trăm của nó thông qua các @mediađiểm dừng hoặc thông qua JavaScript, thì bất kỳ "mục tiêu" cơ sở nào cũng sẽ cần tính toán lại để duy trì "mối quan hệ" tương tự cho kích thước văn bản.

Lấy ví dụ # 1 ở trên. Nếu divđược chuyển sang 25%chiều rộng bằng một trong hai @mediahoặc JavaScript, thì đồng thời, font-sizecần phải điều chỉnh trong truy vấn phương tiện hoặc bằng JavaScript để tính toán mới 5vw * .25 = 1.25. Điều này sẽ đặt kích thước văn bản ở cùng kích thước mà nó sẽ có "chiều rộng" của 50%thùng chứa ban đầu đã giảm một nửa so với kích thước khung nhìn, nhưng hiện đã bị giảm do thay đổi cách tính tỷ lệ phần trăm của chính nó.

Một thử thách

Với chức năng CSS3calc() đang được sử dụng, sẽ rất khó điều chỉnh linh hoạt, vì chức năng đó không hoạt động cho các font-sizemục đích tại thời điểm này. Vì vậy, bạn không thể thực hiện điều chỉnh CSS 3 thuần túy nếu chiều rộng của bạn thay đổi calc(). Tất nhiên, một sự điều chỉnh nhỏ về chiều rộng cho lề có thể không đủ để đảm bảo bất kỳ thay đổi nào font-size, vì vậy nó có thể không quan trọng.


(Có lỗi Chrome với độ dài phần trăm lượt xem và thay đổi kích thước cửa sổ: code.google.com/p/chromium/issues/detail?id=124331 )
ba mươi

@thentydot: Thật không may (nhưng thật tốt khi biết, cảm ơn). Hy vọng lỗi sẽ được giải quyết sớm, nhưng có vẻ như nó đã tồn tại một thời gian.
Scott

20
Tuy nhiên, câu trả lời tuyệt vời sẽ không hoạt động nếu phần tử chứa có chiều rộng tối đa.
Người lập kế hoạch

3
@KristofferNolgren: Điều đó liên quan đến hai điểm được đưa ra trong câu trả lời của tôi: (1) "giả sử rằng container theo một cách nào đó có kích thước linh hoạt" (một khi đạt được "chiều rộng tối đa", nó không còn bị uốn cong nữa, do đó sẽ xảy ra sự cố ). (2) Nếu người ta có thể xác định tại điểm 'chiều rộng tối đa' nào sẽ đạt được, thì như tôi đã lưu ý, bạn có thể đặt @mediađiểm dừng để thay đổi cách phông chữ có kích thước tại điểm đó (về cơ bản là đạt kích thước cố định khi đạt max-width) . Chỉ cần một ý nghĩ để làm việc với một max-widthtình huống.
ScottS

Bạn có nghĩ rằng bạn có thể đưa ra một câu đố khi phần tử container đang thay đổi linh hoạt thông qua các truy vấn phương tiện không? Tôi không chắc là tôi hiểu.
J82

59

Giải pháp với SVG:

<div style="width: 60px;">  
  <svg width="100%" height="100%" viewBox="0 -200 1000 300"
     xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <text font-size="300" fill="black">Text</text>
  </svg>
</div>

https://jsfiddle.net/qc8ht5eb/


Giải pháp với SVG và gói văn bản bằng cách sử dụng foreignObject:

<svg viewBox="0 0 100 100">
  <foreignObject width="100%" height="100%">
    <h1>heading</h1>

    lorem ipsum dolor sit amet
  </foreignObject>
</svg> 

https://jsfiddle.net/2rp1q0sy/


1
Ý tưởng này có vẻ tốt đẹp, lúc đầu. Sau đó, bạn nhận ra rằng bạn không thể dễ dàng kiểm soát phông chữ trên SVG bên trong <html>. Phông chữ khác nhau trên thiết bị di động và máy tính để bàn, tác động đến chiều rộng cuối cùng.
Stopi

@Stopi bạn nghĩ gì về một giải pháp iFrame? ví dụ
Dantio

10
Bạn hoàn toàn có thể tạo kiểu SVG từ HTML / CSS
gman

1
SVG có thể được tạo kiểu với css nếu svg là nội tuyến (không sử dụng thẻ img).

8
Đây là giải pháp tốt nhất, có thể dự đoán nhất được chia tỷ lệ dựa trên một thùng chứa động.
JoshuaDavid

35

Trong một trong các dự án của tôi, tôi sử dụng "hỗn hợp" giữa vw và vh để điều chỉnh kích thước phông chữ theo nhu cầu của mình, ví dụ:

font-size: calc(3vw + 3vh);

Tôi biết điều này không trả lời câu hỏi của OP, nhưng có lẽ nó có thể là một giải pháp cho bất kỳ ai khác.


3
Bạn có thể tốt hơn bằng cách sử dụng vminvà / hoặc vmaxthay vào đó.
sebastian_k

4
công cụ chrome dev gọi đây là giá trị thuộc tính không hợp lệ
phil294

31

Giải pháp Pure-CSS với calc(), các đơn vị CSS và toán học

Đây chính xác không phải là những gì OP yêu cầu, nhưng có thể làm cho một ngày của ai đó. Câu trả lời này không dễ ăn bằng thìa và cần một số nghiên cứu về kết thúc của nhà phát triển.

Cuối cùng tôi đã đến để có được một giải pháp CSS thuần cho việc này bằng calc()các đơn vị khác nhau. Bạn sẽ cần một số hiểu biết toán học cơ bản về các công thức để tìm ra biểu thức của bạn calc().

Khi tôi làm việc này, tôi phải nhận được một tiêu đề đáp ứng có chiều rộng toàn trang với một vài phần đệm trong DOM. Tôi sẽ sử dụng các giá trị của tôi ở đây, thay thế chúng bằng giá trị của riêng bạn.

Đến toán học

Bạn sẽ cần:

  • Tỷ lệ điều chỉnh độc đáo trong một số khung nhìn. Tôi đã sử dụng 320 pixel, do đó tôi có chiều cao 24 pixel và chiều rộng 224 pixel, vì vậy tỷ lệ này là 9.333 ... hoặc 28/3
  • Chiều rộng của container, tôi có padding: 3emvà chiều rộng đầy đủ vì vậy điều này phải100wv - 2 * 3em

X là chiều rộng của vùng chứa, vì vậy hãy thay thế nó bằng biểu thức của riêng bạn hoặc điều chỉnh giá trị để có được văn bản toàn trang. Rlà tỷ lệ bạn sẽ có. Bạn có thể lấy nó bằng cách điều chỉnh các giá trị trong một số khung nhìn, kiểm tra chiều rộng và chiều cao của phần tử và thay thế chúng bằng các giá trị của riêng bạn. Ngoài ra, nó là width / heigth;)

x = 100vw - 2 * 3em = 100vw - 6em
r = 224px/24px = 9.333... = 28 / 3

y = x / r
  = (100vw - 6em) / (28 / 3)
  = (100vw - 6em) * 3 / 28
  = (300vw - 18em) / 28
  = (75vw - 4.5rem) / 7

Và đập! Nó đã làm việc! tôi đã viết

font-size: calc((75vw - 4.5rem) / 7)

với tiêu đề của tôi và nó đã điều chỉnh độc đáo trong mọi chế độ xem.

Nhưng làm thế nào nó hoạt động?

Chúng ta cần một số hằng số ở đây. 100vwcó nghĩa là toàn bộ chiều rộng của khung nhìn và mục tiêu của tôi là thiết lập tiêu đề toàn chiều rộng với một số phần đệm.

Tỉ lệ. Có được chiều rộng và chiều cao trong một khung nhìn giúp tôi có một tỷ lệ để chơi và với tỷ lệ này tôi biết chiều cao của chiều rộng khung nhìn khác là bao nhiêu. Tính toán chúng bằng tay sẽ tốn nhiều thời gian và ít nhất là mất nhiều băng thông, vì vậy đó không phải là một câu trả lời hay.

Phần kết luận

Tôi tự hỏi tại sao không ai tìm ra điều này và một số người thậm chí còn nói rằng điều này sẽ không thể sửa đổi bằng CSS. Tôi không muốn sử dụng JavaScript trong việc điều chỉnh các yếu tố, vì vậy tôi không chấp nhận các câu trả lời của JavaScript (và quên đi jQuery) mà không cần đào sâu thêm. Nói chung, thật tốt khi điều này đã được tìm ra và đây là một bước để triển khai CSS thuần túy trong thiết kế trang web.

Tôi xin lỗi về bất kỳ quy ước bất thường nào trong văn bản của tôi, tôi không phải là người bản ngữ bằng tiếng Anh và cũng khá mới để viết câu trả lời Stack Overflow.

Cũng cần lưu ý rằng chúng ta có các thanh cuộn ác trong một số trình duyệt. Ví dụ: khi sử dụng Firefox tôi nhận thấy điều đó 100vwcó nghĩa là toàn bộ chiều rộng của chế độ xem, mở rộng dưới thanh cuộn (nơi nội dung không thể mở rộng!), Vì vậy văn bản toàn băng thông phải được đặt lề cẩn thận và tốt nhất là nên thử nghiệm với nhiều trình duyệt và thiết bị.


13
Giải pháp này chỉ hoạt động NẾU (1) bạn biết phông chữ và (2) phông chữ có sẵn trên thiết bị của người dùng và (3) văn bản luôn giống nhau. Điều này làm cho nó một trường hợp sử dụng rất hạn chế.
Andrei Volgin

tôi không hiểu điều gì xảy ra nếu container của tôi được sửa chữa với ví dụ: 640px và tỷ lệ 16: 9. Tôi nên viết những calcs nào?
pery mimon

1
Chiều rộng vùng chứa của bạn xlà 640px và tỷ lệ r16: 9, vì vậy: x = 640px, r = 16 / 9, y = x / r = 640px / (16 / 9) = 360px
hegez

Lưu ý: điều này chỉ hoạt động nếu bạn thực sự có một văn bản có kích thước 16: 9, đây là một tình huống kỳ lạ. Có lẽ đọc câu trả lời lần thứ hai có thể giúp đỡ. Ngoài ra, điều này chỉ hoạt động cho một lớp lót.
bá chủ

Thành thật mà nói, bạn không giải thích "Tỷ lệ được điều chỉnh chính xác trong một số chế độ xem. Tôi đã sử dụng 320 pixel, do đó tôi có chiều cao 24 pixel và chiều rộng 224 pixel, vì vậy tỷ lệ này là 9.333 ... hoặc 28/3" Tôi khuyên bạn nên giải thích tỷ lệ này thêm chút nữa. Tỷ lệ này thể hiện điều gì?
3limin4t0r

28

Có một triết lý lớn cho vấn đề này.

Cách dễ nhất để làm là cung cấp một kích thước phông chữ nhất định cho thân máy (tôi khuyên dùng 10), và sau đó tất cả các yếu tố khác sẽ có phông chữ của chúng trong emhoặc rem. Tôi sẽ cho bạn một ví dụ để hiểu các đơn vị đó. Emluôn luôn liên quan đến cha mẹ của nó:

body{font-size: 10px;}
.menu{font-size: 2em;} /* That means 2*10 pixels  = 20 pixels */
.menu li{font-size: 1.5em;} /* That means 1.5*20 pixels = 30 pixels */

Rem luôn luôn tương đối với cơ thể:

body{font-size: 10px;}
.menu{font-size: 2rem;} /* That means 2*10 pixels = 20 pixels */
.menu li{font-size: 1.5rem;} /* that means 1.5*10 pixels = 15 pixels */

Và sau đó, bạn có thể tạo một tập lệnh sẽ sửa đổi kích thước phông chữ tương ứng với chiều rộng vùng chứa của bạn. Nhưng đây không phải là những gì tôi muốn giới thiệu. Bởi vì trong một container có chiều rộng 900 pixel chẳng hạn, bạn sẽ có mộtp phần tử có cỡ chữ 12 pixel, giả sử. Và theo ý tưởng của bạn, nó sẽ trở thành một thùng chứa rộng 300 pixel với cỡ chữ 4 pixel. Phải có một giới hạn thấp hơn.

Các giải pháp khác sẽ là với các truy vấn phương tiện, để bạn có thể đặt phông chữ cho các độ rộng khác nhau.

Nhưng các giải pháp mà tôi muốn giới thiệu là sử dụng thư viện JavaScript giúp bạn thực hiện điều đó. Và fittext.js mà tôi tìm thấy cho đến nay.


6
Các remđơn vị liên quan đến các yếu tố gốc, có nghĩa là htmlphần tử, không phải là bodyphần tử. Phần tử gốc trong DOM là htmlthẻ. developer.mozilla.org/en-US/docs/Web/CSS/length .. remluôn liên quan đến htmlthẻ, là thành phần gốc, không phải thẻ cơ thể .. nhưng câu trả lời hay :)
Jonathan Marzullo

fittext.js làm cho công việc được thực hiện, tôi đã đề xuất giải pháp đó!
Jacek Dziurdzikowski

FitText là người chiến thắng cho tôi. Đã thử một vài lựa chọn thay thế nhưng điều này có vẻ đơn giản nhất và cũng được tích hợp tốt với Drupal / backdrop CMS. github.com/davatron5000/FitText.js
Joel phụ trợ

23

Đây là chức năng:

document.body.setScaledFont = function(f) {
  var s = this.offsetWidth, fs = s * f;
  this.style.fontSize = fs + '%';
  return this
};

Sau đó chuyển đổi tất cả các kích thước phông chữ phần tử con của tài liệu của bạn emthành hoặc %.

Sau đó thêm một cái gì đó như thế này vào mã của bạn để đặt kích thước phông chữ cơ sở.

document.body.setScaledFont(0.35);
window.onresize = function() {
    document.body.setScaledFont(0.35);
}

http://jsfiddle.net/0tpvccjt/


1
Cho đến nay, đây là giải pháp tốt nhất
Nhanh nhẹn

Thực tiễn tồi và kém hiệu quả
Jack Giffin

@tntrox Không hiệu quả như ngày nay, nó kém hiệu quả hơn 4 năm trước. Tôi từ chối câu trả lời này thay cho các lựa chọn thay thế tốt hơn nhiều. Có, để hỗ trợ IE, người ta sẽ cần Javascript. Nhưng, người ta không cần Javascript, điều này thật tồi tệ.
Jack Giffin

3
Tôi đoán sự thiếu hiểu biết của tôi đang hiển thị ở đây. Nhưng TẠI SAO là khủng khiếp ở trên?

Tôi không nghĩ nó tệ. Tôi muốn đề xuất một số thay đổi định dạng nhỏ để dễ đọc hơn. Tôi sẽ đặt mỗi var trên một dòng riêng biệt ít nhất. Nó có thể không cần thiết return thisở cuối chức năng. Đối với hiệu suất, bạn cũng có thể muốn gỡ bỏ kích thước để nó không được vẽ lại khi bạn kéo. Đó là một số mã khá đơn giản, vì vậy ai đó có thể dựa vào giải pháp cải tiến của họ với nó với ít nỗ lực.
Mnebuerquo

19

Có một cách để làm điều này mà không cần JavaScript!

Bạn có thể sử dụng một hình ảnh SVG nội tuyến. Bạn có thể sử dụng CSS trên một SVG nếu nó là nội tuyến. Bạn phải nhớ rằng sử dụng phương pháp này có nghĩa là hình ảnh SVG của bạn sẽ đáp ứng với kích thước vùng chứa của nó.

Hãy thử sử dụng giải pháp sau đây ...

HTML

<div>
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360.96 358.98" >
      <text>SAVE $500</text>
  </svg>
</div>

CSS

div {
  width: 50%; /* Set your container width */
  height: 50%; /* Set your container height */

}

svg {
  width: 100%;
  height: auto;

}

text {
  transform: translate(40px, 202px);
  font-size: 62px;
  fill: #000;
}

Ví dụ: https://jsfiddle.net/k8L4xLLa/32/

Muốn một cái gì đó hào nhoáng hơn?

Hình ảnh SVG cũng cho phép bạn làm những thứ tuyệt vời với hình dạng và rác. Kiểm tra trường hợp sử dụng tuyệt vời này cho văn bản có thể mở rộng ...

https://jsfiddle.net/k8L4xLLa/14/


4
Giải pháp này không khác gì giải pháp được chấp nhận với vwkích thước. nếu bạn thay đổi văn bản, mọi thứ sẽ vượt ra khỏi ràng buộc.
N69S

14

Điều này có thể không thực tế lắm, nhưng nếu bạn muốn một phông chữ là chức năng trực tiếp của cha mẹ, mà không có bất kỳ JavaScript nào nghe / vòng lặp (khoảng) để đọc kích thước của div / trang, có một cách để làm điều đó . Iframes.

Bất cứ điều gì trong iframe sẽ coi kích thước của iframe là kích thước của khung nhìn. Vì vậy, mẹo là chỉ tạo một iframe có chiều rộng là chiều rộng tối đa bạn muốn văn bản của mình và chiều cao của nó bằng chiều cao tối đa * tỷ lệ khung hình của văn bản cụ thể.

Đặt giới hạn sang một bên là các đơn vị khung nhìn cũng không thể đi cùng với các đơn vị cha mẹ cho văn bản (như trong, có kích thước% hoạt động như mọi người khác), các đơn vị khung nhìn cung cấp một công cụ rất mạnh: có thể có kích thước tối thiểu / tối đa . Bạn không thể làm điều đó ở bất cứ nơi nào khác - bạn không thể nói ... làm cho chiều cao của div này là chiều rộng của cha mẹ * một cái gì đó.

Điều đó đang được nói, mẹo là sử dụng vmin và đặt kích thước iframe sao cho [phân số] * tổng chiều cao là kích thước phông chữ tốt khi chiều cao là kích thước giới hạn và [phân số] * tổng chiều rộng khi chiều rộng là giới hạn kích thước. Đây là lý do tại sao chiều cao phải là một sản phẩm của chiều rộng và tỷ lệ khung hình.

Ví dụ cụ thể của tôi, bạn có

.main iframe{
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  height: calc(3.5 * 100%);
  background: rgba(0, 0, 0, 0);
  border-style: none;
  transform: translate3d(-50%, -50%, 0);
}

Khó chịu nhỏ với phương pháp này là bạn phải tự thiết lập CSS của iframe. Nếu bạn đính kèm toàn bộ tệp CSS, điều đó sẽ chiếm rất nhiều băng thông cho nhiều vùng văn bản. Vì vậy, những gì tôi làm là đính kèm quy tắc mà tôi muốn trực tiếp từ CSS của mình.

var rule = document.styleSheets[1].rules[4];
var iDoc = document.querySelector('iframe').contentDocument;
iDoc.styleSheets[0].insertRule(rule.cssText);

Bạn có thể viết hàm nhỏ có quy tắc CSS / tất cả các quy tắc CSS sẽ ảnh hưởng đến vùng văn bản.

Tôi không thể nghĩ ra một cách khác để làm điều đó mà không cần phải đi xe đạp / nghe JavaScript. Giải pháp thực sự sẽ là cho các trình duyệt cung cấp một cách để chia tỷ lệ văn bản thành một chức năng của bộ chứa chính cũng cung cấp chức năng loại vmin / vmax tương tự.

JSFiddle: https://jsfiddle.net/0jr7rrgm/3/ (nhấp một lần để khóa hình vuông màu đỏ cho chuột và nhấp lại để phát hành)

Hầu hết các JavaScript trong fiddle chỉ là chức năng kéo chuột tùy chỉnh của tôi.


@quemished Không phải vậy khi chúng tôi mang thuộc tính 'mới''sáng bóng' (trống xin vui lòng ...) srcdoc: jsfiddle.net/wauzgob6/3
Jack Giffin

9

Sử dụng vw, em& đồng. hoạt động chắc chắn, nhưng IMO nó luôn cần một cú chạm của con người để tinh chỉnh.

Đây là một kịch bản tôi vừa viết dựa trên câu trả lời @ tnt-rox ' cố gắng tự động hóa cảm ứng của con người:

$('#controller').click(function(){
    $('h2').each(function(){
        var
            $el = $(this),
            max = $el.get(0),
            el = null
        ;
        max =
            max
            ? max.offsetWidth
            : 320
        ;
        $el.css({
            'font-size': '1em',
            'display': 'inline',
        });
        el = $el.get(0);

        el.get_float = function(){
            var
                fs = 0
            ;
            if (this.style && this.style.fontSize) {
                fs = parseFloat(this.style.fontSize.replace(/([\d\.]+)em/g, '$1'));
            }
            return fs;
        };

        el.bigger = function(){
            this.style.fontSize = (this.get_float() + 0.1) + 'em';
        };

        while (el.offsetWidth < max) {
            el.bigger();
        }

        // Finishing touch.
        $el.css({
            'font-size': ((el.get_float() -0.1) +'em'),
            'line-height': 'normal',
            'display': '',
        });
    });  // end of (each)
});    // end of (font scaling test)
div {
  width: 50%;
  background-color: tomato;
  font-family: 'Arial';
}

h2 {
  white-space: nowrap;
}

h2:nth-child(2) {
  font-style: italic;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="button" id="controller" value="Apply" />
<div>
  <h2>Lorem ipsum dolor</h2>
  <h2>Test String</h2>
  <h2>Sweet Concatenation</h2>
  <h2>Font Scaling</h2>
</div>

Về cơ bản, nó giảm kích thước phông chữ xuống 1emvà sau đó bắt đầu tăng thêm 0,1 cho đến khi đạt đến chiều rộng tối đa.

Câu đố


1
+1 chỉ dành cho ai đó thừa nhận rằng emscần có sự tiếp xúc của con người và nhịp điệu dọc không phải là một loại phép thuật.
huyết thanh

7

100% liên quan đến kích thước phông chữ cơ sở, nếu bạn không đặt nó, sẽ là mặc định tác nhân người dùng của trình duyệt.

Để đạt được hiệu quả mà bạn theo đuổi, tôi sẽ sử dụng một đoạn mã JavaScript để điều chỉnh kích thước phông chữ cơ sở so với kích thước cửa sổ.


7

Trong CSS của bạn, hãy thử thêm phần này ở phía dưới thay đổi độ rộng 320 pixel cho bất cứ nơi nào thiết kế của bạn bắt đầu phá vỡ:

    @media only screen and (max-width: 320px) {

        body { font-size: 1em; }

    }

Sau đó cung cấp kích thước phông chữ trong "px" hoặc "em" như bạn muốn.


7

Giải pháp của riêng tôi, dựa trên jQuery, hoạt động bằng cách tăng dần kích thước phông chữ cho đến khi vùng chứa tăng chiều cao lớn (có nghĩa là nó bị đứt dòng).

Nó khá đơn giản, nhưng hoạt động khá tốt, và nó rất dễ sử dụng. Bạn không cần phải biết bất cứ điều gì về phông chữ đang được sử dụng, mọi thứ đều được trình duyệt quan tâm.

Bạn có thể chơi với nó trên http://jsfiddle.net/tubededentifrice/u5y15d0L/2/

Điều kỳ diệu xảy ra ở đây:

var setMaxTextSize=function(jElement) {
    // Get and set the font size into data for reuse upon resize
    var fontSize=parseInt(jElement.data(quickFitFontSizeData)) || parseInt(jElement.css("font-size"));
    jElement.data(quickFitFontSizeData, fontSize);

    // Gradually increase font size until the element gets a big increase in height (i.e. line break)
    var i = 0;
    var previousHeight;
    do
    {
        previousHeight=jElement.height();
        jElement.css("font-size", "" + (++fontSize) + "px");
    }
    while(i++ < 300 && jElement.height()-previousHeight < fontSize/2)

    // Finally, go back before the increase in height and set the element as resized by adding quickFitSetClass
    fontSize -= 1;
    jElement.addClass(quickFitSetClass).css("font-size", "" + fontSize + "px");

    return fontSize;
};

1
Vì tập lệnh này sẽ chạy trên mọi sự kiện thay đổi kích thước và / hoặc thay đổi hướng, tôi không khuyên bạn nên sử dụng tập lệnh này. Thay vì sử dụng giải pháp dựa trên javascript, hãy tìm giải pháp dựa trên css như được đưa ra ở trên.
Pilatus

1
Thay đổi kích thước và định hướng là những sự kiện "hiếm", không có vấn đề về hiệu suất ở đây. Nếu bạn thích, đừng liên kết với các sự kiện (nếu họ không thay đổi kích thước các container chẳng hạn, cho các trang web không phản hồi). Các giải pháp CSS không hoạt động trong mọi trường hợp mà không phải suy nghĩ bất cứ điều gì (như độ rộng của phông chữ hoặc như vậy) như giải pháp này.
Vincent

Tôi gói câu trả lời của bạn dưới dạng hàm jQuery. Nó nhận được kích thước phông chữ tối đa, tối thiểu và tối đa cho phép. Xem jsfiddle.net/oriadam/qzsy760k
oriadam

6

Thành phần web này thay đổi kích thước phông chữ để chiều rộng văn bản bên trong khớp với chiều rộng vùng chứa. Kiểm tra bản demo .

Bạn có thể sử dụng nó như thế này:

<full-width-text>Lorem Ipsum</full-width-text>


6

Tôi đã chuẩn bị một hàm tỷ lệ đơn giản bằng cách sử dụng biến đổi CSS thay vì cỡ chữ. Bạn có thể sử dụng nó bên trong bất kỳ vùng chứa nào, bạn không phải đặt truy vấn phương tiện, v.v. :)

Bài đăng trên blog: Tiêu đề có thể mở rộng CSS & JS toàn chiều rộng

Mật mã:

function scaleHeader() {
  var scalable = document.querySelectorAll('.scale--js');
  var margin = 10;
  for (var i = 0; i < scalable.length; i++) {
    var scalableContainer = scalable[i].parentNode;
    scalable[i].style.transform = 'scale(1)';
    var scalableContainerWidth = scalableContainer.offsetWidth - margin;
    var scalableWidth = scalable[i].offsetWidth;
    scalable[i].style.transform = 'scale(' + scalableContainerWidth / scalableWidth + ')';
    scalableContainer.style.height = scalable[i].getBoundingClientRect().height + 'px';
  }
}

Bản demo hoạt động: https://codepen.io/maciejkorsan/pen/BWLryj


Tôi nghĩ rằng OP đang tìm kiếm một giải pháp CSS.
m02ph3u5

5

Sử dụng biến CSS

Chưa ai đề cập đến các biến CSS và cách tiếp cận này phù hợp nhất với tôi, vì vậy:

Giả sử bạn đã có một cột trên trang của mình bằng 100% chiều rộng màn hình của người dùng di động, nhưng có max-width800px, vì vậy trên máy tính để bàn có một khoảng trống ở hai bên của cột. Đặt cái này ở đầu trang của bạn:

<script> document.documentElement.style.setProperty('--column-width', Math.min(window.innerWidth, 800)+'px'); </script>

Và bây giờ bạn có thể sử dụng biến đó (thay vì vwđơn vị tích hợp) để đặt kích thước phông chữ của bạn. Ví dụ

p {
  font-size: calc( var(--column-width) / 100 );
}

Đây không phải là một cách tiếp cận CSS thuần túy , nhưng nó khá gần gũi.


5

Hãy thử http://simplef Focus.com/flowtype/ . Đây là những gì tôi sử dụng cho các trang web của mình và nó đã hoạt động hoàn hảo.


Liên kết rất dễ bay hơi. Hãy giải thích các giải pháp trực tiếp trong câu trả lời của bạn. Ngoài ra, tôi không muốn nhấp vào một số liên kết ngẫu nhiên với bất kỳ nội dung nào.
lilalinux

5

Vấn đề của tôi là tương tự, nhưng liên quan đến việc chia tỷ lệ văn bản trong một tiêu đề. Tôi đã thử Fit Font, nhưng tôi cần chuyển đổi máy nén để có bất kỳ kết quả nào, vì nó đang giải quyết một vấn đề hơi khác, như Text Flow.

Vì vậy, tôi đã viết plugin nhỏ của riêng mình để giảm kích thước phông chữ cho vừa với thùng chứa, giả sử bạn có overflow: hiddenwhite-space: nowrapvì vậy ngay cả khi giảm phông chữ xuống mức tối thiểu cũng không cho phép hiển thị tiêu đề đầy đủ, nó chỉ cắt bỏ những gì nó có thể hiển thị.

(function($) {

  // Reduces the size of text in the element to fit the parent.
  $.fn.reduceTextSize = function(options) {
    options = $.extend({
      minFontSize: 10
    }, options);

    function checkWidth(em) {
      var $em = $(em);
      var oldPosition = $em.css('position');
      $em.css('position', 'absolute');
      var width = $em.width();
      $em.css('position', oldPosition);
      return width;
    }

    return this.each(function(){
      var $this = $(this);
      var $parent = $this.parent();
      var prevFontSize;
      while (checkWidth($this) > $parent.width()) {
        var currentFontSize = parseInt($this.css('font-size').replace('px', ''));
        // Stop looping if min font size reached, or font size did not change last iteration.
        if (isNaN(currentFontSize) || currentFontSize <= options.minFontSize ||
            prevFontSize && prevFontSize == currentFontSize) {
          break;
        }
        prevFontSize = currentFontSize;
        $this.css('font-size', (currentFontSize - 1) + 'px');
      }
    });
  };
})(jQuery);

5

Về mặt nghệ thuật, nếu bạn cần điều chỉnh hai hoặc nhiều dòng văn bản trong cùng một chiều rộng bất kể số lượng ký tự của chúng thì bạn có các tùy chọn đẹp.

Tốt nhất là tìm một giải pháp năng động để bất kỳ văn bản nào được nhập vào, chúng tôi sẽ có một màn hình đẹp.

Hãy xem cách chúng ta có thể tiếp cận.

var els     = document.querySelectorAll(".divtext"),
refWidth    = els[0].clientWidth,
refFontSize = parseFloat(window.getComputedStyle(els[0],null)
                               .getPropertyValue("font-size"));

els.forEach((el,i) => el.style.fontSize = refFontSize * refWidth / els[i].clientWidth + "px")
#container {
  display: inline-block;
  background-color: black;
  padding: 0.6vw 1.2vw;
}
.divtext {
  display: table;
  color: white;
  font-family: impact;
  font-size: 4.5vw;
}
<div id="container">
  <div class="divtext">THIS IS JUST AN</div>
  <div class="divtext">EXAMPLE</div>
  <div class="divtext">TO SHOW YOU WHAT</div>
  <div class="divtext">YOU WANT</div>
</div>

Tất cả những gì chúng ta làm là lấy chiều rộng ( els[0].clientWidth) và kích thước phông chữ ( parseFloat(window.getComputedStyle(els[0],null).getPropertyValue("font-size"))) của dòng đầu tiên làm tham chiếu và sau đó chỉ cần tính kích thước phông chữ tiếp theo cho phù hợp.


4

Hãy thử sử dụng plugin fitText , vì kích thước Viewport không phải là giải pháp cho vấn đề này.

Chỉ cần thêm thư viện:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>

Và thay đổi kích thước phông chữ cho chính xác bằng cách cài đặt hệ số của văn bản:

$("#text_div").fitText(0.8);

Bạn có thể đặt giá trị tối đa và tối thiểu của văn bản:

$("#text_div").fitText(0.8, { minFontSize: '12px', maxFontSize: '36px' });

Điều này chỉ hữu ích cho văn bản hiển thị lớn và không được khuyến nghị cho các đoạn văn.
Shiv

3

Hãy nhìn vào mã của tôi. Nó làm font size smallercho fitbất cứ điều gì ở đó.

Nhưng tôi nghĩ điều này không dẫn đến trải nghiệm người dùng tốt

var containerWidth = $("#ui-id-2").width();
var items = $(".quickSearchAutocomplete .ui-menu-item");
var fontSize = 16;

items.each(function(){
    // Displaying a value depends sometimes on your case. You may make it block or inline-table instead of inline-block or whatever value that make the div take overflow width.
    $(this).css({"whiteSpace": "nowrap", "display": "inline-block"});
    while ($(this).width() > containerWidth){
         console.log("$(this).width()" + $(this).width() + "containerWidth" + containerWidth)
         $(this).css("font-size", fontSize -= 0.5);
    }
});

Kết quả


2

Là một dự phòng JavaScript (hoặc giải pháp duy nhất của bạn), bạn có thể sử dụng plugin jQuery Scalem của tôi , cho phép bạn chia tỷ lệ tương đối với phần tử cha (bộ chứa) bằng cách chuyển referencetùy chọn.


2

Trong trường hợp nó hữu ích cho bất kỳ ai, hầu hết các giải pháp trong chuỗi này đều gói văn bản thành nhiều dòng, dưới dạng e.

Nhưng sau đó tôi đã tìm thấy cái này và nó đã hoạt động:

https://github.com/chunksnbits/jquery-quickfit

Ví dụ sử dụng:

$('.someText').quickfit({max:50,tolerance:.4})


2

Luôn có yếu tố của bạn với thuộc tính này:

JavaScript: element.style.fontSize = "100%";

hoặc là

CSS: style = "font-size: 100%;"

Khi bạn đi toàn màn hình, bạn đã có một biến tỷ lệ được tính (tỷ lệ> 1 hoặc tỷ lệ = 1). Sau đó, trên toàn màn hình:

document.body.style.fontSize = (scale * 100) + "%";

Nó hoạt động độc đáo với ít mã.


2

Đối với văn bản động, plugin này khá hữu ích:

http://freqdec.github.io/slabText/

Chỉ cần thêm CSS:

.slabtexted .slabtext
{
    display: -moz-inline-box;
    display: inline-block;
    white-space: nowrap;
}
.slabtextinactive .slabtext
{
    display: inline;
    white-space: normal;
    font-size: 1em !important;
    letter-spacing: inherit !important;
    word-spacing: inherit !important;
    *letter-spacing: normal !important;
    *word-spacing: normal !important;
}
.slabtextdone .slabtext
{
    display: block;
}

Và kịch bản:

$('#mydiv').slabText();

2

Điều này làm việc cho tôi:

Tôi cố gắng ước tính kích thước phông chữ dựa trên chiều rộng / chiều cao có được từ cài đặt `font-size: 10px`. Về cơ bản, ý tưởng là "nếu tôi có chiều rộng 20 pixel và chiều cao 11 pixel với` font-size: 10px`, vậy thì kích thước phông chữ tối đa để tính toán cho một thùng chứa có chiều rộng 50 pixel và chiều cao 30 pixel là gì? "

Câu trả lời là một hệ thống tỷ lệ kép:

{20: 10 = 50: X, 11: 10 = 30: Y} = {X = (10 * 50) / 20, Y = (10 * 30) / 11}

Bây giờ X là cỡ chữ sẽ khớp với chiều rộng và Y là cỡ chữ sẽ khớp với chiều cao; lấy giá trị nhỏ nhất

function getMaxFontSizeApprox(el){
    var fontSize = 10;
    var p = el.parentNode;

    var parent_h = p.offsetHeight ? p.offsetHeight : p.style.pixelHeight;
    if(!parent_h)
        parent_h = 0;

    var parent_w = p.offsetHeight ? p.offsetWidth : p.style.pixelWidth;
    if(!parent_w)
        parent_w = 0;

    el.style.fontSize = fontSize + "px";

    var el_h = el.offsetHeight ? el.offsetHeight : el.style.pixelHeight;
    if(!el_h)
        el_h = 0;

    var el_w = el.offsetHeight ? el.offsetWidth : el.style.pixelWidth;
    if(!el_w)
        el_w = 0;

    // 0.5 is the error on the measure that JavaScript does
    // if the real measure had been 12.49 px => JavaScript would have said 12px
    // so we think about the worst case when could have, we add 0.5 to 
    // compensate the round error
    var fs1 = (fontSize*(parent_w + 0.5))/(el_w + 0.5);
    var fs2 = (fontSize*(parent_h) + 0.5)/(el_h + 0.5);

    fontSize = Math.floor(Math.min(fs1,fs2));
    el.style.fontSize = fontSize + "px";
    return fontSize;
}

NB: đối số của hàm phải là phần tử span hoặc phần tử nhỏ hơn cha mẹ của nó, nếu không, nếu con và cha mẹ có cả hàm chiều rộng / chiều cao giống nhau sẽ không thành công.



1

Để làm cho kích thước phông chữ phù hợp với thùng chứa của nó, thay vì cửa sổ, hãy xem resizeFont()chức năng tôi đã chia sẻ trong câu hỏi này (kết hợp các câu trả lời khác, hầu hết trong số đó đã được liên kết ở đây). Nó được kích hoạt bằng cách sử dụng window.addEventListener('resize', resizeFont);.

Vanilla JavaScript: Thay đổi kích thước phông chữ tuyệt vời để vừa với thùng chứa

JavaScript:

function resizeFont() {
  var elements  = document.getElementsByClassName('resize');
  console.log(elements);
  if (elements.length < 0) {
    return;
  }
  _len = elements.length;
  for (_i = 0; _i < _len; _i++) {
    var el = elements[_i];
    el.style.fontSize = "100%";
    for (var size = 100; el.scrollHeight > el.clientHeight; size -= 10) {
      el.style.fontSize = size + '%';
    }
  }
}

Có lẽ bạn có thể sử dụng vw / vh như một dự phòng, vì vậy bạn tự động gán emhoặcrem đơn vị sử dụng JavaScript, đảm bảo rằng các phông chữ sẽ mở rộng ra cửa sổ nếu JavaScript bị tắt.

Áp dụng .resizelớp cho tất cả các thành phần có chứa văn bản bạn muốn được thu nhỏ.

Kích hoạt chức năng trước khi thêm cửa sổ thay đổi kích thước trình nghe sự kiện. Sau đó, bất kỳ văn bản nào không phù hợp với vùng chứa của nó sẽ được thu nhỏ lại khi tải trang, cũng như khi nó được thay đổi kích thước.

LƯU Ý: Giá trị mặc định font-sizephải được thiết lập để một trong hai em, remhoặc %để đạt được kết quả đúng.


1

HTML

<div style="height:100px; width:200px;">
  <div id='qwe'>
    test
  </div>
</div>

Mã JavaScript để tối đa hóa kích thước phông chữ:

var fontSize, maxHeight, maxWidth, textElement, parentElement;
textElement = document.getElementById('qwe');
parentElement = textElement.parentElement;    
maxHeight = parentElement.clientHeight;
maxWidth = parentElement.clientWidth;
fontSize = maxHeight;
var minFS = 3, maxFS = fontSize;
while (fontSize != minFS) {
  textElement.style.fontSize = `${fontSize}px`;
  if (textElement.offsetHeight < maxHeight && textElement.offsetWidth <= maxWidth) {
    minFS = fontSize;
  } else{
    maxFS = fontSize;
  }
  fontSize = Math.floor((minFS + maxFS)/2);
}
textElement.style.fontSize = `${minFS}px`;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.