L'introduction des dispositions Flex dans InDesign 2026 représente une évolution significative dans l'architecture de scripting. Contrairement aux objets plus périphériques, FlexObject opère au même niveau hiérarchique que les conteneurs de mise en page fondamentaux (Spread, MasterSpread) tout en exhibant des comportements similaires aux groupes et aux objets multi-états (MultiStateObject), mais avec des capacités de mise en page dynamique inspirées par le modèle CSS Flexbox très en vogue sur le Web dit « moderne ».

Bien que FlexObject implémente l'interface de n'importe quel PageItem (comme en témoigne son API à base de geometricBounds, transform et toutes les autres propriétés typiques à ce niveau hiérarchique), il s'inscrit dans l'architecture doté d'une nature similaire à celle d'un groupe ou d'un MSO. Comme stipulé dans le SDK d'InDesign, un PageItem s'entend d'un « contenu que l'utilisateur crée et édite sur une planche » — et une disposition Flex se range évidemment sous cette qualification. Le fait que les objets Document, Spread et Page exposent désormais une collection flexObjects (parallèle aux collections existantes : pageItems, groups, multiStateObjects, etc.) confirme bien le statut de FlexObject comme réalisant un conteneur de première classe.

Relations parent/enfant

En situation de parent, un composant FlexObject peut adresser une trentaine de types distincts, dont n'importe quel élément à valeur de PageItem, à savoir : les SplineItems (Polygon, Rectangle, Oval, GraphicLine…), les champs de formulaire ou objets de genre HTML (CheckBox, ComboBox, ListBox, RadioButton, TextBox, SignatureField…), les MediaItems (Sound, Movie) et la classe SVG, les blocs-texte (TextFrame et EndnoteTextFrame), les conteneurs composites (Group, MultiStateObject, Button), sans parler bien sûr des options et préférences rattachées à d'autres entités impliquant une disposition Flex (AnimationSetting, famille TransparencySetting, TextWrapPreference et ainsi de suite.)

L'introduction du type FlexObject entre InDesign 2025 et InDesign 2026 se caractérise par un apport et des changements massifs dans le scripting DOM.

Comme le montre en vue aérienne la capture ci-dessus (réalisée à partir d'un différentiel Git du DOM en XML), le taux de pénétration de la classe FlexObject dans l'architecture est très important : 65 classes ont été modifiées entre InDesign 20 et InDesign 21, la plupart de ces changements concernant directement la disposition Flex.

Si l'on s'en réfère aveuglément à l'API officielle, un FlexObject ne pourrait appartenir qu'à trois types parents : Spread, MasterSpread et FlexObject lui-même (permettant ainsi l'imbrication). Ce modèle asymétrique visait sans doute à illustrer la double nature du nouveau composant : se comporter comme un conteneur de haut niveau (enfant direct d'une planche) tout en conservant la flexibilité d'un PageItem quant au contenu enfant.

La doc officielle est loin de faire le tour de la question !

C'est en tout cas ce que dit l'explorateur de propriétés (ci-dessus affiché dans l'ESTK). Mais il est facile de vérifier, dans InDesign, que cette restriction ne s'applique nullement. Par exemple, on peut sans difficulté grouper deux dispositions Flex :

Création d'un groupe formé de deux dispositions Flex.

De quoi il résultera que chacun des composants FlexObject aura pour propriété parent le groupe en question. Je n'ai pas testé plus en profondeur ce type de configurations hybrides, mais compte tenu que la collection flexObjects est exposée dans tous les objets de genre PageItem (y compris les plus terminaux), il y a tout lieu de considérer qu'en fait, un FlexObject peut virtuellement appartenir à n'importe quelle catégorie de parent, et ce en de folles imbrications !

Note. — Il existe cependant certaines limitations propres au paradigme Flex, par exemple : « La disposition Flex ne prend pas en charge les blocs de texte à dimensionnement automatique. Si vous placez du texte à dimensionnement automatique dans une disposition Flex, le dimensionnement automatique sera désactivé. » (cf. Gérez les conflits de disposition Flex dans InDesign.)

La cartographie du Flex dans InDesign

Notons en premier lieu que les parallèles architecturaux avec CSS Flexbox sont flagrants :

CSS Flexbox Équivalent InDesign
Conteneur display:flex FlexObject (implémentation PageItem avec comportement flex)
Éléments flex Implémentations de genre PageItem avec enfants
Conteneurs flex imbriqués Confinement FlexObject récursif
Direction, justification, alignement flex Attributs spécifiques à FlexObject
Reflux dynamique Repositionnement automatique des enfants

Le modèle est clairement pensé pour les flux de publication numérique, où des mises en page dynamiques et responsives auront la part belle.

Schéma InDesign traditionnel :
Spread → Group/MSO → [éléments enfants, éventuellement multi-états]

Modèle FlexObject :
Spread → FlexObject → [éléments arrangés dynamiquement]

FlexObject suit le modèle établi d'InDesign pour les conteneurs en implémentant des propriétés de collection dédiées :

// Modèles existants
document.pageItems          // Enfants PageItem (toutes catégories)
document.groups             // Conteneurs Group
document.multiStateObjects  // Conteneurs MSO
// etc.
 
// Adjonction FlexObject
document.flexObjects        // Conteneurs FlexObject
spread.flexObjects          // ...vus d'une planche
page.flexObjects            // ...vus d'une page
// etc.
 

Mais une divergence cruciale doit être signalée ici : contrairement à la collection groups qui renvoie uniquement les enfants directs de l'objet hôte (Document, Spread, etc.), et donc ne tient pas compte des sous-groupes éventuels situés plus en profondeur hiérarchiquement, la collection flexObjects est exhaustive, c'est-à-dire qu'elle indexe tous les objets Flex visibles sous l'objet considéré, y compris les FlexObjects imbriqués. Les seules entités pouvant échapper à flexObjects sont celles éventuellement inscrites dans un état inactif en cas de configuration multi-états comportant des éléments FlexObject.

Cette singularité se reflète également dans la collection générique pageItems, qui a normalement vocation à renvoyer tous les « enfants directs » (quelle que soit leur nature), par opposition au tableau allPageItems. Ainsi, même lorsqu'un FlexObject se situe à un niveau hiérarchique plus profond, il est néanmoins indexé parmi les pageItems de l'objet hôte. Si vous cuisinez un script qui doit tenir compte des emboîtements, il faudra donc vous méfier de cette incohérence architecturale : étant donnés trois objets Flex fx1, fx2, fx3 listés dans la collection flexObjects (ou pageItems) d'un certain objet obj, vous ne pouvez pas conclure que obj est le parent direct de ces trois entités, il est possible par exemple que fx3.parent===fx2.parent===fx1.

Note. — Pour être complet sur le chapitre des rapports hiérarchiques, ajoutons que les propriétés collectrices (flexObjects, pageItems) ignorent comme d'habitude ce qui se passe dans les objets ancrés sous-jacents. Comme le savent tous les développeurs InDesign, l'exploration des objets ancrés doit emprunter un circuit radicalement différent via les conteneurs textuels. Dans ce type de situations, un FlexObject ancré (au même titre que n'importe quel objet ancré) a pour parent un Character.

Cas d'un FlexObject ancré. (Il n'est alors pas visible dans mySpread.flexObjects)

API FlexObject (fonctionnalités spécifiques)

Dans la mesure où FlexObject implémente le système de mise en page issu du Flexbox CSS, il expose essentiellement l'API d'un Group à quoi s'ajoutent les fonctionnalités Flex. Voici donc les propriétés et méthodes spécifiques à FlexObject par rapport au conteneur Group traditionnel (je conserve les descriptions documentées en anglais).

• Propriétés FlexObject

NAME TYPE DESCRIPTION
flexWidthMode enum The width behavior of the flex container: FlexWidthHeightMode or FlexEnum enum.
flexHeightMode enum The height behavior of the flex container: FlexWidthHeightMode or FlexEnum enum.
flexDirection enum The direction of the flex container: FlexDirection
flexWrap enum Whether flex items are forced onto one line or can wrap onto multiple lines: FlexWrap
justifyContent enum Defines how the browser distributes space between and around content items along the main-axis: FlexPosition or FlexSpacing enum.
alignItems enum Defines the default behavior for how flex items are laid out along the cross axis: FlexPosition or FlexEnum enum.
alignContent enum Aligns a flex container's lines within when there is extra space in the cross-axis: FlexPosition or FlexEnum enum.
flexPaddingTop num/str Top padding (MeasurementUnit), range: 0–720 pt.
flexPaddingRight num/str Right padding (MeasurementUnit), range: 0–720 pt.
flexPaddingBottom num/str Bottom padding (MeasurementUnit), range: 0–720 pt.
flexPaddingLeft num/str Left padding (MeasurementUnit), range: 0–720 pt.
flexGapRow num/str Row gap between flex items (MeasurementUnit), range: 0–720 pt.
flexGapColumn num/str Column gap between flex items (MeasurementUnit), range: 0–720 pt.

Note. — Le type FlexEnum fournit uniquement l'énumérateur FlexEnum.FLEX_AUTO (attribut utilisable pour toute propriété acceptant un paramètre Flex automatique.) Nous ne détaillerons pas ici les autres énumerateurs, ils sont bien documentés et reflètent exactement les préférences disponibles dans le panneau Disposition Flex d'InDesign.

• Méthodes FlexObject

NAME TYPE DESCRIPTION
addFlexObject(pgItem) undef Add page item to flex container at the end.
addPageItemAfter(refItem, pgItem) undef Add a page item after the specified page item.
addPageItemBefore(refItem, pgItem) undef Add a page item before the specified page item.
addPageItemAt(positionIndex:num, pgItem) undef Add a page item at the specified index.
addPageItemAtStart(pgItem) undef Add a page item at the start of the container.
addPageItemAtEnd(pgItem) undef Add a page item at the end of the container.

Les méthodes d'adjonction listées ci-dessus se démarquent de l'API d'un Group du seul fait de leur existence, car un groupe ne dispose d'aucune méthode directe d'insertion de composants — problème souvent rencontré par les développeurs et jusqu'alors résolu par le truchement de MSO temporaires ou astuces similaires.

Note. — Autre point critique : à ce jour un FlexObject ne fournit aucune méthode unflex analogue à Group.ungroup(). En clair, il n'y pas de façon simple de supprimer la disposition Flex par un script, sauf à invoquer l'action de menu associée !

On peut bien sûr créer un FlexObject ex nihilo à partir de la méthode add(…) d'une collection flexObjects. Un aspect original de cette approche est qu'elle autorise la formation d'un FlexObject totalement vide (c'est-à-dire, sans aucun élément enfant) :

// Test de FlexObjects.add() sans argument
var flx = mySpread.flexObjects.add();
 

Un FlexObject « vide » possède encore une aire intrinsèque (geometricBounds).

On doit aussi retenir que contrairement à un Group ou à un MultiStateObject, un FlexObject instancie un authentique conteneur physique (pas seulement logique), doté de ses propres attributs de couleur, de bordure, etc.

Note. — À l'heure où je publie ces lignes, je n'ai pas encore déterminé la fonction de l'argument flexDescription (string), premier paramètre optionnel de la méthode FlexObjects.add(...). Malgré son nom et son type obscurs, on peut conjecturer que cet argument permettrait de charger des éléments préexistants lors de la création du FlexObject (?). Je reviendrai sur ce point dès que j'en saurai plus…

Si vous développez ou mettez à jour des scripts InDesign faisant intervenir des conteneurs FlexObject, un aspect capital à garder à l'esprit est que, par définition, les éléments enfants perdent des degrés de liberté en matière de positionnement dans la maquette. Il conviendra donc de sécuriser toute procédure contrôlant les coordonnées, les dimensions ou les transformations spatiales de tels objets.

Les FlexObjects, des groupes dynamiques ?

Le parallélisme avec les groupes et objets multi-états traduit clairement que le composant FlexObject répond à une stratégie de conteneur. Le modèle d'accès via les collections permet des opérations par lot sur tous les composants flex d'un document, des scénarios d'automatisation cohérents et une migration facile des groupes statiques vers les dispositions dynamiques (et vice versa).

Le fait qu'une disposition Flex puisse en contenir d'autres (exactement comme un groupe peut contenir des sous-groupes) permet d'imaginer des modèles de mise en page imbriqués d'une complexité quelconque :

FlexObject (mise en page horizontale)
  ├─ FlexObject (mise en page verticale)
  │   ├─ TextFrame
  │   └─ Image
  ├─ FlexObject (mise en page verticale)
  │   ├─ Button
  │   └─ Button
  └─ Rectangle
 

Toute l'innovation réside en ce que FlexObject rend cette récursivité sémantiquement active dans votre projet : chaque niveau d'imbrication peut spécifier ses propres propriétés de direction, spacing, padding et alignment, produisant une mise en page adaptative au sens dynamique du terme, option qui échappait aux mises en page liquides et variantes de mise en page.

Les développeurs de scripts ne pourront pas ignorer trop longtemps le composant FlexObject, car il représente une évolution stratégique dans l'architecture InDesign :

   — du figé à l'adaptatif : passer du positionnement manuel à une mise en page guidée par des contraintes (tout en conservant le contrôle des rapports dans l'espace) ;

   — du statique au dynamique : concevoir des composants et variantes où la mise en page s'ajuste d'elle-même lorsque le contenu change, éliminant en tout ou partie le réajustement manuel (pensez aux projets reposant sur la fusion de données !) ;

   — du manuel au déclaratif : permettre aux maquettistes de spécifier des « intentions de mise en page » (direction, espacement, alignement) plutôt que des coordonnées explicites.