Getting ControlAddIns to have the right size is a science, and something I spend way too much time on, mostly without any useful results, so this time, I turn to a hack. Check it out:

In this video, Erik tackles one of his biggest frustrations with Control Add-ins in Business Central: their inability to properly fill the available screen space. When a control add-in shares a page with other controls (like a repeater in a grid layout), it often fails to stretch vertically to use all the available real estate. Erik walks through diagnosing the problem using browser developer tools and arrives at a clever JavaScript hack that dynamically sizes the control add-in’s iframe to match the available height.
The Problem: Control Add-ins Won’t Fill the Screen
Even when you set HorizontalStretch and VerticalStretch to true in your control add-in definition, the vertical stretch often doesn’t work as expected — especially when the add-in sits alongside other controls on the page. The horizontal stretch works fine, but the add-in stubbornly refuses to take up the full vertical space.
Here’s the control add-in definition Erik is working with:
controladdin testaddin
{
StartupScript = 'startup.js';
Scripts = 'script.js', 'raphael.js', 'flowchart-latest.js';
HorizontalStretch = true;
VerticalStretch = true;
//RequestedHeight = 600;
event ImAmReady(Parameters: JsonObject);
procedure HeresSomeData(Data: JsonObject);
procedure Draw(code: Text);
}
The page uses a grid layout with the control add-in and other controls side by side:
page 50132 "Test Page"
{
SourceTable = Customer;
Editable = true;
PageType = List;
layout
{
area(Content)
{
grid(g)
{
usercontrol(x; testaddin)
{
ApplicationArea = all;
trigger ImAmReady(Parameters: JsonObject)
var
JsonTools: Codeunit "Json Tools";
begin
CurrPage.x.Draw(TheCode);
end;
}
field(TheCode; TheCode)
{
ApplicationArea = all;
MultiLine = true;
trigger OnValidate()
begin
CurrPage.x.Draw(TheCode);
end;
}
}
}
}
var
TheCode: Text;
}
Why RequestedHeight Doesn’t Solve It
You might think setting RequestedHeight = 600 would help, and it does give you a fixed height — but that’s exactly the problem. If the browser window is taller than 600 pixels, you waste space. If it’s shorter, you get an unnecessary scrollbar. The RequestedHeight property ends up becoming a min-height on the iframe, which isn’t what we want at all. We want the add-in to dynamically fill whatever space is available.
Diagnosing with Browser Dev Tools
Erik opens the browser’s developer tools and inspects the DOM to understand why the add-in isn’t stretching. The control add-in’s content lives inside an iframe, and even though the inner HTML elements are all set to height: 100%, the iframe itself is constrained. Walking up the DOM tree, he finds that the iframe and several parent divs are stuck at the fixed height (e.g., 600px when RequestedHeight is set), while a higher-level container div actually has the correct, full height.
The key discovery: a div with the CSS class control-addin-form has the correct height that represents the available space. By reading the height from this element and applying it to the iframe, the add-in can fill the screen properly.
The Hack: Seven Lines of JavaScript
The solution lives entirely in the startup script. Here’s the final version:
var controlAddIn = document.getElementById('controlAddIn');
var heightindicator = window.parent.document.querySelector('div[class~="control-addin-form"]');
if (heightindicator != null) {
window.frameElement.style.height = heightindicator.offsetHeight.toString() + "px";
window.addEventListener('resize', function (event) {
window.frameElement.style.height = heightindicator.offsetHeight.toString() + "px";
}, true);
}
How It Works, Step by Step
- Find the height reference element: Using
window.parent.document.querySelector('div[class~="control-addin-form"]'), we escape out of the iframe (viawindow.parent) and query the parent page’s DOM for a div with the classcontrol-addin-form. This element has the actual available height we want. - Guard against failure: The
if (heightindicator != null)check is crucial. The class namecontrol-addin-formis an internal Microsoft implementation detail — it could change in any hotfix or update. If it stops existing, the code gracefully falls back to the default sizing behavior instead of breaking. - Apply the height to the iframe:
window.frameElementgives us the iframe element from inside the iframe itself — a handy shortcut. We read theoffsetHeight(the actual rendered pixel height, not a CSS property), convert it to a string, append"px"for the CSS unit, and assign it to the iframe’sstyle.height. - Handle window resizing: An event listener on the
resizeevent re-applies the height whenever the browser window changes size, so the add-in stays properly sized. Becauseheightindicatoris declared as a global variable, it remains accessible inside the event handler’s closure.
Key JavaScript Gotchas Erik Encountered
.heightvs.offsetHeight: The.heightproperty on a DOM element returnsundefinedbecause it’s not a standard property for divs. The actual computed pixel height is available through.offsetHeight.- Units matter: Assigning a raw integer to
style.heightdoes nothing — CSS requires a unit. You must convert the number to a string and append"px". - JavaScript’s dynamic types: You can freely concatenate a number with a string in JavaScript (
offsetHeight.toString() + "px"). This is quite different from AL’s strict typing.
Important Caveat: This Is a Hack
Erik emphasizes that this approach relies on an internal CSS class name (control-addin-form) that Microsoft has never documented or promised to keep stable. It could break with any update. That’s why the null check on line 5 of the startup script is the most important line — it ensures your add-in degrades gracefully if Microsoft changes their DOM structure, falling back to whatever default sizing the control add-in would normally have.
Summary
Control add-ins in Business Central struggle with vertical sizing when placed alongside other controls on a page. The VerticalStretch property doesn’t always work, and RequestedHeight gives a fixed size that creates its own problems. By using JavaScript to read the available height from a parent container in the DOM and applying it to the iframe, you can make control add-ins properly fill the screen — and with a resize event listener, they stay responsive when the window size changes. Just remember: this is an undocumented hack, so always include a null check fallback for when Microsoft inevitably changes their internal DOM structure.