diff --git a/doc/global/grid.qdocconf b/doc/global/grid.qdocconf
new file mode 100644
index 00000000000..32b7b2a3cbc
--- /dev/null
+++ b/doc/global/grid.qdocconf
@@ -0,0 +1,59 @@
+# Macros for laying out a three-column grid structure of
+# items in online documentation. Takes three arguments,
+# wrapped in braces:
+# a link, a title, and a description.
+
+# Usage:
+# \grid
+# \griditem {qtqml-index.html} {Qt Qml} {Classes for QML and JavaScript languages.}
+# \griditem {qtquick-index.html} {Qt Quick} {
+# Declarative framework for dynamic apps with custom UIs.
+# }
+# \griditem {qtquickcontrols-index.html} {Qt Quick Controls} {
+# Lightweight QML types for creating performant user
+# interfaces.
+# }
+# \endgrid
+
+# Note: For offline documentation, these macros
+# generate a \table structure instead.
+
+
+macro.grid = \
+"\\if defined(onlinedocs)\n" \
+" \\raw HTML\n" \
+"
\n" \
+"
\n" \
+" \\endraw\n" \
+"\\else\n" \
+" \\table\n" \
+"\\endif\n"
+
+macro.griditem = \
+"\\detailedgriditem {\1} {\2} {\3} {#} {}"
+
+macro.detailedgriditem = \
+"\\if defined(onlinedocs)\n" \
+" \\raw HTML\n" \
+" - \n" \
+"
\n" \
+"
\2
\n" \
+"
\3
\n" \
+"
\n" \
+"
\n" \
+"
\n" \
+" \n" \
+" \\endraw\n" \
+"\\else\n" \
+" \\row \\li \\l {\1}{\2} \\li (\5) \3\n" \
+"\\endif\n"
+
+macro.endgrid = \
+"\\if defined(onlinedocs)\n" \
+" \\raw HTML\n" \
+"
\n" \
+" \\endraw\n" \
+"\\else\n" \
+" \\endtable\n" \
+"\\endif\n"
+
diff --git a/doc/global/macros.qdocconf b/doc/global/macros.qdocconf
index 0bb02323c18..59301ee4488 100644
--- a/doc/global/macros.qdocconf
+++ b/doc/global/macros.qdocconf
@@ -171,3 +171,5 @@ macro.qtpolicydeprecatedbehavior = "\\note The \\c{OLD} behavior of a policy is
#group.
#Must be placed directly under a \brief command
macro.techpreview = "(Technical preview)\n\n\\meta status {Technical preview}\n\\ingroup tech_preview\n"
+
+include(grid.qdocconf)