问题
I'm trying to get some fonts to scale for a responsive banner on my page, and found and modified some code I found online for these purposes. There are basically two parts to this:
On decent sized tablets, laptops, and desktop (or external) monitors, I will use a horizontal banner at the top - this works.
On smaller tablets and phones, I want to use a vertical banner on the left side - this is not working.
========== HTML ==========
The HTML structure is essentially this (some strings changed to protect the innocent ;-)):
<body>
<section id="page">
<section id="header">
<div id="logo"><img src="./Images/site/logo.png" alt="record" height="195px" width="195px"/></div>
<div id="h_banner">
<img id="ban_img_left" src="./Images/site/lt.png"/>
<div id="banner_h">
<div class="banner_string flexFontH"><u>Mumble</u> <img src="./Images/site/And.png" height="200px"/> <u>Grumble</u></div>
</div>
<img id="ban_img_right" src="./Images/site/rb.png"/>
</div><!-- h_banner -->
<div id="v_banner">
<img id="ban_img_top" src="./Images/site/lt.png"/>
<div id="banner_v">
<div class="banner_string flexFontV">M<br/>u<br/>m<br/>b<br/>l<br/>e<br/>
<img src="./Images/site/And.png" height="80px"/>
<br/>G<br/>r<br/>u<br/>m<br/>b<br/>l<br/>e<br/></div>
</div>
<img id="ban_img_bottom" src="./Images/site/rb.png"/>
</div><!-- v_banner -->
</section><!-- header -->
...
<div id="TestFontSize" class="banner_string">WWWWWWWWWWWWWWWW</div>
========== CSS ==========
The CSS code is grid-based (ommitted some non-pertinant pieces like col:
#page {
display: grid;
grid-template-columns: 80px 120px auto 200px;
grid-template-rows: 200px auto 200px;
}
#header {
grid-column: 1/5; grid-row: 1/2;
display: grid;
grid-template-columns: 200px auto 200px;
grid-template-rows: 200px;
position: relative;
}
#logo {grid-column: 1/3; grid-row: 1/2; position: fixed;}
#banner_h {grid-column: 1/5; grid-row: 1/2;}
#h_banner {grid-column: 1/5;}
#ban_img_left {grid-column: 1/3; position: absolute; height: 200px; left: 10px;}
#ban_img_right{gird-column: 4/5; position: absolute; height: 200px; right: 10px;}
#banner_v {
grid-column: 1/2; grid-row: 1/4;
display: grid;
grid-template-columns: auto;
grid-template-rows: 80px auto 80px;
}
#v_banner {grid-row: 2/3; display: none;}
#ban_img_top {grid-row: 1/2; display: none; position: fixed; width: 80px; top: 10px;}
#ban_img_bottom {grid-row: 3/4; display: none; position: fixed; width: 80px; bottom: 10px;}
.banner_string {
position:absolute; height: 200px; width: 100%;
display: flex; justify-content: center; align-items: center;
/*font-family: HaarlemDecoDEMO; letter-spacing: 10px;*/
font-family: Jazz-let; letter-spacing: 5px;
color: #83AFE4;
}
@media only screen and (max-width: 1000px) { /* [small-ish] iPhones */
#page {grid-template-columns: 80px auto; grid-template-rows: auto;}
#header {grid-template-columns: auto; grid-template-rows: auto;}
#logo {display: none;}
#banner_h {display: none;}
#h_banner {display: none;}
#ban_img_left {display: none;}
#ban_img_right {display: none;}
#banner_v {display: grid; width: 80px; height: 100%; position: fixed;}
#v_banner {display: block;}
#ban_img_top {display: block;}
#ban_img_bottom {display: block;}
.banner_string {
display: inline; width: 80px; height: 100%; position: fixed; display: block;
transform: translate(25px, 0px);
}
}
========== JS ==========
The Javascript is where the responsive aspect of scaling the font in the banner comes into play. I'll admit that some of the numbers I've used were from trial-and-error to find something that seemed to work, so take it with a modicum of salt.
flexFont = function() {
var len = "Mumble & Grumble".length;
/* (1) horizontal banner */
var hBanner = $(".flexFontH");
var hBannerWidth = $(hBanner).width();
var hBannerHeight = $(hBanner).height();
if (hBannerHeight > 0) {
var fontSize = 2 * (hBannerWidth - (2 * hBannerHeight)) / len; /* Jazz-let */
if (fontSize > 154) { fontSize = 154; } /* max that fits within 200px height for Jazz-let */
$(hBanner).css("fontSize", fontSize+"px");
}
/* (2) vertical banner */
var vBanner = $(".flexFontV");
var vBannerWidth = $(vBanner).width();
var vBannerHeight = $(vBanner).height();
if (vBannerWidth > 0) {
var fontSize = 1.125 * (vBannerHeight - (2 * vBannerWidth)) / len;
var lineHeight = (fontSize - 5) + "px";
var test = document.getElementById("TestFontSize");
test.style.fontSize = fontSize+"px";
var stringWidth = (test.clientWidth + 1);
var paddingTop = ((vBannerHeight - stringWidth) / 2) + "px";
var h = (vBannerHeight - 160) + "px";
$(vBanner).css({"fontSize": fontSize+"px", "height": h, "padding-top": paddingTop, "line-height": lineHeight});
}
}
window.onload = function(event) {
flexFont();
}
window.onresize = function(event) {
flexFont();
}
========== PROBLEM ==========
When I resize the window when it is wide-enough to use the horizontal banner - it all works as I want, the font in the banner scales up / down as the window width increases / decreases.
When I resize the window when it is narrow enough to use the vertical banner - the text disappears on the first redraw. If I refresh the page it shows up, but then if I resize the window (narrower, taller, shorter) it disappears again - and apparently the problem is that $(vBanner).height() becomes '0' and so all calculations based on that value are also '0'.
That's on my laptop trying to simulate the change of screen size. On my phone, it's still pretty much the same thing: when I first render the page, the vertical banner looks fine, but then if I change the orientation to / from landscape / portrait - again, the text disappears.
So - can anywone figure out why this might be the case? and - more importantly, what I might be able to do to fix it?
回答1:
You can simplify this a lot. You don't need javascript or media queries for this, you can use viewport units. vw stands for viewport width and vh stands for viewport height. These are extremely valuable for fonts because they are based on the width or height of the viewport, which is the user's visible area of a web page (which changes on resize and based on device)
font-size: 5vw;
^ 5% of the viewport width. Here's a jsFiddle so you can see it in action
回答2:
I tried to recreate your issue by copy-pasting code and importing placeholder images of my own. It would very helpful if you could update your question with a jsfiddle that demonstrates your issue.
It seems that every time the flexFont is called, it shrinks the content by a substantial amount until it reaches a minimum value.
The vertical banner code is creating issues when setting the height in the css. If you leave the height setting alone, it seems to function more appropriately:
$(vBanner).css({"fontSize": fontSize+"px", /*"height": h,*/ "padding-top": paddingTop, "line-height": lineHeight});
Give this a try and see if it helps you towards your goal. If it doesn't, please update your question to provide a jsfiddle and some more info of what you need.
来源:https://stackoverflow.com/questions/52599633/responsive-design-gone-awry