Building, integrating, or customizing apps and workflows within Microsoft Teams using developer tools and APIs
Based on your description, I understand you are experiencing rendering inconsistencies with Adaptive Cards (v1.5) specifically on the Teams iOS client. While Desktop, Web, and Android display the layout flawlessly, the iOS app renders a cramped, compressed layout with squeezed inputs, broken spacing, and inconsistent ColumnSet behavior.
Here are the answers to your specific questions, along with actionable layout adjustments to achieve cross-platform consistency.
1.Adaptive Cards are not rendered using a single unified engine across all platforms. Teams iOS relies on a native iOS rendering pipeline that interprets the card schema differently than the web-based (Desktop/Web) or Android engines. Historically, rendering glitches on Teams iOS frequently appear or change following native iOS app updates, independent of the schema version. A major culprit in your current JSON is the ColumnSet component; utilizing "width": "stretch" on side-by-side columns often breaks or collapses the structural layout on iOS mobile viewports, leading to the compressed look you described.
2.While Microsoft has not released an official public document declaring this exact structural compression as a static bug, spacing and column defects on mobile clients are heavily tracked. Microsoft maintains a dedicated repository to monitor, log, and resolve these specific behaviors:
- Official Mobile Tracking Repo: GitHub - Microsoft/Teams-AdaptiveCards-Mobile
3.To force Teams iOS to render cleanly without breaking the layout on Desktop or Android, you can apply the following mobile-optimization workarounds:
- Fix the ColumnSet Widths: Avoid using
"width": "stretch"inside aColumnSeton mobile-targeted cards. Instead, assign explicit weighted numbers or relative ratios (e.g.,"width": "1"or"width": "50"). Alternatively, on narrow mobile screens, stacked vertical inputs (full-width) offer a far cleaner user experience than side-by-side columns. - Adjust Spacing Properties: The
"spacing": "Small"property placed on text blocks immediately preceding inputs often collapses completely on iOS. Upgrade these boundaries to"spacing": "Medium"or"spacing": "Default". - Replace Markdown Bold: Using markdown syntax like
Expense Category:within a text block can sometimes trigger a font fallback (like Serif) on certain iOS sub-versions, messing up the design. Use the native"weight": "Bolder"property instead. - Downgrade Schema Version: Unless your application strictly relies on features unique to version 1.5, we highly recommend downgrading the schema version to
1.4(or even1.3). Version 1.4 has a significantly more stable and mature footprint on older native mobile rendering pipelines.
4.During internal testing, reproducing your original schema initially yielded the same squeezed constraints on iOS.
However, after converting the columns to explicit numeric weights, elevating the spacing, and relying on native properties rather than markdown, the rendering stabilized perfectly.
You can try using this modified version of your Adaptive Card:
{
"type": "AdaptiveCard",
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.5",
"body": [
{
"type": "Container",
"style": "emphasis",
"items": [
{
"type": "TextBlock",
"text": "Project Expense Confirmation",
"weight": "Bolder",
"size": "Large",
"wrap": true
},
{
"type": "TextBlock",
"text": "Please review and complete the required project expense details below.",
"wrap": true,
"spacing": "Small",
"isSubtle": true
}
]
},
{
"type": "FactSet",
"spacing": "Medium",
"facts": [
{ "title": "Project", "value": "Project Name Here" },
{ "title": "Expense Category", "value": "Travel / Meals / Lodging" }
]
},
{
"type": "TextBlock",
"text": "Transaction Date",
"weight": "Bolder",
"spacing": "Medium"
},
{
"type": "Input.Date",
"id": "transDate",
"isRequired": true,
"errorMessage": "Transaction date is required"
},
{
"type": "TextBlock",
"text": "Activity",
"weight": "Bolder",
"spacing": "Medium"
},
{
"type": "Input.ChoiceSet",
"id": "wbsHierarchyId",
"style": "compact",
"placeholder": "Select an activity",
"isRequired": true,
"errorMessage": "Please select an activity",
"choices": [
{ "title": "Activity 1", "value": "activity1" },
{ "title": "Activity 2", "value": "activity2" }
]
},
{
"type": "TextBlock",
"text": "Currency Code",
"weight": "Bolder",
"spacing": "Medium"
},
{
"type": "Input.ChoiceSet",
"id": "currencyCode",
"style": "compact",
"placeholder": "Select currency",
"value": "USD",
"isRequired": true,
"errorMessage": "Please select a currency",
"choices": [
{ "title": "USD", "value": "USD" },
{ "title": "EUR", "value": "EUR" },
{ "title": "VND", "value": "VND" }
]
},
{ "type": "ColumnSet", "columns": [ { "type": "Column", "width": "stretch", "items": [{ "type": "TextBlock", "text": "Tax Amount" }, { "type": "Input.Text", "id": "taxAmount" }] }, { "type": "Column", "width": "stretch", "items": [{ "type": "TextBlock", "text": "Total Amount" }, { "type": "Input.Text", "id": "totalAmount" }] } ] },
{
"type": "TextBlock",
"text": "External Comment",
"weight": "Bolder",
"spacing": "Medium"
},
{
"type": "Input.Text",
"id": "externalComment",
"placeholder": "Add any additional notes or comments",
"isMultiline": true,
"maxLength": 500
}
],
"actions": [
{
"type": "Action.Execute",
"title": "Create",
"verb": "create",
"style": "positive"
},
{
"type": "Action.Execute", "title": "Edit Category",
"verb": "editCategory"
},
{
"type": "Action.Execute",
"title": "Cancel",
"verb": "cancel",
"style": "destructive"
}
]
}
Please test this updated schema in your environment and see if it relieves the cramped layout on your iOS clients. I look forward to hearing your results!
If the answer is helpful, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.