Kabın genişliğine göre yazı tipi ölçeklendirme


1187

Yazı tipini ölçeklendirmek için kafamı zorlaştırıyorum

Şu anda % 100 bir gövdeye sahip bu sitem var font-size. 100% ne olsa? Bu 16 piksel olarak hesaplanıyor gibi görünüyor.

% 100'ün bir şekilde tarayıcı penceresinin boyutunu ifade edeceği izlenimindeydim, ancak görünüşe göre, pencerenin mobil genişliğe veya tam gelişmiş geniş ekran masaüstüne yeniden boyutlandırılması her zaman 16 piksel değil.

Sitemdeki metni kapsayıcıyla ilişkili olarak nasıl yapabilirim? Kullanmayı denedim em, ama bu da ölçeklenmiyor.

Benim akıl yeniden boyutlandırmak zaman azaltmak gerekir yani benim menüsü gibi bu işler, ezilmiş haline olduğu px font-sizebir .menuItemkabın genişliğine göre diğer elemanlar arasında. (Örneğin, büyük bir masaüstündeki menüde 22pxmükemmel çalışır. Tablet genişliğine gidin ve 16pxdaha uygundur.)

Ben kesme noktaları ekleyebilir farkındayım, ama gerçekten ölçeğine metin olarak istediğiniz zamanda her 100pixels metni kontrol etmek genişliğinde azalma için aksi takdirde, kesme noktaları yüzlerce bitireceğiz gibi olan ekstra kesme noktaları.


34
font-size: 100%;metnin büyüklüğünün% 100'ü anlamına gelir (ör. üst öğesinden miras aldığı). Varsayılan olarak bu 16 pikseldir. Eğer% 50 kullanırsanız, yazı tipi boyutu olurdu: 8px
Andy

31
Aradığınıza duyarlı veya görünüm alanı boyutlu tipografi denir. css-tricks.com/viewport-sized-typography
gearsdigital

8
Ver FitText bir göz.
Patsy Issa

12
@Andy: Aslında, "varsayılan olarak" kullanıcıların tarayıcı metin boyutu her ne olursa olsun 16px olarak çözülmeyebilir.
ScottS

Yanıtlar:


1496

DÜZENLE: Kapsayıcı gövde değilse CSS Tricks bir konteynere metin sığdırmak için tüm seçeneklerinizi kapsar .

Kap gövdeyse , aradığınız şey Viewport yüzdesi uzunluklarıdır :

Görünüm, yüzdeli uzunlukları büyüklüğüne bağlı olan ilk taşıyıcı blok . İlk içeren bloğun yüksekliği veya genişliği değiştirildiğinde, bunlar uygun şekilde ölçeklenir. Ancak, kök öğedeki taşma değeri otomatik olduğunda, kaydırma çubuklarının var olmadığı varsayılır.

Değerler:

  • vw (görünüm alanı genişliğinin yüzdesi)
  • vh (görünüm yüksekliğinin yüzdesi)
  • vi (Kök öğenin satır içi ekseni yönünde görünüm boyutunun% 1'i)
  • vb (Kök öğenin blok ekseni yönünde görünüm boyutunun% 1'i)
  • vmin(küçük vwya da vh)
  • vmax(daha büyük veya vwveya vh)

1 v *, başlangıçtaki bloğun% 1'ine eşittir.

Bunu kullanmak şöyle görünür:

p {
    font-size: 4vw;
}

Gördüğünüz gibi, görüntü alanı genişliği arttığında, font-sizemedya sorguları kullanmanıza gerek kalmadan da.

Bu değerler, tıpkı pxveya gibi bir boyutlandırma birimidir, embu nedenle genişlik, kenar boşluğu veya dolgu gibi diğer öğeleri de boyutlandırmak için kullanılabilirler.

Tarayıcı desteği oldukça iyi, ancak muhtemelen bir yedeklemeye ihtiyacınız olacak:

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

Destek istatistiklerine göz atın: http://caniuse.com/#feat=viewport-units .

Ayrıca, daha geniş bir görünüm için CSS-Tricks'e göz atın: Viewport Sized Tipografi

Minimum / maksimum boyutları ayarlama ve boyutlar üzerinde biraz daha fazla kontrol kullanma hakkında güzel bir makale: Duyarlı tipografi üzerinde hassas kontrol

Ve işte, calc () kullanarak boyutunuzu ayarlamakla ilgili bir makale, böylece metin görüntüyü doldurur: http://codepen.io/CrocoDillon/pen/fBJxu

Ayrıca, satır yüksekliğini de ayarlamak için 'erimiş kurşun' adlı bir teknik kullanan bu makaleye bakınız. CSS'de Erimiş Lider


547
Peki ya konteyner görüntü alanı (gövde) değilse?
Alex

12
@Alex, bu JS bölgesi. FitText.js@Jbenjohnson sağlanan makalenin altındaki sağlanan alternatif deneyin .
Robbert

10
Bu, sözde öğe sorgularının devreye girdiği yerdir. Medya sorgularının aksine, öğe sorguları, şaşırtıcı olan görünüm penceresine değil, şeyleri içerdiği bloğa göre boyutlandırır! Ama maalesef henüz mevcut değil. Bununla birlikte, ilgileniyorsanız bazı çoklu dolgular ve kavram kanıtları mevcuttur: coding.smashingmagazine.com/2013/06/25/… ve filamentgroup.com/lab/element_query_workarounds
jbenjohnson

139
Bu soruya cevap vermediği için indirildi. Kapsayıcıyı sordu, manzarayı değil. Tamamen farklı kullanım durumu.
SongBox

6
"başlangıçtaki blok", kök elemanı ifade eder. Bu, sorulan soruya doğru cevap değil.
Glif

320

Peki ya konteyner görüntü alanı (gövde) değilse?

Bu soru kabul edilen cevap altında Alex tarafından bir yorumda sorulur .

Bu gerçek, vwbu konteynır için bir ölçüde kullanılamayacağı anlamına gelmez . Şimdi hepsinde herhangi bir varyasyon görmek için, kabın bir şekilde esnek boyutta olduğunu varsaymak gerekir. İster doğrudan yüzde, ister width% 100 eksi marjlar olsun. Kap her zaman geniş olarak ayarlanmışsa, nokta "tartışma" haline gelir 200px- diyelim ki genişlik - font-sizeo genişlik için çalışan bir a ayarlayın .

örnek 1

Bununla birlikte, esnek genişlikli bir kapla, kabın bir şekilde yine de görünümden boyutlandırıldığı anlaşılmalıdır . Bu nedenle, vwgörünümün yüzde boyut farkını temel alan bir ayarı ayarlamak meselesidir , bu da üst sargıların boyutlarını dikkate almak anlamına gelir. Bu örneği ele alalım :

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

Burada varsayarsak divbir çocuktur body, öyle 50%Bunun 100%bu temel durumda viewport boyutudur genişliği. Temel olarak, size vwiyi görünecek bir tane ayarlamak istersiniz. Yukarıdaki CSS içeriğindeki yorumumda görebileceğiniz gibi, bunu tam görüntüleme alanı boyutuna göre matematiksel olarak "düşünebilirsiniz", ancak bunu yapmanız gerekmez . Kap, görünüm alanı yeniden boyutlandırılarak esnediğinden, metin kapla "esneyecek". GÜNCELLEME: işte iki farklı boyutta konteynır örneği .

ÖRNEK 2

Buna dayalı hesaplamayı zorlayarak görünüm alanı boyutlandırmasının sağlanmasına yardımcı olabilirsiniz. Bu örneği düşünün :

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

Boyutlandırma hala görüntüleme alanına dayanmaktadır, ancak özünde konteyner boyutunun kendisine göre kurulmuştur.

Konteynerin Boyutu Dinamik Olarak Değişirse ...

Kap öğesinin boyutlandırılması, @mediakesme ilişkisiyle veya JavaScript aracılığıyla yüzde ilişkisini dinamik olarak değiştirirse , temel "hedef" ne olursa olsun, metin boyutlandırması için aynı "ilişkiyi" korumak için yeniden hesaplama gerekir.

Yukarıdaki # 1 örneğini ele alalım. Eğer divaktanlmıştır 25%ya genişlik @mediaveya JavaScript, daha sonra, aynı zamanda, font-sizeyeni hesaplama için her iki ortam sorgu ya da JavaScript tarafından ayarlamak gerekir 5vw * .25 = 1.25. Bu, metin boyutunu orijinal 50%kabın "genişliğinin" görüntü alanı boyutundan yarı yarıya azaltılmış olacağı boyuta getirecektir , ancak şimdi kendi yüzde hesaplamasındaki bir değişiklik nedeniyle azalmıştır.

Meydan okuma

İle CSS3 calc()fonksiyonu kullanımda, bu işlev için çalışmıyor gibi dinamik ayarlamak zor olacaktı font-sizebu zamanda amaçları. Böylece genişliğiniz değişiyorsa saf bir CSS 3 ayarlaması yapamazsınız calc(). Tabii ki, kenar boşlukları için küçük bir genişlik ayarı, herhangi bir değişikliği garanti etmek için yeterli font-sizeolmayabilir, bu yüzden önemli olmayabilir.


(Görünüm yüzdesi uzunlukları olan ve pencereyi yeniden boyutlandıran bir Chrome hatası var: code.google.com/p/chromium/issues/detail?id=124331 )
otuz nokta

@ thirtydot: Bu talihsiz (ama farkında olmak güzel, teşekkürler). Umarım hata yakında çözülür, ancak bir süredir devam ediyor gibi görünüyor.
ScottS

20
Bununla birlikte, harika yanıt, içeren elemanın maksimum genişliğe sahip olması durumunda işe yaramaz.
Himmators

3
@KristofferNolgren: Bu, cevabımda verilen iki nokta ile ilgilidir: (1) "kabın bir şekilde esnek boyutta olduğu varsayılarak" ('maksimum genişliğe' ulaşıldığında, artık esner, bu yüzden bir sorun var ). (2) 'maksimum genişliğe' hangi noktaya ulaşılacağını belirleyebilirseniz, daha önce de belirttiğim gibi @media, yazı tipinin o noktada nasıl boyutlandırıldığını değiştirmek için bir kırılma noktası ayarlayabilirsiniz (esas olarak ulaşmada sabit bir boyut verir max-width) . Sadece bir max-widthdurumla çalışmak için bir düşünce .
ScottS

Kap öğesinin medya sorguları aracılığıyla dinamik olarak değiştiği zaman keman atabileceğinizi düşünüyor musunuz? Anladığımdan emin değilim.
J82

59

SVG ile çözüm:

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


SVG ve metin kaydırma ile çözüm 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
Bu fikir ilk başta hoş görünüyor. Sonra <html> içindeki SVG'deki yazı tipini kolayca kontrol edemeyeceğinizi fark edersiniz. Yazı tipi, son genişliği etkileyen mobil ve masaüstünde farklıdır.
Stopi

@Stopi iFrame çözümü hakkında ne düşünüyorsunuz? örnek
Dantio

10
HTML /
CSS'den

1
SVG satır içi ise SVG css ile şekillendirilebilir (img etiketi kullanmayın).

8
Bu, dinamik bir kaba dayalı olarak ölçeklenen en iyi, en öngörülebilir çözümdür.
JoshuaDavid

35

Projelerimden birinde, yazı tipi boyutunu ihtiyaçlarıma göre ayarlamak için vw ve vh arasında bir "karışım" kullanıyorum, örneğin:

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

Bunun OP'nin sorusuna cevap vermediğini biliyorum, ama belki başka birine bir çözüm olabilir.


3
vminVe / veya vmaxyerine daha iyi olabilirsiniz .
sebastian_k

4
chrome dev tools bunu geçersiz bir özellik değeri olarak adlandırır
phil294

31

Pure-CSS çözümü calc(), CSS birimleri ve matematik

Bu tam olarak OP'nin istediği şey değildir, ancak birisinin gününü yapabilir. Bu cevap kaşıkla beslemek kolay değildir ve geliştirici tarafında biraz araştırmaya ihtiyaç vardır.

Sonunda calc()farklı birimlerle bunun için saf bir CSS çözümü almaya geldim . İfadenizi çözmek için bazı temel matematiksel formül anlayışına ihtiyacınız olacaktır calc().

Bunu çözdüğümde, DOM'da bazı ebeveynleri doldururken tam sayfa genişliğinde duyarlı bir başlık almak zorunda kaldım. Değerlerimi burada kullanacağım, kendi değerlerinizle değiştireceğim.

Matematiğe

İhtiyacın olacak:

  • Bazı görünümlerde güzel ayarlanmış oran. 320 piksel kullandım, bu yüzden 24 piksel yüksek ve 224 piksel genişliğe sahiptim, bu yüzden oran 9.333 ... veya 28/3
  • Konteyner genişliği, ben vardı padding: 3emve tam genişlik böylece bu var100wv - 2 * 3em

X, kabın genişliğidir, bu yüzden onu kendi ifadenizle değiştirin veya tam sayfa metni almak için değeri ayarlayın. Rsahip olacağınız oran. Bazı görünüm penceresindeki değerleri ayarlayarak, öğe genişliğini ve yüksekliğini denetleyerek ve bunları kendi değerlerinizle değiştirerek elde edebilirsiniz. Ayrıca, o 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

Ve vur! İşe yaradı! yazdım

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

başlığım ve her görünümde güzel ayarlanmış.

Ama nasıl çalışır?

Burada bazı sabitlere ihtiyacımız var. 100vwbakış açısının tam genişliği anlamına gelir ve amacım bazı dolgularla tam genişlikte başlık oluşturmaktı.

Oran. Bir görüntü alanında bir genişlik ve yükseklik elde etmem bana bir oran verdi ve oranla diğer görünüm alanı genişliğinde ne olması gerektiğini biliyorum. Bunları el ile hesaplamak çok zaman alacak ve en azından çok fazla bant genişliği alacaktı, bu yüzden iyi bir cevap değil.

Sonuç

Kimsenin bunu neden çözemediğini merak ediyorum ve bazı insanlar bunun CSS ile uğraşmanın imkansız olacağını bile söylüyor. Öğeleri ayarlamada JavaScript kullanmak istemiyorum, bu yüzden daha fazla kazmadan JavaScript (ve jQuery hakkında unutmak) cevaplarını kabul etmiyorum. Sonuç olarak, bunun anlaşılması iyidir ve bu, web sitesi tasarımında saf CSS uygulamalarına bir adımdır.

Metnimde olağandışı bir kongre için özür dilerim, İngilizce anadili değil ve Stack Overflow cevaplarını yazmak için de oldukça yeniyim.

Bazı tarayıcılarda kötü kaydırma çubuklarımız olduğu da unutulmamalıdır. Örneğin, Firefox kullanırken 100vw, kaydırma çubuğunun altında (içeriğin genişleyemediği yerlerde) genişleyen görünüm penceresinin tam anlamı anlamına geldiğini fark ettim, bu nedenle tam genişlikli metnin dikkatlice kenarlanması ve tercihen birçok tarayıcı ve cihazla test edilmesi gerekir.


13
Bu çözüm yalnızca yazı tipini biliyorsanız (2) yazı tipi bir kullanıcının cihazında mevcutsa ve (3) metin her zaman aynı ise çalışır. Bu onu çok sınırlı bir kullanım durumu haline getirir.
Andrei Volgin

benim konteyner örneğin: 640px ve 16: 9 oranı ile sabit olup olmadığını anlamıyorum. hangi calcs yazmalıyım?
pery mimon

1
Konteyner genişliğiniz x640 piksel ve oran r16: 9, bu nedenle: x = 640px, r = 16 / 9, y = x / r = 640px / (16 / 9) = 360px
hegez

Not: Bu yalnızca 16: 9 boyutunda bir metniniz varsa işe yarar, bu garip bir durumdur. Belki de cevabı ikinci kez okumak yardımcı olabilir. Ayrıca, bu sadece bir gömlek için geçerlidir.
hegez

Dürüst olmak gerekirse, "Bazı görünümlerde güzel ayarlanmış oran. 320 piksel kullandım, bu yüzden 24 piksel yüksek ve 224 piksel genişliğe sahibim, bu nedenle oran 9.333 ... veya 28/3" oranını açıklamanızı öneririm Biraz daha. Oran neyi temsil ediyor?
3limin4t0r

28

Bu konuda büyük bir felsefe var.

Yapılması en kolay şey, gövdeye belirli bir yazı tipi boyutu vermek (10'u öneririm) ve daha sonra diğer tüm öğelerin yazı tipi emveya olur rem. Bu birimleri anlamanız için size bir örnek vereceğim. Emher zaman ebeveyni ile ilişkilidir:

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 daima vücuda görecelidir:

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 */

Ardından, kapsayıcı genişliğinize göre yazı tipi boyutunu değiştirecek bir komut dosyası oluşturabilirsiniz. Ama bu tavsiye ederim değil. Çünkü 900 piksel genişliğinde bir kapta,p 12 piksellik yazı tipi boyutuna öğeye sahip . Ve fikrinize göre, 4 piksel yazı tipi boyutunda 300 piksel genişliğinde bir kap haline gelecektir. Daha düşük bir sınır olmalı.

Diğer çözümler medya sorgularıyla olabilir, böylece farklı genişlikler için yazı tipi ayarlayabilirsiniz.

Ancak önerebileceğim çözümler size yardımcı olan bir JavaScript kitaplığı kullanmaktır. Ve şimdiye kadar bulduğum fittext.js .


6
remBirim anlamına kök elemana göre olan htmleleman değil bodyöğesi. DOM'deki kök öğe htmletikettir. developer.mozilla.org/tr-TR/docs/Web/CSS/length .. remher zaman htmlgövde etiketi değil, kök eleman olan etikete göreceli .. ama iyi cevap :)
Jonathan Marzullo

fittext.js işi yapar, bu çözümü tavsiye ettim!
Jacek Dziurdzikowski

FitText benim için kazanan oldu. Birkaç alternatif denedi, ancak bu en basit ve aynı zamanda Drupal / Backdrop CMS ile iyi entegre görünüyordu. github.com/davatron5000/FitText.js
Yardımcı Joel

23

İşte işlevi:

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

Sonra tüm belgelerinizin alt öğe yazı tipi boyutlarını em's veya' ya dönüştürün %.

Ardından, temel yazı tipi boyutunu ayarlamak için kodunuza böyle bir şey ekleyin.

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

http://jsfiddle.net/0tpvccjt/


1
Şimdiye kadar bu en iyi çözümdür.Kısa ve hafif
wp öğrencisi

Kötü uygulamalar ve aşırı verimsiz
Jack Giffin

@tntrox Bugün olduğu gibi verimsiz olduğu için, 4 yıl önce çok daha verimsizdi. Bu cevabı daha iyi alternatifler yerine reddediyorum. Evet, IE desteği için Javascript gerekir. Ancak, bu korkunç Javascript gerekmez.
Jack Giffin

3
Sanırım cehaletim burada gösteriyor. Ama yukarıdaki neden NEDEN korkunç?

Bunun korkunç olduğunu düşünmüyorum. Daha okunabilir hale getirmek için bazı küçük biçimlendirme değişiklikleri öneririm. Her varyantı en azından ayrı bir satıra koyardım. return thisFonksiyonun sonunda gerekli olmayabilir . Performans için, sürükledikçe yeniden çizilmemesi için onresize öğesinin geri çekilmesini de isteyebilirsiniz. Oldukça basit bir kod, bu yüzden birisi gelişmiş çözümlerini az çaba ile temel alabilir.
Mnebuerquo

19

JavaScript olmadan bunu yapmanın bir yolu var !

Satır içi bir SVG görüntüsü kullanabilirsiniz. Satır içi ise bir SVG'de CSS kullanabilirsiniz. Bu yöntemi kullanmanın SVG resminizin kap boyutuna yanıt vereceği anlamına geldiğini hatırlamanız gerekir.

Aşağıdaki çözümü kullanmayı deneyin ...

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

Örnek: https://jsfiddle.net/k8L4xLLa/32/

Daha gösterişli bir şey ister misiniz?

SVG görüntüleri ayrıca şekiller ve önemsiz şeyler ile harika şeyler yapmanıza izin verir. Ölçeklenebilir metin için bu harika kullanım durumunu inceleyin ...

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


4
Bu çözüm, vwboyutlandırma ile kabul edilenlerden farklı değildir . metni değiştirirseniz, her şey sınır dışı olur.
N69S

14

Bu çok pratik olmayabilir, ancak div / sayfanın boyutunu okumak için dinleyen / döngüler (aralık) olan herhangi bir JavaScript olmadan, bir fontun üst öğenin doğrudan işlevi olmasını istiyorsanız, bunu yapmanın bir yolu vardır. . Iframe'ler.

İframe içindeki her şey iframe'in boyutunu görünümün boyutu olarak kabul eder. Dolayısıyla, püf noktası sadece genişliği metninizin olmasını istediğiniz maksimum genişlik olan ve yüksekliği belirli bir metnin en boy oranına * eşit olan bir iframe yapmaktır.

Görünüm çerçevesi birimlerinin metin için yan üst birimlerle de gelememesi sınırlamasını bir kenara bırakarak (olduğu gibi,% boyutunun herkes gibi davranması), görünüm alanı birimleri çok güçlü bir araç sağlar: minimum / maksimum boyutu elde edebilme . Bunu başka hiçbir yerde yapamazsınız - diyemezsiniz ... bu div'in yüksekliğini ebeveynin genişliği * yapın.

Bununla birlikte, hile vmin kullanmak ve iframe boyutunu [kesir] * toplam yükseklik, yükseklik sınırlayıcı boyut olduğunda iyi bir yazı tipi boyutu olacak şekilde ayarlamak ve [kesir] * toplam genişlik sınırlayıcı boyut. Bu yüzden yüksekliğin genişlik ve en boy oranının bir ürünü olması gerekir.

Özel örneğim için,

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

Bu yöntemle ilgili küçük sıkıntı, iframe'in CSS'sini manuel olarak ayarlamanız gerektiğidir. CSS dosyasının tamamını eklerseniz, bu, birçok metin alanı için çok fazla bant genişliği gerektirir. Yani, doğrudan CSS'mden istediğim kuralı eklemek istiyorum.

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

CSS kuralını alan küçük bir işlev / metin alanını etkileyecek tüm CSS kurallarını yazabilirsiniz.

Bazı bisiklet / dinleme JavaScript olmadan yapmanın başka bir yol düşünemiyorum. Gerçek çözüm, tarayıcıların metni ana kapsayıcının bir işlevi olarak ölçeklemenin bir yolunu sağlaması ve aynı vmin / vmaks türü işlevselliği sağlamak için.

JSFiddle: https://jsfiddle.net/0jr7rrgm/3/ (kırmızı kareyi fareye kilitlemek için bir kez tıklayın ve serbest bırakmak için tekrar tıklayın)

Kemandaki JavaScript'in çoğu sadece benim özel tıklama sürükle işlevim.


@quemeful 'Yeni' ve 'parlak' (davul çalmak lütfen ...) srcdocözelliğini getirdiğimizde öyle değil
Jack Giffin

9

Kullanılması vw, em& co. kesin olarak çalışır, ancak IMO'nun ince ayar için her zaman bir insan dokunuşuna ihtiyacı vardır.

İşte @ tnt-rox ' cevabına dayanarak yazdığım bir senaryo, o insanın dokunuşunu otomatikleştirmeye çalışıyor:

$('#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>

Temel olarak font boyutunu küçültür ve 1emmaksimum genişliğe ulaşana kadar 0,1 oranında artırmaya başlar.

JSFiddle


1
+1 sadece emsinsan dokunuşu ve dikey ritim gerektiren bir kişi için bir çeşit büyücülük değildir.
serraosays

7

% 100, temel yazı tipi boyutuna göredir; bu, ayarlamadıysanız tarayıcının kullanıcı aracısının varsayılanı olur.

Artırdığınız etkiyi elde etmek için, temel yazı tipi boyutunu pencere boyutlarına göre ayarlamak için bir parça JavaScript kodu kullanırdım.


7

CSS'nizin içine, tasarımınızın kırılmaya başladığı yer için 320 piksel genişliğini değiştirerek bunu alt tarafa eklemeyi deneyin:

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

        body { font-size: 1em; }

    }

Ardından, yazı tipi boyutunu istediğiniz gibi "px" veya "em" olarak belirtin.


7

Kendi çözümüm, jQuery tabanlı, kap yükseklikte bir artış elde edene kadar yazı tipi boyutunu yavaş yavaş artırarak çalışır (yani satır sonu var).

Oldukça basit, ama oldukça iyi çalışıyor ve kullanımı çok kolay. Kullanılan yazı tipi hakkında hiçbir şey bilmek zorunda değilsiniz , her şey tarayıcı tarafından halledilir.

Bununla http://jsfiddle.net/tubededentifrice/u5y15d0L/2/ adresinde oynayabilirsiniz.

Sihir burada olur:

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
Bu komut dosyası her resize olayı ve / veya yön değişikliği üzerinde çalışacağından bunu kullanmanızı önermiyorum. Javascript tabanlı bir çözüm kullanmak yerine, yukarıda verilen gibi bir css tabanlı çözüm arayın.
Pilatus

1
Yeniden boyutlandırma ve yönlendirme değişiklikleri "nadir" etkinliklerdir, burada performans sorunu yoktur. İsterseniz, etkinliklere bağlanmayın (örneğin kapsayıcıları yeniden boyutlandırmazlarsa, yanıt vermeyen web siteleri için). CSS çözümleri, bu çözümün yaptığı gibi hiçbir şeyi (yazı tipinin genişliği gibi) düşünmek zorunda kalmadan her durumda çalışmıyor.
Vincent

Cevabınızı bir jQuery fonksiyonu olarak tamamladım. İzin verilen maksimum yükseklik, minimum ve maksimum yazı tipi boyutlarını alır. Bkz. Jsfiddle.net/oriadam/qzsy760k
oriadam

6

Bu web bileşeni , iç metin genişliği kap genişliğine uyacak şekilde yazı tipi boyutunu değiştirir. Demoyu kontrol edin .

Bu şekilde kullanabilirsiniz:

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


6

Yazı tipi boyutu yerine CSS dönüşümü kullanarak basit bir ölçek işlevi hazırladım. Herhangi bir kabın içinde kullanabilirsiniz, medya sorguları vb. Ayarlamanız gerekmez :)

Blog yayını: Tam genişlikte CSS ve JS ölçeklenebilir üstbilgi

Kod:

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

Çalışma demosu: https://codepen.io/maciejkorsan/pen/BWLryj


Bence OP bir CSS çözümü arıyor.
7.07.2017

5

CSS Değişkenlerini Kullan

Henüz kimse CSS değişkenlerinden bahsetmedi ve bu yaklaşım benim için en iyi sonucu verdi, bu yüzden:

Sayfanızda, mobil bir kullanıcı ekranının genişliğinin% 100'ü olan, ancak max-width800 piksele sahip bir sütun bulunduğunu varsayalım , bu nedenle masaüstünde sütunun her iki tarafında biraz alan var. Bunu sayfanızın en üstüne koyun:

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

Ve şimdi vw, yazı tipinizin boyutunu ayarlamak için bu değişkeni kullanabilirsiniz (yerleşik birim yerine ). Örneğin

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

Bu bir değil , saf CSS yaklaşımı, ama oldukça yakındır.



5

Sorunum benzerdi, ancak bir başlık içindeki metni ölçeklendirmeyle ilgili. Fit Font'u denedim, ancak Metin Akışı gibi biraz farklı bir sorunu çözdüğü için herhangi bir sonuç almak için kompresörü açmam gerekiyordu.

Elinizde varsayarak, konteyner sığacak şekilde yazı tipi boyutunu azaltılmış kendi küçük eklenti yazmış Yani overflow: hiddenve white-space: nowrapböylece bile minimuma yazı azaltılması durumunda tam rotasını gösteren izin etmediğini, sadece o göstermek ne keser.

(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

Sanatsal olarak, karakter sayısına bakılmaksızın aynı genişliğe iki veya daha fazla metin satırı sığdırmanız gerekiyorsa, güzel seçenekleriniz vardır.

Dinamik bir çözüm bulmak en iyisidir, böylece hangi metin girilirse girsin hoş bir görüntü elde ederiz.

Bakalım nasıl yaklaşabiliriz.

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>

Tek yaptığımız , ilk satırın genişliğini ( els[0].clientWidth) ve yazı tipi boyutunu ( parseFloat(window.getComputedStyle(els[0],null).getPropertyValue("font-size"))) referans olarak almak ve ardından sonraki satırların yazı tipi boyutunu buna göre hesaplamaktır.


4

Viewport boyutları bu sorunun çözümü olmadığı için fitText eklentisini kullanmaya çalışın .

Sadece kütüphaneyi ekleyin:

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

Ve metin katsayısını ayarlara göre yazı tipi boyutunu değiştirin:

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

Metnin maksimum ve minimum değerlerini ayarlayabilirsiniz:

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

Bu yalnızca Büyük ekran metni için kullanışlıdır ve paragraflar için önerilmez.
Shiv

3

Koduma bak. O yapar font size smalleriçin fitorada her neyse.

Ancak bunun iyi bir kullanıcı deneyimine yol açmayacağını düşünüyorum

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

Sonuç


2

JavaScript yedek (veya tek çözümünüz) olarak, seçeneği ileterek üst öğeye (kapsayıcı) göre ölçeklendirmenize olanak tanıyan jQuery Scalem eklentimi kullanabilirsiniz reference.


2

Herkes için yararlı olması durumunda, bu iş parçacığındaki çözümlerin çoğu, metni e biçiminde birden çok satıra sarıyordu.

Ama sonra bunu buldum ve işe yaradı:

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

Örnek kullanım:

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


2

Her zaman var eleman , bu özelliğe sahip:

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

veya

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

Tam ekrana geçtiğinizde, hesaplanmış bir ölçek değişkeniniz zaten olmalıdır (ölçek> 1 veya ölçek = 1). Ardından, tam ekranda:

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

Küçük kod ile güzel çalışır.


2

Dinamik metin için bu eklenti oldukça kullanışlıdır:

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

Sadece CSS ekleyin:

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

Ve senaryo:

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

2

Bu benim için çalıştı:

Yazı tipi boyutunu, yazı tipi boyutu: 10 piksel olarak ayarlanan genişlik / yüksekliğe göre yaklaşık olarak bulmaya çalışıyorum. Temel olarak, "yazı tipi boyutu: 10 piksel" ile 20 piksel genişlik ve 11 piksel yüksekliğim varsa, 50 piksel genişlik ve 30 piksel yükseklikte bir kapsayıcıyı matematik yapmak için maksimum yazı tipi boyutu ne olurdu? "

Cevap çift oranlı bir sistemdir:

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

Şimdi X, genişlikle eşleşecek bir yazı tipi boyutudur ve Y, yükseklikle eşleşecek bir yazı tipi boyutudur; en küçük değeri al

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

Not: işlevin bağımsız değişkeni bir yayılma öğesi veya üst öğesinden daha küçük bir öğe olmalıdır, aksi takdirde çocuklar ve üst öğelerin her ikisi de aynı genişlik / yükseklik işlevine sahipse başarısız olur.



1

Yazı tipi boyutunu pencereden ziyade kapsayıcısına sığdırmak için, resizeFont()bu soruda paylaştığım işleve bakın (çoğu burada zaten bağlı olan diğer yanıtların bir kombinasyonu). Kullanılarak tetiklenir window.addEventListener('resize', resizeFont);.

Vanilya JavaScript: Kapsayıcı sığdırmak için yazı tipini yeniden boyutlandır

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 + '%';
    }
  }
}

Yedek olarak vw / vh kullanabilirsiniz, böylece dinamik olarak emveyarem JavaScript devre dışı bırakıldığında fontların pencereye ölçeklenmesini sağlayarak JavaScript kullanarak birimler .

.resizeSınıfı, ölçeklendirilmesini istediğiniz metin içeren tüm öğelere uygulayın .

Pencere yeniden boyutlandırma olay dinleyicisini eklemeden önce işlevi tetikleyin. Ardından, kabına sığmayan metin sayfa yüklendiğinde ve yeniden boyutlandırıldığında ölçeklendirilir.

NOT: Varsayılan font-sizeya ayarlanması gerekir em, remya da %uygun sonuçlar elde etmek.


1

HTML

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

Yazı tipi boyutunu en üst düzeye çıkarmak için JavaScript kodu:

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`;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.