Copy link to clipboard
Copied
Hi,
Is there a way to make text automatically change size to the size of a text box?
So no matter how much text is entered, it never falls out of the box.
Thanks,
Em
No, you are not doing something wrong, it was me misunderstanding.
There is no standard option in Illustrator to do this.
Maybe a script?
Touch-wood this should resize text larger/smaller to fit the frame. Caveat emptor, E&OE, etc. If OP requires a more complex script they are welcome to DM me.
// fit_text_to_frame.jsx
// resizes text larger/smaller to fit the selected text frame(s)
// (the text frame must be fully selected; point text and non-text items are ignored)
// current limitations: this assumes all characters are same size; leading is not adjusted
(function() {
var MIN_SIZE = 1, MAX_SIZE = 1296 // practical limits,
...
Copy link to clipboard
Copied
Select Auto Size in the Area Type Options.
Copy link to clipboard
Copied
Hi Ton,
I have tried this but it doesn't work.
It doesn't change the text size at all, it just contrains text to the width of box unless I am doing something wrong?
Thanks,
Em
Copy link to clipboard
Copied
No, you are not doing something wrong, it was me misunderstanding.
There is no standard option in Illustrator to do this.
Maybe a script?
Copy link to clipboard
Copied
“Auto Size” dynamically resizes the text frame to fit the text, which is the opposite to what OP wants.
AFAIK there is no way to dynamically resize text to fit an area text frame. You can wrap a single line of point text inside a Mesh Envelope, which causes the text to scale horizontally to fit the mesh’s boundaries, but I suspect that’s not what OP wants.
OP could search existing third-party AI plugins to see if there is one that implements a custom text frame that offers this auto-fitting behavior. (Plugins have the advantage that they hook directly into AI’s low-level C++ APIs, which expose additional functionality not found in its scripting APIs.) Or they could hire a plugin developer to write one (although that won’t be cheap):
community.adobe.com/t5/illustrator/ct-p/ct-illustrator?page=1&sort=latest_replies&tabid=all&topics=label-thirdpartyplugins
If OP is willing to compromise on fully automatic behavior [1], it is certainly possible to resize text to fit by manually running a script, e.g.:
community.adobe.com/t5/illustrator-discussions/fit-frame-to-text-free-script/m-p/8715230
It’s a bit of a pain to script this as AI’s text frame objects, unlike ID’s, do not provide a convenient script-accessible “overflows” property, necessitating some creative kludging to detect overflowing text. So caveat emptor on that, although it seems to work well enough IME. (Detecting underflows is left as an exercise.)
--
[1] Ideally, AI would allow OP to attach the above script to the document’s text frames, so that the script runs automatically after a text frame has been edited. In theory, one could create a C++ plugin to provide this general-purpose “attachability” to scripters. This would be amazingly powerful. Alas, AI’s low-level C++ plugins have absolutely rotten integration with AI’s high-level scripting interface; thus wrapping a text frame in a custom plugin makes that text frame all but invisible to scripts. (This is a problem space I am currently spelunking w.r.t. text frames wrapped in AI’s own Envelopes plugin, and it is a royal PITA.)
Copy link to clipboard
Copied
Oops: minor brain fart on my part: the script that I linked fits frame to text, not text to frame as OP wants, so it would require some adaptation to perofrm the latter.
The simplest implementation is to detect if there is an overflow, and if there is then iterate across all the characters, reducing them by a fixed amount each time (step size); repeating until the overflow goes away. Can be very slow if the step size is small, but it does the job.
A slightly more sophisticated option is to use a binary search algorithm: i.e. if the text is overflowing then reduce the font size by 50% of its original size, then reduce or increase the font size by 25% of its original size depending on whether there is or isn’t an overflow; and repeat that process, halving the step size each time until it falls below some minimum percentage (e.g. <4%) or point size (e.g. 1pt), then check for an overflow and reduce it one last time if needed. Good for giving you an exact fit if that’s what you want, and quicker on average than the linear reduction algorithm since the number of steps it performs is constant (or near as).
I’ve written such fitting routines before—they’re a bit kludgy, but doable via AI’s existing scripting APIs. (I’m sure fitting text could be done quicker and more elegantly in a C++ plugin, but that’s a LOT more work to develop.) If OP would like such a script knocked together, they are welcome to DM me with their requirements.
Copy link to clipboard
Copied
Can you show a sketch or a screenshot with a couple of type objects that may illustrate the behaviour you are looking for?
You may include further instructions if required.
Copy link to clipboard
Copied
Don't start with a text box, just type, and then you can just use the transform panel and change text block to desired width, not sure it's what you want though.
If you want dynamic changing, that's not in Illy.
Again, I'm not sure it's exactly what you mean, but add your voice here:
You may find something useable here - https://www.linkedin.com/pulse/adobe-illustrator-variable-data-dealing-overset-text-vasily-hall
Copy link to clipboard
Copied
It does sound like it should be possible. But from design perspective it is a bad idea beacuse normally you would want to have control on the typography. You would probably run into legal accessibility issues too.
Copy link to clipboard
Copied
Sure, but presumably OP has a reason for doing it anyway. (e.g. Multi-language packaging, where text density can vary greatly within a single line depending on whether each localized artwork has to hold 1, 2, or 3 languages. Yes, the resulting artworks may look awful from a design perspective. No, there’s nothing you can do as an artwork grunt as that’s what the customer requires.)
As for legal requirements, it’s simple enough to define a minimum font size below which the script will not go. One of the advantages of automated artwork production is that you encode all your brand guidelines, legal requirements, etc within the automation, ensuring consistency and conformance across all artworks.
If OP wishes to discuss details they are welcome to post additional information and some examples of the artworks they’re producing.
Copy link to clipboard
Copied
You could do it manually like this:
Use guides to remember the original size of the textbox.
Scale the textbox bounding box with the selection tool and shift key until the overset + sign disappears.
Use the Scale tool to scale the text object back to the original size.
Copy link to clipboard
Copied
So far there are only some long-winded speculations. The entire request can be interpreted in different ways.
What is required? At least a sketch that shows the initial situation and the desired ultimate result. Or better yet, some Illustrator sample files.
Copy link to clipboard
Copied
OP’s request was clear enough: they want the text within a text frame to resize so that it fits into that frame without overflowing. What’s lacking is sufficient detail to provide a production-ready solution, e.g.:
As we’ve both said, if OP can post some sample files it will give us a better idea of what the job entails. If OP’s requirements are minimal, it’s a 5-minute modification to the free fitting script I linked to above, which someone here might do for free if OP can’t code. If it’s more involved, the development work can be budgeted and a proposal put forward.
Copy link to clipboard
Copied
Thanks for all of the replies.
I probably should have stated my reasoning behind this.
I am using varaible data text that varies in length. Not massively, but enough for the text to need to be resized so it fits on one line and within the width of the box.
There are no legal requirements regarding the text size.
It should both increase or decrease, as I don't have a lower or max limit of characters. I am altering multiple text boxes per page with variable data, though it is only one that needs the auto fit text to size of box.
I am not a coder but will take a look at the scripts/plugins suggested so thanks for that. Will also try and post example later 🙂
Copy link to clipboard
Copied
Probably or certainly true, hhas.
Let's see what further infos emmatomo is going to provide.
Copy link to clipboard
Copied
Touch-wood this should resize text larger/smaller to fit the frame. Caveat emptor, E&OE, etc. If OP requires a more complex script they are welcome to DM me.
// fit_text_to_frame.jsx
// resizes text larger/smaller to fit the selected text frame(s)
// (the text frame must be fully selected; point text and non-text items are ignored)
// current limitations: this assumes all characters are same size; leading is not adjusted
(function() {
var MIN_SIZE = 1, MAX_SIZE = 1296 // practical limits, in pts
var MIN_STEP = 0.1 // the smaller this is, the more precise (and slower) the fit
function fitTextToFrame(textFrame) {
// textFrame : TextFrame -- path or area text
if (textFrame.typename !== 'TextFrame' || textFrame.kind === TextType.POINTTEXT) { return }
var length = textFrame.contents.replace(/\s+$/, "").length // length of printable text (ignores trailing whitespace)
if (length === 0) { return } // skip empty text frame
// overflow checker; this checks length of printable text to index of last visible character in frame
var hasOverflow = function() {
var lastLine = textFrame.lines[textFrame.lines.length-1]
if (!lastLine) { return true } // no lines visible (frame is too small)
var visibleLength = (lastLine.characters[0].characterOffset + lastLine.length - 1)
return visibleLength < length
}
// (caution: do not use JS’s +=, -=, *=, /= operators on AI properties as JSX doesn't handle them right)
var style = textFrame.textRange.characterAttributes
var size = style.size
// 1. resize text so it is just overflowing
while (hasOverflow() && size >= MIN_SIZE * 2) { // decrease size until no overflow
size /= 2.0
style.size = size
}
if (hasOverflow()) { return } // hit minimum size and it's still overflowing, so give up
while (!hasOverflow() && size <= MAX_SIZE / 2) { // increase size until text overflows
size *= 2.0
style.size = size
}
if (!hasOverflow()) { return } // hit maximum size and it hasn't overflowed, so give up
// 2. now do binary search for the largest size that will just fit the text frame
var step = size / 2.0
while (step > MIN_STEP) {
step /= 2.0
size += hasOverflow() ? -step : step
style.size = size
}
// 3. if text ends up overflowing after last step, step it back down
while (hasOverflow()) {
style.size = size - step
step *= 1.1
}
}
var items = app.activeDocument.selection
for (var i = 0; i < items.length; i++) { // iterate over currently selected items
fitTextToFrame(items[i])
}
})()
Copy link to clipboard
Copied
Very good! I have not been able to find such a script (only one for single lines), but this works fine with a simple test I made.
Copy link to clipboard
Copied
The above script does not care how many lines of text there are, only that they all fit into the text frame. If the text frame is tall enough to accommodate a single short line of large text, and the text frame is set to use auto-leading, it may be that as a longer piece of text is reduced in size it flows onto a second line. If OP wants to avoid that wraparound, the simplest solution would be to set the leading to a fixed value that is greater than the height of the text frame.
The kiwi automation engine I built a few years back has a load of options for fitting text and other content (example of capabilities here: [www.youtube.com/watch?v=a8LgiIMpI9s]). The above algorithm is similar to the one used in its `scale text to fit` rule, which has proved reliable, so I’m fairly confident it’ll work without issue. (I’m currently planning a new, cross-platform kiwi system, although whether that ends up being written in JavaScript or something else I’ve yet to decide.)
I’ll also update the older `fit_frame_to_text.jsx` script later on, as I noticed a couple minor bugs in it while writing this one.
Copy link to clipboard
Copied
Bonjour à tous,
Merci pour votre script hhas01 qui fonctionne "très bien", sauf que je n'ai pas eu de chance car mon premier test n'a pas été concluant:
text size 12 pts au départ du script.
Ok avec 11.9 ou 12.1 ou encore avec step /= 2.1
Désolé je n'ai pas trouvé ce qui se passe exactement..
Cordialement René
Copy link to clipboard
Copied
Apologies, yes. That’s a bug in my math. Immediately beneath:
// 2. now do binary search for the largest size that will just fit the text frame
change:
var step = size
to:
var step = size / 2.0
and after:
// 3. if text ends up overflowing after last step, step it back down
change:
if (hasOverflow()) { style.size = size - step }
to:
if (hasOverflow()) { style.size = size - step * 2 }
I think that should be it now. (Sorry, long week.)
Copy link to clipboard
Copied
Thank you very much for your prompt intervention.
Sincerely, René
Copy link to clipboard
Copied
I have made a small additional fix in the above script, changing part 3 to:
// 3. if text ends up overflowing after last step, step it back down
while (hasOverflow()) {
style.size = size - step
step *= 1.1
}
I realized there’s a small possibility that a small change in font size could cause a dramatic change in text height, should the text grow just large enough to wrap onto an extra line on one of the last steps. This corrects for that, reducing it until the overflow goes away.
The script doesn’t seek a perfect fit, just “good enough”. (This is why the font size may change very very slightly if you run it then run it again on the same text.) However, it should never leave the text overflowing, it should run quickly, and it should never get stuck in an infinite loop. And while it does not include a workaround for the “12pt Myriad Pro Regular” bug (which we now know is an Illustrator bug relating to “Normal Character Style”), at worst it will leave the text smaller than it could be, not too large to fit.
Copy link to clipboard
Copied
I hope it's okay that I used my rudimentary programming skills to adapt your script to my needs.
An attempt is made to adapt each line to the text box. Unfortunately, for some reason you have to run the script twice - sometimes even three times, but at some point it fits 🙂
// fit_text_to_frame.jsx
// resizes text larger/smaller to fit the selected text frame(s)
// (the text frame must be fully selected; point text and non-text items are ignored)
// current limitations: this assumes all characters are same size; leading is not adjusted
(function() {
var MIN_SIZE = 1, MAX_SIZE = 1296 // practical limits, in pts
var MIN_STEP = 0.05 // the smaller this is, the more precise (and slower) the fit
function fitTextToFrame(textFrame) {
// textFrame : TextFrame -- path or area text
if (textFrame.typename !== 'TextFrame' || textFrame.kind === TextType.POINTTEXT) { return }
var l=0
var countlines=textFrame.lines.length
while(l< countlines){
var length = textFrame.lines[l].contents.replace(/\s+$/, "").length // length of printable text (ignores trailing whitespace)
if (length === 0) { return } // skip empty text frame
var visLength = textFrame.lines[l].contents.replace(/\s+$/, "").length // length of written text
var style = textFrame.textRange.lines[l].characterAttributes
var size = style.size
// 1. resize text so it is just overflowing
while ((visLength > length) && size >= MIN_SIZE * 2) { // decrease size until no overflow
size /= 2.0
style.size = size
visLength = textFrame.lines[l].contents.replace(/\s+$/, "").length
}
if ((visLength > length)) { return } // hit minimum size and it's still overflowing, so give up
while ((visLength < length) && size <= MAX_SIZE / 2) { // increase size until text overflows
size *= 2.0
style.size = size
visLength = textFrame.lines[l].contents.replace(/\s+$/, "").length
}
if ((visLength < length)) { return } // hit maximum size and it hasn't overflowed, so give up
// 2. now do binary search for the largest size that will just fit the text frame
var step = size / 1.5
while (step > MIN_STEP) {
step /= 1.25
size += (visLength < length) ? -step : step
style.size = size
visLength = textFrame.lines[l].contents.replace(/\s+$/, "").length
}
// 3. if text ends up overflowing after last step, step it back down
while ((visLength < length)) {
style.size = size - step
step *= 1.1
visLength = textFrame.lines[l].contents.replace(/\s+$/, "").length
}
l++
}
}
var items = app.activeDocument.selection
for (var i = 0; i < items.length; i++) { // iterate over currently selected items
fitTextToFrame(items[i])
}
})()
Copy link to clipboard
Copied
Copy link to clipboard
Copied
I presume the script should be run in Illustrator.