@brian_p_dts, I had a bit of a play and wrote a function "fitText" that aims to fit text to a given textFrame and also takes a maxLineCount parameter, so you can specify that you want, say, 3 lines and if there are more than 3 lines it will reduce point size further. (maxLineCount only works in area text—on path text you just get one line no matter what.) It's a quick script so will definitely fail in edge cases. See what you think.
- Mark

/**
* @file Fit text to text frame.js
*
* Limitation: this will make all the text in the frame the same size!
*
* @author m1b
* @version 2026-05-17
* @discussion https://community.adobe.com/t5/illustrator-discussions/jsx-parm-error-when-setting-characterattributes-size-of-story-textrange/m-p/13535839
*/
(function () {
var doc = app.activeDocument;
var tf = doc.selection[0];
if (tf == undefined)
return alert('Please select a text frame and try again.');
// some example text
// tf.textRange.contents = 'The quick brown fox jumps over the lazy dog';
// fit the text, specifying number of lines
var numberOfLines = 3;
fitText(tf, numberOfLines);
/**
* Fits text to an area text frame or path text.
* @author m1b
* @version 2023-01-29
* @param {TextFrame} textFrame - an Illustrator TextFrame (area text or path text).
* @param {Number} [maxLineCount] - the maximum number of lines of the final text (default: no limit). This is ignored for path text.
* @param {Number} [increment] - the increment of size changing; the precision of the fit (default: 0.05).
*/
function fitText(textFrame, maxLineCount, increment) {
maxLineCount = maxLineCount || Infinity;
increment = increment || 0.05;
if (TextType.POINTTEXT === textFrame.kind)
// "fitting" makes no sense with point text
return;
var size = textFrame.textRange.characterAttributes.size;
// make an overflow text frame
var overflowTextFrame = addOverflowTextFrame(textFrame);
if (!overflowTextFrame)
return;
$.writeln('textFrame.lines.length = ' + textFrame.lines.length);
// first enlarge text
while (
overflowTextFrame.words.length === 0
&& textFrame.lines.length !== 0
) {
size += increment;
sizeBothTextFrames(size);
}
$.writeln('textFrame.lines.length = ' + textFrame.lines.length);
// now reduce the text size to fit
while (
overflowTextFrame.words.length > 0
|| textFrame.lines.length > maxLineCount
) {
size -= increment;
sizeBothTextFrames(size);
}
// cleanup
overflowTextFrame.remove();
// helper function
function sizeBothTextFrames(size) {
textFrame.textRange.characterAttributes.size = size;
overflowTextFrame.textRange.characterAttributes.size = size;
}
};
/**
* Adds a linked area text frame to the given text frame.
*
* Tries to overcome a complication that destroys overset
* text when the new linked frame is created.
*
* @author m1b
* @version 2026-05-17
* @param {TextFrame} textFrame - an Illustrator TextFrame (area text or path text).
* @returns {TextFrame} - the overflow textFrame
*/
function addOverflowTextFrame(textFrame) {
const EXPAND_AMOUNT = 1000;
var overflowTextFrame;
var position = textFrame.position;
var width = textFrame.textPath.width;
var height = textFrame.textPath.height;
// temporarily expand the text frame to ensure all text content is fitting
textFrame.position = [0, 0];
textFrame.textPath.width += EXPAND_AMOUNT;
textFrame.textPath.height += EXPAND_AMOUNT;
try {
overflowTextFrame = textFrame.layer.textFrames.areaText(textFrame.layer.pathItems.rectangle(0, 150, 1000, 1000), TextOrientation.HORIZONTAL, textFrame);
} catch (error) { }
finally {
//clean up
textFrame.textPath.width = width;
textFrame.textPath.height = height;
textFrame.position = position;
}
return overflowTextFrame;
};
})();
Edit 2026-05-17: improved `addOverflowTextFrame`.