css scaling based on character count of fixed size font - javascript

I'm getting ready to start on a webapp/phonegap app that will be displaying code.
I will be using highlight.js to display code. HighlightJs uses pre tags and has a style called monokai_sublime that uses a fixed width font
I have snippets of code carefully edited to be either max 40, 60, or 80 characters long.
What I want is some css or viewport magic to where I can have 3 css classes .code40, .code60, .code80 and when I set those on the element, it will make it to where the width of the element will exactly contain 40,60,or 80 fixed size characters.
so I want to show this snippet where it takes up the full width
do_some_cool_magic(with,stuff); //size40
but also show this snippet at the same width (full width), so with a smaller font size
do_some_cool_magic(with, {stuff:"that is longer"}); //size60
If I switch the phone to landscape, it should still do the same thing. if class code60 is applied 60 characters should be the full width of the screen(or div)
Right now I Just hard-coded the supposed number of pixels my phone screen has (1080x1920) and set the font size to a px amount that matched, but on my phone, it showed up as gigantic letters and didn't fit on the screen (there was scrolling, as though it was zoomed in 200%, and well, it was dependent on the exact size/proportion of the screen anyways)
here's the jsfiddle http://jsfiddle.net/xqck5j4g/
I'm not expecting you to rewrite the fiddle, but I want to know what is an effective way to set up my css is so that: regardless of screen size, orientation, dpi etc when I set class .code60 on a code block, the font will be such that 60 characters fills the width. We can assume that the width is always 100% if that helps.

Related

How to make a repsonsive design so H2 get its maximum font size in a 1-line DIV?

How do I make a headline, H2, to fit into the current width of a DIV.
I want the H2 to get the maximum font size, displaying its full context (without using overflow to cut or hide its content), while not breaking into a second line within the DIV.
There's a few ways - some more complex than others. There's a few JavaScript plugins that can handle this which might serve you best.
A simple but effective CSS-only way would be to use the viewport width (vw) as the value for font-size. Here's an example using white-space: nowrap in conjunction: https://jsfiddle.net/6tueLheq/
HTML:
<h2>
Hello there i don't break to the next line no matter what the width!
</h2>
CSS:
h2 {
white-space: nowrap;
font-size: 3vw;
}
NOTE - this way is not perfect by any means - I'd suggest using something like FitText: http://fittextjs.com/, which is quite powerful.
More info on viewport units: https://web-design-weekly.com/2014/11/18/viewport-units-vw-vh-vmin-vmax/
Js Way :
You can use Javascript based plugins like FitTextJs http://fittextjs.com/. This plugin allows you to have headings that can resize based on the current device width.
CSS Way:
You can provide the font size using vw units. This will scale the font size based on current viewport size.
E.g., 1vw will direct the browser to use the font size as 1% of current viewport width.
But please check if your targeted browsers support this unit before Implementation.
Custom implementation :
I have used following way to design fluid websites, that should align and appear identical in all possible screen resolutions.
If the font size at 320 px is 12px, then the mobile font multiplication factor will be
320px has font size as 12px
Then what should be the font size at 480px
The calculation will be
X = ( 12 * 480) / 320;
Once the font size is dynamically calculated, you can set the font size to body tag and set font sizes for dependent elements in %.
e.g.,
h2 { font-size:110%;}
This method is fun to implement.
But there will be a slight delay before the new calculated font size to be applied on window resize or orientation changes

Set CSS aspect ratio to the inverse of width?

I'm having trouble with a CSS layout - the key part is that I'd like a box to grow in height as its width decreases.
Now, I've started with the 'fixed aspect ratio' technique on an element - where you set the height to 0, and the padding-top to a percentage, say 50%. The padding value is calculated as 50% of the width of the parent element (not the height, as you might guess), so what you end up with is a box with a fixed 2:1 aspect ratio, but otherwise is fluid in size.
The next step (in my half-baked solution) is to modify the padding percentage so it increases as the width decreases (the width is 100% of the page). I'm pretty sure this can't happen in straight CSS, and I'm happy with a small piece of Javascript to update the value when the window is resized.
Can anyone help me with the formula to adjust that percentage inversely to the width?
A few other notes:
The element is a 'spacer' - it will be invisible, so if it takes two elements, etc. that's OK.
The whole layout is fluid and responsive from 2500+ px wide down to 320px, so there's no 'max value' we can use (I don't think).
Thanks in advance.
Perhaps the jQuery .resize() function might be of assistance? it binds a function to whenever the element (or window) is resized.
For example, if you wanted the area of an element #el to always be 50,000 pixels-squared
$(window).resize(function() {
area = 50000;
width = $('#el').width();
$('#el').height(Math.ceil(area/width));
});
Working Example: http://jsfiddle.net/asifrc/T8HrW/embedded/result/
Example Code: http://jsfiddle.net/asifrc/T8HrW/
jQuery .resize() Documentation: http://api.jquery.com/resize/
Let me know if this is what you were looking for :)

Javascript mobile - calculate element dimensions in pixels based on screen dimensions

I want to calculate the dimensions of certain elements (img, ul, div, etc.) based on screen size. I can't to use percent values. I need pixel values. I also don't want to 'hardcode' everything using media queries and a new set of images for every resolution or screen size.
I thought about making this using screen size. I only need width calculation. So I add the initial width of my images and some initial space between them -> total width, and I then get scaling factor using: screenwidth / totalwidth
Now I scale all of my images and also the space between with this factor.
It's a very simple layout, only a few images and HTML elements. So this scaling should not be expensive.
It would work if the devices gave me reliable width measure for the screen. But depending of the device, I get a different meaning of this value. I'm using screen.width
In some cases screen.width is what the currently width is - in portrait it's a small value, in landscape a large one. But in other ones, width is always the same - the value which is defined as device's width.
So how do I scale my layout according to what's currently screen width in a consistent way with rotation, and without CSS % values? Is this an acceptable way to do layout scaling or am doing no-go?
Edit: I have to add more details after trying Jasper's solution. The images are used in a slider. The slider is basically an UL and each LI contains an image with float:left - so all the images are appended horizontally one after the other. With overflow hidden and stuff only the current slide is visible. Now, the official width of the UL is the sum of the width of all contained LIs. And this means, at least with my current state of knowledge, that I can't use percentage size for the LI elements, because if I did, this will be % of this total width of the UL, which is very large, and I end with immense LI elements/images.
Isn't there any reliable way to get current screen width for all devices ? I already have working code, I only need that the value of screen width is correct.
New update
Look here is a similar approach to what I'm trying to do:
http://ryangillespie.com/phonegap.php#/phonegap.php?
Entry of June 18, 2011 "One Screen Resolution to Rule Them All"
I tried also with exactly that example, copy pasting it in my code. But it doesn't work either. window.outerWidth has the same problems as I'm describing for screen.width (as well as JQuery $('body').width()). It works as long as the device isn't rotated - it initializes well. But at the first rotation, depending of the device, I get problems. In some it works as expected, in others it interchanges the values, so that I get large width in portrait mode and short in landscape, in others it gives fixed width and height all time, in others it doesn't rotate at all....
This is most likely accomplish-able with CSS alone (which is usually good for performance):
img {
width : 100%;
height : auto;
}
That will keep all the image's aspect ratios but re-size them to 100% width. Now that width is set based on the image's parent element(s) width. If you are using jQuery Mobile then the data-role="content" elements have a 15px padding, so to remove that you can just add a container to the image elements that removes the padding:
HTML --
<div class="remove-page-margins">
<img src="http://chachatelier.fr/programmation/images/mozodojo-mosaic-image.jpg" />
</div>
CSS --
.remove-page-margins {
margin : 0 -15px;
}​
And walaa, you've got responsive images without loads of code or overhead.
Here is a demo using a container and not using a container: http://jsfiddle.net/EVF4w/
Coincidentally I found that this works:
$(window).resize(function() {
updateScaling($('body').width());
});
This is always called and passes correct width. As far as I remember it also works with screen.width
In updateScaling I calculate a scalingFactor and adjust my elements.
I tried out responsive CSS, media queries and so on, but at some point it didn't make sense anymore, because I have anyways to recalculate the margin of slider's UL based on current slide and new width - and other stuff which needs script. So I made everything with script.
I removed window.onorientationchange.

When I have width: auto and specific left and right, why does setting min-width to the value of calculated width expand the element by 2px?

I have a page made of elements with width and height set to auto and their dimensions defined with left, right, top and bottom properties. When the page is loaded, all widths and heights are set to their calculated values by the browser, as they should be. However, when I set min-width of the elements to their respective calculated widths, each of those elements is expanded by 2px. The same happens if I set their min-height to be equal to the calculated height. I do it with jQuery, like this
element.css('min-width', element.css('width'));
or
element.css('min-width', element.width());
The effect is exactly the same as it should be, but there should not be the extra 2px if I understand what's happening correctly. Using
element.css('min-width', element.width() - 2);
completely solves the problem but I don't like not understanding why there are the extra 2px. According to specifications, neither width nor min-width nor max-width should include padding, borders or margins.
I've tested in Chrome and FF and both behave the same way.
What browser are you testing and can it be that your document is in quirksmode?
element.css('min-width', element.width()); shouldn't be doing anything in standards mode, because element.width() returns an integer without a CSS unit, and min-width requires a unit in standardsmode.
So put your document in standards mode and then try:
element.css('min-width', element.width() + "px");
If that doesn't help you'll need to show a working example.

How do you find the largest font size that won't break a given text?

I'm trying to use CSS (under #media print) and JavaScript to print a one-page document with a given piece of text made as large as possible while still fitting inside a given width. The length of the text is not known beforehand, so simply using a fixed-width font is not an option.
To put it another way, I'm looking for proper resizing, so that, for example, "IIIII" would come out in a much larger font size than "WWWWW" because "I" is much skinnier than "W" in a variable-width font.
The closest I've been able to get with this is using JavaScript to try various font sizes until the clientWidth is small enough. This works well enough for screen media, but when you switch to print media, is there any guarantee that the 90 DPI I appear to get on my system (i.e., I put the margins to 0.5in either side, and for a text resized so that it fits just within that, I get about 675 for clientWidth) will be the same anywhere else? How does a browser decide what DPI to use when converting from pixel measurements? Is there any way I can access this information using JavaScript?
I would love it if this were just a CSS3 feature (font-size:max-for-width(7.5in)) but if it is, I haven't been able to find it.
The CSS font-size property accepts length units that include absolute measurements in inches or centimeters:
Absolute length units are highly dependent on the output medium, and
so are less useful than relative units. The following absolute units
are available:
in (inches; 1in=2.54cm)
cm (centimeters; 1cm=10mm)
mm (millimeters)
pt (points; 1pt=1/72in)
pc (picas; 1pc=12pt)
Since you don't know how many characters your text is yet, you may need to use a combination of javascript and CSS in order to dynamically set the font-size property correctly. For example, take the length of the string in characters, and divide 8.5 (assuming you're expecting US letter size paper) by the number of characters and that gives you the size in inches to set the font-size to for that chunk of text. Tested the font-size with absolute measurements in Firefox, Safari, and IE6 so it should be pretty portable. Hope that helps.
EDIT: Note that you may also need to play around with settings such as the letter-spacing property as well and experiment with what font you use, since the font-size setting isn't really the width of the letters, which will be different based on letter-spacing, and font, proportional to length. Oh, and using a monospace font helps ;)
I don't know of a way to do this in CSS. I think your best bet would be to use Javascript:
Put the text in a div
Get the dimensions of the div
Make the text smaller if necessary
Go back to step 2 until the text is small enough
Here's some sample code to detect the size of the div.
Here's some code I ended up using, in case someone might find it useful. All you need to do is make the outer DIV the size you want in inches.
function make_big(id) // must be an inline element inside a block-level element
{
var e = document.getElementById(id);
e.style.whiteSpace = 'nowrap';
e.style.textAlign = 'center';
var max = e.parentNode.scrollWidth - 4; // a little padding
e.style.fontSize = (max / 4) + 'px'; // make a guess, then we'll use the resulting ratio
e.style.fontSize = (max / (e.scrollWidth / parseFloat(e.style.fontSize))) + 'px';
e.style.display = 'block'; // so centering takes effect
}

Categories