Pertanyaan Penskalaan huruf berdasarkan lebar wadah


Saya mengalami kesulitan untuk memahami skala font.

Saya saat ini punya situs ini dengan tubuh font-size 100%. 100% dari apa? Ini tampaknya menghitung pada 16px.

Saya mendapat kesan bahwa 100% akan entah bagaimana mengacu pada ukuran jendela browser, tetapi tampaknya bukan karena selalu 16px apakah jendela diubah ukurannya menjadi lebar seluler atau desktop layar lebar penuh ledak.

Bagaimana saya bisa membuat teks pada skala situs saya dalam kaitannya dengan wadahnya? Saya mencoba menggunakan em tapi ini tidak skala juga.

Alasan saya adalah hal-hal seperti menu saya menjadi rusak ketika Anda mengubah ukuran, jadi saya harus mengurangi px font-size dari .menuItem di antara unsur-unsur lain dalam kaitannya dengan lebar wadah. (Misalnya di menu pada desktop besar, 22px berfungsi sempurna. Turun ke lebar tablet dan 16px lebih sesuai.)

Saya sadar saya dapat menambahkan breakpoint, tapi saya benar-benar ingin teks untuk skala sebagai BAIK memiliki tambahan breakpoint, jika tidak, saya akan berakhir dengan ratusan breakpoints untuk setiap penurunan 100px lebar untuk mengontrol teks.


808
2018-04-17 09:37


asal


Jawaban:


EDIT: Jika wadahnya bukan badan Trik CSS mencakup semua opsi Anda di sini: https://css-tricks.com/fitting-text-to-a-container/

Jika wadah adalah tubuh, apa yang Anda cari adalah Panjang persentase viewport:

Itu persentase viewport-panjang relatif terhadap ukuran blok yang mengandung awal. Ketika tinggi atau lebar blok yang mengandung awal berubah, mereka diskalakan sesuai. Namun, ketika nilai limpahan pada elemen root adalah otomatis, setiap bilah gulir dianggap tidak ada.

Nilai-nilainya adalah:

  • vw (% dari lebar viewport)
  • vh (% dari ketinggian viewport)
  • vi (1% dari ukuran viewport dalam arah sumbu inline elemen root)
  • vb (1% dari ukuran viewport dalam arah sumbu blok elemen root)
  • vmin (yang lebih kecil dari vw atau vh)
  • vmax (lebih besar atau vw atau vh)

1 v * sama dengan 1% dari blok yang mengandung awal.

menggunakannya terlihat seperti ini:

p {
    font-size: 4vw;
}

Seperti yang Anda lihat, ketika lebar viewport meningkat, begitu juga ukuran font, tanpa perlu menggunakan kueri media.

Nilai-nilai ini adalah unit ukuran, sama seperti px atau em, sehingga mereka dapat digunakan untuk mengukur elemen lain juga, seperti lebar, margin, atau padding.

Dukungan browser cukup bagus, tetapi Anda mungkin akan membutuhkan fallback, seperti:

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

Lihat statistik dukungan: http://caniuse.com/#feat=viewport-units.

Juga, periksa CSS-Trik untuk tampilan yang lebih luas: http://css-tricks.com/viewport-sized-typography/

Berikut ini artikel yang bagus tentang pengaturan ukuran min / max dan melatih sedikit lebih banyak kontrol atas ukuran: http://madebymike.com.au/writing/precise-control-responsive-typography/

Dan inilah artikel tentang pengaturan ukuran Anda menggunakan calc () sehingga teks mengisi viewport: http://codepen.io/CrocoDillon/pen/fBJxu

Juga, silakan lihat artikel ini, yang menggunakan teknik yang dijuluki 'memimpin leleh' untuk menyesuaikan tinggi garis juga. https://css-tricks.com/molten-leading-css/


1172
2017-11-06 14:40



Tetapi bagaimana jika wadah tersebut bukan viewport (tubuh)?

Pertanyaan ini diminta dalam komentar oleh Alex di bawah jawaban yang diterima.

Kenyataan itu tidak berarti vw tidak dapat digunakan sampai batas tertentu untuk ukuran wadah itu. Sekarang untuk melihat variasi apa pun, seseorang harus berasumsi bahwa wadah itu dalam beberapa hal memiliki ukuran yang fleksibel. Baik melalui persentase langsung width atau melalui 100% minus margin. Intinya menjadi "diperdebatkan" jika kontainer selalu disetel ke, katakanlah, 200px lebar - lalu setel a font-size yang berfungsi untuk lebar itu.

Contoh 1

Dengan wadah lebar yang fleksibel, bagaimanapun, harus disadari bahwa dalam beberapa cara wadah tersebut masih berukuran dari viewport. Dengan demikian, ini adalah masalah penyesuaian a vw pengaturan didasarkan bahwa perbedaan ukuran persentase ke viewport, yang berarti mempertimbangkan ukuran pembungkus orang tua. Ambil contoh ini:

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; 
}

Diasumsikan di sini div adalah anak dari body, ini 50% dari itu 100% lebar, yang merupakan ukuran viewport dalam kasus dasar ini. Pada dasarnya, Anda ingin mengatur vw itu akan terlihat baik untukmu. Seperti yang Anda lihat dalam komentar saya di css di atas, Anda dapat "berpikir" melalui matematis itu sehubungan dengan ukuran viewport penuh, tetapi Anda tidak perlu untuk melakukannya. Teks akan "flex" dengan wadah, karena wadah melenturkan dengan perubahan ukuran viewport. MEMPERBARUI: inilah contoh dua wadah berukuran berbeda.

Contoh 2

Anda dapat membantu memastikan ukuran viewport dengan memaksa perhitungan berdasarkan itu. Pertimbangkan contoh ini:

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 200% 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; 
}

Ukurannya masih berdasarkan viewport, tetapi pada dasarnya diatur berdasarkan ukuran kontainer itu sendiri.

Haruskah Ukuran dari Container Ubah Secara Dinamis ...

Jika ukuran elemen kontainer akhirnya mengubah secara dinamis hubungan persentasenya baik melalui @media break point atau melalui javascript, maka apapun "target" basisnya akan membutuhkan perhitungan ulang untuk mempertahankan "hubungan" yang sama untuk ukuran teks.

Ambil Contoh # 1 di atas. Jika itu div dialihkan ke 25% lebar dengan baik @media atau javascript, lalu pada saat yang sama, font-size perlu menyesuaikan baik dalam permintaan media atau dengan javascript ke perhitungan baru 5vw * .25 = 1.25. Ini akan menempatkan ukuran teks pada ukuran yang sama itu akan memiliki "lebar" dari aslinya 50% kontainer dikurangi setengahnya dari ukuran tampilan, tetapi sekarang telah berkurang karena perubahan dalam perhitungan persentase sendiri.

Sebuah tantangan

Dengan CSS3 calc() fungsi sedang digunakan, akan menjadi sulit untuk menyesuaikan secara dinamis, karena fungsi itu tidak berfungsi font-sizetujuan saat ini. Jadi Anda tidak bisa melakukan penyesuaian CSS3 murni jika lebar Anda berubah calc(). Tentu saja, penyesuaian kecil lebar untuk margin mungkin tidak cukup untuk menjamin perubahan apa pun font-size, jadi itu tidak masalah.


249
2017-11-06 16:56



Apa yang saya lakukan di salah satu proyek saya adalah "campuran" antara vw dan vh untuk menyesuaikan ukuran font dengan kebutuhan saya, mis .:

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

Saya tahu ini tidak menjawab pertanyaan op, tapi mungkin itu bisa menjadi solusi bagi orang lain.


21
2018-03-11 08:30



Ada filosofi besar untuk masalah ini. Hal termudah untuk dilakukan adalah memberikan ukuran font tertentu ke badan (saya memberi rekomendasi ulang 10), dan kemudian semua elemen lain akan memiliki font di em atau rem. Saya akan memberi Anda dan contoh untuk memahami unit-unit itu. Em selalu relatif terhadap orang tuanya

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

Rem selalu relatif terhadap tubuh

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

Dan daripada Anda dapat membuat skrip yang akan memodifikasi ukuran font relatif terhadap lebar penampung Anda. Tapi ini bukan apa yang saya sarankan. Karena dalam wadah lebar 900px misalnya Anda akan memiliki p elemen dengan ukuran font 12px katakanlah. Dan pada ideea Anda yang akan menjadi pada wadah lebar 300px pada ukuran font 4px. Harus ada batas yang lebih rendah. Solusi lain adalah dengan kueri media, sehingga Anda dapat menetapkan font untuk lebar yang berbeda.

Tetapi solusi yang saya sarankan adalah menggunakan pustaka javascript yang membantu Anda dengan itu. Dan fittext.js yang saya temukan sejauh ini.


20
2017-11-11 10:01



Solusi dengan 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/


19
2018-06-18 16:47



Diperbarui karena saya mendapat suara rendah.

Inilah fungsinya:

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

Kemudian konversikan semua ukuran font elemen anak Anda ke em atau%.

Kemudian tambahkan sesuatu seperti ini ke kode Anda untuk mengatur ukuran font dasar.

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

http://jsfiddle.net/0tpvccjt/


18
2018-01-07 09:43



Ini mungkin tidak terlalu praktis, tetapi jika Anda ingin font menjadi fungsi langsung dari induknya, tanpa memiliki JS yang mendengarkan / loop (interval) untuk membaca ukuran div / halaman, ada cara untuk melakukannya. Iframes. Apa pun dalam iframe akan mempertimbangkan ukuran iframe sebagai ukuran viewport. Jadi, triknya adalah hanya membuat iframe yang lebarnya adalah lebar maksimum yang Anda inginkan untuk teks Anda, dan yang tingginya sama dengan tinggi maksimum * rasio aspek teks tertentu.

Mengesampingkan batasan bahwa unit viewport tidak dapat juga datang bersama unit induk untuk teks (seperti dalam, memiliki ukuran% berperilaku seperti orang lain), unit viewport menyediakan alat yang sangat kuat: mampu mendapatkan dimensi min / max . Anda tidak bisa melakukan itu di tempat lain - Anda tidak bisa mengatakan ... membuat tinggi div ini menjadi lebar dari induk * sesuatu.

Yang sedang berkata, triknya adalah menggunakan vmin, dan untuk mengatur ukuran iframe sehingga [fraksi] * tinggi total adalah ukuran font yang baik ketika tinggi adalah dimensi pembatas, dan [fraksi] * lebar total ketika lebar adalah membatasi dimensi. Inilah sebabnya mengapa heats harus menjadi produk dari lebar dan aspek rasio.

untuk contoh khusus saya, Anda punya

.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);
}

Gangguan kecil dengan metode ini adalah Anda harus mengatur CSS dari iframe secara manual. Jika Anda melampirkan seluruh file CSS, itu akan memakan banyak bandwidth untuk banyak bidang teks. Jadi, yang saya lakukan adalah melampirkan aturan yang saya inginkan langsung dari CSS saya.

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

Anda dapat menulis fungsi kecil yang mendapatkan aturan CSS / semua aturan CSS yang akan mempengaruhi area teks.

Saya tidak dapat memikirkan cara lain untuk melakukannya tanpa memiliki JS bersepeda / mendengarkan. Solusi sebenarnya adalah untuk browser untuk menyediakan cara untuk skala teks sebagai fungsi dari wadah induk DAN juga menyediakan fungsionalitas vmin / vmax yang sama.

JS fiddle: https://jsfiddle.net/0jr7rrgm/3/ (klik sekali untuk mengunci kotak merah ke mouse, klik lagi untuk melepaskan)

Sebagian besar JS dalam biola hanyalah fungsi klik-tarik khusus saya


12
2018-04-12 19:22



Solusi Pure-CSS dengan calc(), Unit CSS dan matematika

Ini bukan apa yang OP minta, tetapi mungkin membuat hari seseorang. Jawaban ini tidak mudah menyuap dan perlu diteliti di bagian pengembang.

Saya akhirnya mendapatkan solusi CSS murni untuk penggunaan ini calc() dengan unit berbeda. Anda akan memerlukan beberapa pemahaman matematika dasar tentang rumus untuk melatih ekspresi Anda calc().

Ketika saya menyelesaikan masalah ini, saya harus mendapatkan header responsif lebar-halaman penuh dengan beberapa orang tua di DOM. Saya akan menggunakan nilai-nilai saya di sini, ganti dengan nilai Anda sendiri.

Untuk matematika

Anda akan perlu:

  • rasio yang disesuaikan dengan baik di beberapa viewport, saya menggunakan 320px, sehingga saya mendapat tinggi 24px dan lebar 224px sehingga rasio 9,333 ... atau 28/3
  • lebar kontainer, saya punya padding: 3em dan lebar penuh jadi ini harus 100wv - 2 * 3em

X adalah lebar wadah jadi ganti dengan ekspresi Anda sendiri atau sesuaikan nilainya untuk mendapatkan teks halaman penuh. R adalah rasio yang akan Anda miliki. Anda bisa mendapatkannya dengan menyesuaikan nilai di beberapa viewport, memeriksa lebar dan tinggi elemen dan menggantinya dengan nilai Anda sendiri. Juga, ini 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

Dan bang! Itu berhasil! saya menulis

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

ke header saya dan itu disesuaikan dengan baik di setiap viewport.

Tapi bagaimana cara kerjanya?

Kami butuh beberapa konstanta di sini. 100vw berarti lebar penuh viewport, dan tujuan saya adalah membuat header lebar penuh dengan beberapa padding.

Rasio. Mendapatkan lebar dan tinggi dalam satu viewport membuat saya memiliki rasio untuk bermain dengan, dan dengan rasio saya tahu berapa tinggi seharusnya dalam lebar viewport lainnya. Menghitungnya dengan tangan akan memakan banyak waktu dan setidaknya mengambil banyak bandwidth jadi itu bukan jawaban yang bagus.

Kesimpulan

Saya bertanya-tanya mengapa tidak ada yang mengetahui hal ini dan beberapa orang bahkan mengatakan bahwa ini tidak mungkin untuk mengotak-atik CSS. Saya tidak suka menggunakan Javascript dalam menyesuaikan elemen, jadi saya tidak menerima JS atau bahkan jawaban jQuery tanpa menggali lebih banyak. Semua dalam semua, itu baik bahwa ini sudah tahu dan ini adalah salah satu langkah untuk implementasi CSS murni dalam desain situs web.

Saya mohon maaf atas konvensi yang tidak biasa dalam teks saya, saya bukan penutur asli bahasa Inggris dan juga cukup baru untuk menulis jawaban SO.

Edit: itu juga harus dicatat bahwa kami memiliki scrollbar jahat di beberapa browser. Misalnya, ketika menggunakan Firefox, saya memperhatikannya 100vw berarti lebar penuh viewport, membentang di bawah scrollbar (di mana konten tidak dapat diperluas!), sehingga teks lebar harus dimiringkan dengan hati-hati dan sebaiknya diuji dengan banyak browser dan perangkat.


12
2017-09-01 10:27



Ada cara untuk melakukan ini TANPA javascript!

Anda dapat menggunakan svg inline. Anda dapat menggunakan css pada svg jika inline. Anda harus ingat bahwa menggunakan metode ini berarti svg Anda akan merespons ukuran penampungnya.

Coba gunakan solusi berikut ...

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;

}

contoh: https://jsfiddle.net/k8L4xLLa/32/

Ingin sesuatu yang lebih mencolok?

SVG juga memungkinkan Anda untuk melakukan hal-hal keren dengan bentuk dan sampah. Lihat contoh penggunaan hebat ini untuk teks skalabel ...

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


10
2018-03-13 15:48