[{"data":1,"prerenderedAt":2329},["ShallowReactive",2],{"blog-en-nest-row-in-col":3},{"id":4,"title":5,"author":6,"body":10,"date":902,"description":2295,"draft":2296,"extension":2297,"howTo":2298,"image":2319,"meta":2320,"navigation":486,"path":2321,"seo":2322,"stem":2323,"tags":2324,"updated":2319,"__hash__":2328},"blog/blog/025.nest-row-in-col.md","How do I nest a Row inside a Col in gpdf?",{"name":7,"url":8,"avatar":9},"Taiki Noda","https://nadai.dev/en/about","https://nadai.dev/og-default.png",{"type":11,"value":12,"toc":2282},"minimark",[13,18,56,60,107,111,121,428,462,466,469,1171,1188,1196,1202,1625,1643,1647,1658,1875,1888,1892,1907,1962,1978,1982,1988,2195,2202,2206,2242,2246,2249,2266,2278],[14,15,17],"h2",{"id":16},"the-question-in-other-words","The question, in other words",[19,20,21,22,26,27,30,31,33,34,36,37,39,40,47,48,51,52,55],"p",{},"You've used Bootstrap or Tailwind, where ",[23,24,25],"code",{},".row"," and ",[23,28,29],{},".col"," nest freely. You can put a ",[23,32,25],{}," inside a ",[23,35,29],{}," inside another ",[23,38,25],{}," and the grid keeps cascading. You sit down with ",[41,42,46],"a",{"href":43,"rel":44},"https://github.com/gpdf-dev/gpdf",[45],"nofollow","gpdf",", see the same ",[23,49,50],{},"r.Col(span, fn)"," idiom, and reach for ",[23,53,54],{},"c.Row(...)"," inside the column callback. It's not there. Was that an oversight?",[14,57,59],{"id":58},"tldr","TL;DR",[19,61,62,63,67,68,71,72,75,76,75,79,75,82,75,85,75,88,91,92,95,96,99,100,103,104,106],{},"No. ",[64,65,66],"strong",{},"gpdf's 12-column grid is flat on purpose."," ",[23,69,70],{},"ColBuilder"," only accepts content — ",[23,73,74],{},"Text",", ",[23,77,78],{},"Image",[23,80,81],{},"Table",[23,83,84],{},"Box",[23,86,87],{},"List",[23,89,90],{},"Spacer"," — and ",[23,93,94],{},"Row","/",[23,97,98],{},"AutoRow"," live on ",[23,101,102],{},"PageBuilder",", not on ",[23,105,70],{},". If you came here looking for the syntax, there isn't one. Read on for the three things that replace it.",[14,108,110],{"id":109},"the-shape-of-the-api","The shape of the API",[19,112,113,114,116,117,120],{},"Here's what ",[23,115,70],{},"'s method set actually contains (from ",[23,118,119],{},"gpdf/template/grid.go","):",[122,123,128],"pre",{"className":124,"code":125,"language":126,"meta":127,"style":127},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","func (c *ColBuilder) Text(text string, opts ...TextOption)\nfunc (c *ColBuilder) Image(src []byte, opts ...ImageOption)\nfunc (c *ColBuilder) Box(fn func(c *ColBuilder), opts ...BoxOption)\nfunc (c *ColBuilder) Table(header []string, rows [][]string, opts ...TableOption)\nfunc (c *ColBuilder) Line(opts ...LineOption)\nfunc (c *ColBuilder) List(items []string, opts ...ListOption)\nfunc (c *ColBuilder) Spacer(height document.Value)\n// …PageNumber, TotalPages, RichText, QRCode, Barcode\n","go","",[23,129,130,184,224,270,319,349,387,421],{"__ignoreMap":127},[131,132,135,139,142,146,149,152,155,159,162,165,169,172,175,178,181],"span",{"class":133,"line":134},"line",1,[131,136,138],{"class":137},"sMK4o","func",[131,140,141],{"class":137}," (",[131,143,145],{"class":144},"sHdIc","c ",[131,147,148],{"class":137},"*",[131,150,70],{"class":151},"sBMFI",[131,153,154],{"class":137},")",[131,156,158],{"class":157},"s2Zo4"," Text",[131,160,161],{"class":137},"(",[131,163,164],{"class":144},"text",[131,166,168],{"class":167},"spNyl"," string",[131,170,171],{"class":137},",",[131,173,174],{"class":144}," opts",[131,176,177],{"class":137}," ...",[131,179,180],{"class":151},"TextOption",[131,182,183],{"class":137},")\n",[131,185,187,189,191,193,195,197,199,202,204,207,210,213,215,217,219,222],{"class":133,"line":186},2,[131,188,138],{"class":137},[131,190,141],{"class":137},[131,192,145],{"class":144},[131,194,148],{"class":137},[131,196,70],{"class":151},[131,198,154],{"class":137},[131,200,201],{"class":157}," Image",[131,203,161],{"class":137},[131,205,206],{"class":144},"src",[131,208,209],{"class":137}," []",[131,211,212],{"class":167},"byte",[131,214,171],{"class":137},[131,216,174],{"class":144},[131,218,177],{"class":137},[131,220,221],{"class":151},"ImageOption",[131,223,183],{"class":137},[131,225,227,229,231,233,235,237,239,242,244,247,250,253,256,258,261,263,265,268],{"class":133,"line":226},3,[131,228,138],{"class":137},[131,230,141],{"class":137},[131,232,145],{"class":144},[131,234,148],{"class":137},[131,236,70],{"class":151},[131,238,154],{"class":137},[131,240,241],{"class":157}," Box",[131,243,161],{"class":137},[131,245,246],{"class":144},"fn",[131,248,249],{"class":137}," func(",[131,251,252],{"class":144},"c",[131,254,255],{"class":137}," *",[131,257,70],{"class":151},[131,259,260],{"class":137},"),",[131,262,174],{"class":144},[131,264,177],{"class":137},[131,266,267],{"class":151},"BoxOption",[131,269,183],{"class":137},[131,271,273,275,277,279,281,283,285,288,290,293,295,298,300,303,306,308,310,312,314,317],{"class":133,"line":272},4,[131,274,138],{"class":137},[131,276,141],{"class":137},[131,278,145],{"class":144},[131,280,148],{"class":137},[131,282,70],{"class":151},[131,284,154],{"class":137},[131,286,287],{"class":157}," Table",[131,289,161],{"class":137},[131,291,292],{"class":144},"header",[131,294,209],{"class":137},[131,296,297],{"class":167},"string",[131,299,171],{"class":137},[131,301,302],{"class":144}," rows",[131,304,305],{"class":137}," [][]",[131,307,297],{"class":167},[131,309,171],{"class":137},[131,311,174],{"class":144},[131,313,177],{"class":137},[131,315,316],{"class":151},"TableOption",[131,318,183],{"class":137},[131,320,322,324,326,328,330,332,334,337,339,342,344,347],{"class":133,"line":321},5,[131,323,138],{"class":137},[131,325,141],{"class":137},[131,327,145],{"class":144},[131,329,148],{"class":137},[131,331,70],{"class":151},[131,333,154],{"class":137},[131,335,336],{"class":157}," Line",[131,338,161],{"class":137},[131,340,341],{"class":144},"opts",[131,343,177],{"class":137},[131,345,346],{"class":151},"LineOption",[131,348,183],{"class":137},[131,350,352,354,356,358,360,362,364,367,369,372,374,376,378,380,382,385],{"class":133,"line":351},6,[131,353,138],{"class":137},[131,355,141],{"class":137},[131,357,145],{"class":144},[131,359,148],{"class":137},[131,361,70],{"class":151},[131,363,154],{"class":137},[131,365,366],{"class":157}," List",[131,368,161],{"class":137},[131,370,371],{"class":144},"items",[131,373,209],{"class":137},[131,375,297],{"class":167},[131,377,171],{"class":137},[131,379,174],{"class":144},[131,381,177],{"class":137},[131,383,384],{"class":151},"ListOption",[131,386,183],{"class":137},[131,388,390,392,394,396,398,400,402,405,407,410,413,416,419],{"class":133,"line":389},7,[131,391,138],{"class":137},[131,393,141],{"class":137},[131,395,145],{"class":144},[131,397,148],{"class":137},[131,399,70],{"class":151},[131,401,154],{"class":137},[131,403,404],{"class":157}," Spacer",[131,406,161],{"class":137},[131,408,409],{"class":144},"height",[131,411,412],{"class":151}," document",[131,414,415],{"class":137},".",[131,417,418],{"class":151},"Value",[131,420,183],{"class":137},[131,422,424],{"class":133,"line":423},8,[131,425,427],{"class":426},"sHwdD","// …PageNumber, TotalPages, RichText, QRCode, Barcode\n",[19,429,430,431,433,434,433,436,439,440,443,444,447,448,450,451,454,455,458,459,461],{},"No ",[23,432,94],{},". No ",[23,435,98],{},[23,437,438],{},"Col",". The ",[23,441,442],{},"Col → Row"," path doesn't exist as a method, and ",[23,445,446],{},"c.Box(fn, ...)"," is the closest thing — but ",[23,449,84],{}," accepts another ",[23,452,453],{},"*ColBuilder",", not a row. You can nest ",[64,456,457],{},"columns inside columns"," (sort of, via ",[23,460,84],{},"), but you can't open a new horizontal row inside a column. That's the constraint.",[14,463,465],{"id":464},"idiom-1-sibling-rows-at-the-page-level","Idiom 1 — Sibling rows at the page level",[19,467,468],{},"This is what 90% of \"nested row\" patterns actually want.",[122,470,472],{"className":124,"code":471,"language":126,"meta":127,"style":127},"package main\n\nimport (\n    \"log\"\n    \"os\"\n\n    \"github.com/gpdf-dev/gpdf\"\n    \"github.com/gpdf-dev/gpdf/document\"\n    \"github.com/gpdf-dev/gpdf/template\"\n)\n\nfunc main() {\n    doc := gpdf.NewDocument(\n        gpdf.WithPageSize(document.A4),\n        gpdf.WithMargins(document.UniformEdges(document.Mm(15))),\n    )\n    page := doc.AddPage()\n\n    // What you wanted to write (but can't):\n    //\n    //   page.AutoRow(func(r *template.RowBuilder) {\n    //       r.Col(8, func(c *template.ColBuilder) {\n    //           c.Row(...) ❌ doesn't exist\n    //       })\n    //   })\n\n    // What you write instead:\n    page.AutoRow(func(r *template.RowBuilder) {\n        r.Col(8, func(c *template.ColBuilder) {\n            c.Text(\"Article title\", template.FontSize(18), template.Bold())\n        })\n        r.Col(4, func(c *template.ColBuilder) {\n            c.Text(\"2026-05-16\")\n        })\n    })\n    page.AutoRow(func(r *template.RowBuilder) {\n        r.Col(8, func(c *template.ColBuilder) {\n            c.Text(\"Lead paragraph spans the same 8-wide column.\")\n        })\n        r.Col(4, func(c *template.ColBuilder) {\n            c.Text(\"by Taiki Noda\")\n        })\n    })\n\n    data, err := doc.Generate()\n    if err != nil {\n        log.Fatal(err)\n    }\n    _ = os.WriteFile(\"flat.pdf\", data, 0o644)\n}\n",[23,473,474,482,488,497,508,517,521,530,539,549,554,559,573,594,618,655,661,680,685,691,697,703,709,715,721,727,732,738,768,801,849,855,887,907,912,918,943,974,994,999,1030,1050,1055,1060,1065,1087,1103,1121,1127,1165],{"__ignoreMap":127},[131,475,476,479],{"class":133,"line":134},[131,477,478],{"class":137},"package",[131,480,481],{"class":151}," main\n",[131,483,484],{"class":133,"line":186},[131,485,487],{"emptyLinePlaceholder":486},true,"\n",[131,489,490,494],{"class":133,"line":226},[131,491,493],{"class":492},"s7zQu","import",[131,495,496],{"class":137}," (\n",[131,498,499,502,505],{"class":133,"line":272},[131,500,501],{"class":137},"    \"",[131,503,504],{"class":151},"log",[131,506,507],{"class":137},"\"\n",[131,509,510,512,515],{"class":133,"line":321},[131,511,501],{"class":137},[131,513,514],{"class":151},"os",[131,516,507],{"class":137},[131,518,519],{"class":133,"line":351},[131,520,487],{"emptyLinePlaceholder":486},[131,522,523,525,528],{"class":133,"line":389},[131,524,501],{"class":137},[131,526,527],{"class":151},"github.com/gpdf-dev/gpdf",[131,529,507],{"class":137},[131,531,532,534,537],{"class":133,"line":423},[131,533,501],{"class":137},[131,535,536],{"class":151},"github.com/gpdf-dev/gpdf/document",[131,538,507],{"class":137},[131,540,542,544,547],{"class":133,"line":541},9,[131,543,501],{"class":137},[131,545,546],{"class":151},"github.com/gpdf-dev/gpdf/template",[131,548,507],{"class":137},[131,550,552],{"class":133,"line":551},10,[131,553,183],{"class":137},[131,555,557],{"class":133,"line":556},11,[131,558,487],{"emptyLinePlaceholder":486},[131,560,562,564,567,570],{"class":133,"line":561},12,[131,563,138],{"class":137},[131,565,566],{"class":157}," main",[131,568,569],{"class":137},"()",[131,571,572],{"class":137}," {\n",[131,574,576,580,583,586,588,591],{"class":133,"line":575},13,[131,577,579],{"class":578},"sTEyZ","    doc ",[131,581,582],{"class":137},":=",[131,584,585],{"class":578}," gpdf",[131,587,415],{"class":137},[131,589,590],{"class":157},"NewDocument",[131,592,593],{"class":137},"(\n",[131,595,597,600,602,605,607,610,612,615],{"class":133,"line":596},14,[131,598,599],{"class":578},"        gpdf",[131,601,415],{"class":137},[131,603,604],{"class":157},"WithPageSize",[131,606,161],{"class":137},[131,608,609],{"class":578},"document",[131,611,415],{"class":137},[131,613,614],{"class":578},"A4",[131,616,617],{"class":137},"),\n",[131,619,621,623,625,628,630,632,634,637,639,641,643,646,648,652],{"class":133,"line":620},15,[131,622,599],{"class":578},[131,624,415],{"class":137},[131,626,627],{"class":157},"WithMargins",[131,629,161],{"class":137},[131,631,609],{"class":578},[131,633,415],{"class":137},[131,635,636],{"class":157},"UniformEdges",[131,638,161],{"class":137},[131,640,609],{"class":578},[131,642,415],{"class":137},[131,644,645],{"class":157},"Mm",[131,647,161],{"class":137},[131,649,651],{"class":650},"sbssI","15",[131,653,654],{"class":137},"))),\n",[131,656,658],{"class":133,"line":657},16,[131,659,660],{"class":137},"    )\n",[131,662,664,667,669,672,674,677],{"class":133,"line":663},17,[131,665,666],{"class":578},"    page ",[131,668,582],{"class":137},[131,670,671],{"class":578}," doc",[131,673,415],{"class":137},[131,675,676],{"class":157},"AddPage",[131,678,679],{"class":137},"()\n",[131,681,683],{"class":133,"line":682},18,[131,684,487],{"emptyLinePlaceholder":486},[131,686,688],{"class":133,"line":687},19,[131,689,690],{"class":426},"    // What you wanted to write (but can't):\n",[131,692,694],{"class":133,"line":693},20,[131,695,696],{"class":426},"    //\n",[131,698,700],{"class":133,"line":699},21,[131,701,702],{"class":426},"    //   page.AutoRow(func(r *template.RowBuilder) {\n",[131,704,706],{"class":133,"line":705},22,[131,707,708],{"class":426},"    //       r.Col(8, func(c *template.ColBuilder) {\n",[131,710,712],{"class":133,"line":711},23,[131,713,714],{"class":426},"    //           c.Row(...) ❌ doesn't exist\n",[131,716,718],{"class":133,"line":717},24,[131,719,720],{"class":426},"    //       })\n",[131,722,724],{"class":133,"line":723},25,[131,725,726],{"class":426},"    //   })\n",[131,728,730],{"class":133,"line":729},26,[131,731,487],{"emptyLinePlaceholder":486},[131,733,735],{"class":133,"line":734},27,[131,736,737],{"class":426},"    // What you write instead:\n",[131,739,741,744,746,748,751,754,756,759,761,764,766],{"class":133,"line":740},28,[131,742,743],{"class":578},"    page",[131,745,415],{"class":137},[131,747,98],{"class":157},[131,749,750],{"class":137},"(func(",[131,752,753],{"class":144},"r",[131,755,255],{"class":137},[131,757,758],{"class":151},"template",[131,760,415],{"class":137},[131,762,763],{"class":151},"RowBuilder",[131,765,154],{"class":137},[131,767,572],{"class":137},[131,769,771,774,776,778,780,783,785,787,789,791,793,795,797,799],{"class":133,"line":770},29,[131,772,773],{"class":578},"        r",[131,775,415],{"class":137},[131,777,438],{"class":157},[131,779,161],{"class":137},[131,781,782],{"class":650},"8",[131,784,171],{"class":137},[131,786,249],{"class":137},[131,788,252],{"class":144},[131,790,255],{"class":137},[131,792,758],{"class":151},[131,794,415],{"class":137},[131,796,70],{"class":151},[131,798,154],{"class":137},[131,800,572],{"class":137},[131,802,804,807,809,811,813,816,820,822,824,827,829,832,834,837,839,841,843,846],{"class":133,"line":803},30,[131,805,806],{"class":578},"            c",[131,808,415],{"class":137},[131,810,74],{"class":157},[131,812,161],{"class":137},[131,814,815],{"class":137},"\"",[131,817,819],{"class":818},"sfazB","Article title",[131,821,815],{"class":137},[131,823,171],{"class":137},[131,825,826],{"class":578}," template",[131,828,415],{"class":137},[131,830,831],{"class":157},"FontSize",[131,833,161],{"class":137},[131,835,836],{"class":650},"18",[131,838,260],{"class":137},[131,840,826],{"class":578},[131,842,415],{"class":137},[131,844,845],{"class":157},"Bold",[131,847,848],{"class":137},"())\n",[131,850,852],{"class":133,"line":851},31,[131,853,854],{"class":137},"        })\n",[131,856,858,860,862,864,866,869,871,873,875,877,879,881,883,885],{"class":133,"line":857},32,[131,859,773],{"class":578},[131,861,415],{"class":137},[131,863,438],{"class":157},[131,865,161],{"class":137},[131,867,868],{"class":650},"4",[131,870,171],{"class":137},[131,872,249],{"class":137},[131,874,252],{"class":144},[131,876,255],{"class":137},[131,878,758],{"class":151},[131,880,415],{"class":137},[131,882,70],{"class":151},[131,884,154],{"class":137},[131,886,572],{"class":137},[131,888,890,892,894,896,898,900,903,905],{"class":133,"line":889},33,[131,891,806],{"class":578},[131,893,415],{"class":137},[131,895,74],{"class":157},[131,897,161],{"class":137},[131,899,815],{"class":137},[131,901,902],{"class":818},"2026-05-16",[131,904,815],{"class":137},[131,906,183],{"class":137},[131,908,910],{"class":133,"line":909},34,[131,911,854],{"class":137},[131,913,915],{"class":133,"line":914},35,[131,916,917],{"class":137},"    })\n",[131,919,921,923,925,927,929,931,933,935,937,939,941],{"class":133,"line":920},36,[131,922,743],{"class":578},[131,924,415],{"class":137},[131,926,98],{"class":157},[131,928,750],{"class":137},[131,930,753],{"class":144},[131,932,255],{"class":137},[131,934,758],{"class":151},[131,936,415],{"class":137},[131,938,763],{"class":151},[131,940,154],{"class":137},[131,942,572],{"class":137},[131,944,946,948,950,952,954,956,958,960,962,964,966,968,970,972],{"class":133,"line":945},37,[131,947,773],{"class":578},[131,949,415],{"class":137},[131,951,438],{"class":157},[131,953,161],{"class":137},[131,955,782],{"class":650},[131,957,171],{"class":137},[131,959,249],{"class":137},[131,961,252],{"class":144},[131,963,255],{"class":137},[131,965,758],{"class":151},[131,967,415],{"class":137},[131,969,70],{"class":151},[131,971,154],{"class":137},[131,973,572],{"class":137},[131,975,977,979,981,983,985,987,990,992],{"class":133,"line":976},38,[131,978,806],{"class":578},[131,980,415],{"class":137},[131,982,74],{"class":157},[131,984,161],{"class":137},[131,986,815],{"class":137},[131,988,989],{"class":818},"Lead paragraph spans the same 8-wide column.",[131,991,815],{"class":137},[131,993,183],{"class":137},[131,995,997],{"class":133,"line":996},39,[131,998,854],{"class":137},[131,1000,1002,1004,1006,1008,1010,1012,1014,1016,1018,1020,1022,1024,1026,1028],{"class":133,"line":1001},40,[131,1003,773],{"class":578},[131,1005,415],{"class":137},[131,1007,438],{"class":157},[131,1009,161],{"class":137},[131,1011,868],{"class":650},[131,1013,171],{"class":137},[131,1015,249],{"class":137},[131,1017,252],{"class":144},[131,1019,255],{"class":137},[131,1021,758],{"class":151},[131,1023,415],{"class":137},[131,1025,70],{"class":151},[131,1027,154],{"class":137},[131,1029,572],{"class":137},[131,1031,1033,1035,1037,1039,1041,1043,1046,1048],{"class":133,"line":1032},41,[131,1034,806],{"class":578},[131,1036,415],{"class":137},[131,1038,74],{"class":157},[131,1040,161],{"class":137},[131,1042,815],{"class":137},[131,1044,1045],{"class":818},"by Taiki Noda",[131,1047,815],{"class":137},[131,1049,183],{"class":137},[131,1051,1053],{"class":133,"line":1052},42,[131,1054,854],{"class":137},[131,1056,1058],{"class":133,"line":1057},43,[131,1059,917],{"class":137},[131,1061,1063],{"class":133,"line":1062},44,[131,1064,487],{"emptyLinePlaceholder":486},[131,1066,1068,1071,1073,1076,1078,1080,1082,1085],{"class":133,"line":1067},45,[131,1069,1070],{"class":578},"    data",[131,1072,171],{"class":137},[131,1074,1075],{"class":578}," err ",[131,1077,582],{"class":137},[131,1079,671],{"class":578},[131,1081,415],{"class":137},[131,1083,1084],{"class":157},"Generate",[131,1086,679],{"class":137},[131,1088,1090,1093,1095,1098,1101],{"class":133,"line":1089},46,[131,1091,1092],{"class":492},"    if",[131,1094,1075],{"class":578},[131,1096,1097],{"class":137},"!=",[131,1099,1100],{"class":137}," nil",[131,1102,572],{"class":137},[131,1104,1106,1109,1111,1114,1116,1119],{"class":133,"line":1105},47,[131,1107,1108],{"class":578},"        log",[131,1110,415],{"class":137},[131,1112,1113],{"class":157},"Fatal",[131,1115,161],{"class":137},[131,1117,1118],{"class":578},"err",[131,1120,183],{"class":137},[131,1122,1124],{"class":133,"line":1123},48,[131,1125,1126],{"class":137},"    }\n",[131,1128,1130,1133,1136,1139,1141,1144,1146,1148,1151,1153,1155,1158,1160,1163],{"class":133,"line":1129},49,[131,1131,1132],{"class":578},"    _ ",[131,1134,1135],{"class":137},"=",[131,1137,1138],{"class":578}," os",[131,1140,415],{"class":137},[131,1142,1143],{"class":157},"WriteFile",[131,1145,161],{"class":137},[131,1147,815],{"class":137},[131,1149,1150],{"class":818},"flat.pdf",[131,1152,815],{"class":137},[131,1154,171],{"class":137},[131,1156,1157],{"class":578}," data",[131,1159,171],{"class":137},[131,1161,1162],{"class":650}," 0o644",[131,1164,183],{"class":137},[131,1166,1168],{"class":133,"line":1167},50,[131,1169,1170],{"class":137},"}\n",[19,1172,1173,1174,1176,1177,1180,1181,1183,1184,1187],{},"The two ",[23,1175,98],{},"s share the same ",[23,1178,1179],{},"8+4"," spans, so the columns line up visually. There's no sub-grid; there's a flat sequence of rows that happen to use the same carve. The output is identical to what you'd get from a CSS layout that nested ",[23,1182,25],{}," inside ",[23,1185,1186],{},".col-8"," — because the only thing the nested form bought you was syntactic locality, and gpdf prefers you spend that on width consistency instead.",[14,1189,1191,1192,1195],{"id":1190},"idiom-2-cbox-for-visual-grouping","Idiom 2 — ",[23,1193,1194],{},"c.Box"," for visual grouping",[19,1197,1198,1199,1201],{},"If the real motivation was \"I want a bordered card with two stacked elements inside this column,\" you wanted ",[23,1200,84],{},", not a sub-row:",[122,1203,1205],{"className":124,"code":1204,"language":126,"meta":127,"style":127},"page.AutoRow(func(r *template.RowBuilder) {\n    r.Col(6, func(c *template.ColBuilder) {\n        c.Box(func(c *template.ColBuilder) {\n            c.Text(\"Bill to\", template.Bold())\n            c.Text(\"Acme GmbH\")\n            c.Text(\"Hamburg, Germany\")\n        },\n            template.WithBoxBorder(template.Border(\n                template.BorderWidth(document.Pt(1)),\n                template.BorderColor(pdf.RGBHex(0xBDBDBD)),\n            )),\n            template.WithBoxPadding(document.UniformEdges(document.Mm(4))),\n        )\n    })\n    r.Col(6, func(c *template.ColBuilder) {\n        c.Box(func(c *template.ColBuilder) {\n            c.Text(\"Ship to\", template.Bold())\n            c.Text(\"Same as billing\")\n        },\n            template.WithBoxPadding(document.UniformEdges(document.Mm(4))),\n        )\n    })\n})\n",[23,1206,1207,1232,1264,1289,1316,1335,1354,1359,1380,1407,1433,1438,1469,1474,1478,1508,1532,1559,1578,1582,1612,1616,1620],{"__ignoreMap":127},[131,1208,1209,1212,1214,1216,1218,1220,1222,1224,1226,1228,1230],{"class":133,"line":134},[131,1210,1211],{"class":578},"page",[131,1213,415],{"class":137},[131,1215,98],{"class":157},[131,1217,750],{"class":137},[131,1219,753],{"class":144},[131,1221,255],{"class":137},[131,1223,758],{"class":151},[131,1225,415],{"class":137},[131,1227,763],{"class":151},[131,1229,154],{"class":137},[131,1231,572],{"class":137},[131,1233,1234,1237,1239,1241,1243,1246,1248,1250,1252,1254,1256,1258,1260,1262],{"class":133,"line":186},[131,1235,1236],{"class":578},"    r",[131,1238,415],{"class":137},[131,1240,438],{"class":157},[131,1242,161],{"class":137},[131,1244,1245],{"class":650},"6",[131,1247,171],{"class":137},[131,1249,249],{"class":137},[131,1251,252],{"class":144},[131,1253,255],{"class":137},[131,1255,758],{"class":151},[131,1257,415],{"class":137},[131,1259,70],{"class":151},[131,1261,154],{"class":137},[131,1263,572],{"class":137},[131,1265,1266,1269,1271,1273,1275,1277,1279,1281,1283,1285,1287],{"class":133,"line":226},[131,1267,1268],{"class":578},"        c",[131,1270,415],{"class":137},[131,1272,84],{"class":157},[131,1274,750],{"class":137},[131,1276,252],{"class":144},[131,1278,255],{"class":137},[131,1280,758],{"class":151},[131,1282,415],{"class":137},[131,1284,70],{"class":151},[131,1286,154],{"class":137},[131,1288,572],{"class":137},[131,1290,1291,1293,1295,1297,1299,1301,1304,1306,1308,1310,1312,1314],{"class":133,"line":272},[131,1292,806],{"class":578},[131,1294,415],{"class":137},[131,1296,74],{"class":157},[131,1298,161],{"class":137},[131,1300,815],{"class":137},[131,1302,1303],{"class":818},"Bill to",[131,1305,815],{"class":137},[131,1307,171],{"class":137},[131,1309,826],{"class":578},[131,1311,415],{"class":137},[131,1313,845],{"class":157},[131,1315,848],{"class":137},[131,1317,1318,1320,1322,1324,1326,1328,1331,1333],{"class":133,"line":321},[131,1319,806],{"class":578},[131,1321,415],{"class":137},[131,1323,74],{"class":157},[131,1325,161],{"class":137},[131,1327,815],{"class":137},[131,1329,1330],{"class":818},"Acme GmbH",[131,1332,815],{"class":137},[131,1334,183],{"class":137},[131,1336,1337,1339,1341,1343,1345,1347,1350,1352],{"class":133,"line":351},[131,1338,806],{"class":578},[131,1340,415],{"class":137},[131,1342,74],{"class":157},[131,1344,161],{"class":137},[131,1346,815],{"class":137},[131,1348,1349],{"class":818},"Hamburg, Germany",[131,1351,815],{"class":137},[131,1353,183],{"class":137},[131,1355,1356],{"class":133,"line":389},[131,1357,1358],{"class":137},"        },\n",[131,1360,1361,1364,1366,1369,1371,1373,1375,1378],{"class":133,"line":423},[131,1362,1363],{"class":578},"            template",[131,1365,415],{"class":137},[131,1367,1368],{"class":157},"WithBoxBorder",[131,1370,161],{"class":137},[131,1372,758],{"class":578},[131,1374,415],{"class":137},[131,1376,1377],{"class":157},"Border",[131,1379,593],{"class":137},[131,1381,1382,1385,1387,1390,1392,1394,1396,1399,1401,1404],{"class":133,"line":541},[131,1383,1384],{"class":578},"                template",[131,1386,415],{"class":137},[131,1388,1389],{"class":157},"BorderWidth",[131,1391,161],{"class":137},[131,1393,609],{"class":578},[131,1395,415],{"class":137},[131,1397,1398],{"class":157},"Pt",[131,1400,161],{"class":137},[131,1402,1403],{"class":650},"1",[131,1405,1406],{"class":137},")),\n",[131,1408,1409,1411,1413,1416,1418,1421,1423,1426,1428,1431],{"class":133,"line":551},[131,1410,1384],{"class":578},[131,1412,415],{"class":137},[131,1414,1415],{"class":157},"BorderColor",[131,1417,161],{"class":137},[131,1419,1420],{"class":578},"pdf",[131,1422,415],{"class":137},[131,1424,1425],{"class":157},"RGBHex",[131,1427,161],{"class":137},[131,1429,1430],{"class":650},"0xBDBDBD",[131,1432,1406],{"class":137},[131,1434,1435],{"class":133,"line":556},[131,1436,1437],{"class":137},"            )),\n",[131,1439,1440,1442,1444,1447,1449,1451,1453,1455,1457,1459,1461,1463,1465,1467],{"class":133,"line":561},[131,1441,1363],{"class":578},[131,1443,415],{"class":137},[131,1445,1446],{"class":157},"WithBoxPadding",[131,1448,161],{"class":137},[131,1450,609],{"class":578},[131,1452,415],{"class":137},[131,1454,636],{"class":157},[131,1456,161],{"class":137},[131,1458,609],{"class":578},[131,1460,415],{"class":137},[131,1462,645],{"class":157},[131,1464,161],{"class":137},[131,1466,868],{"class":650},[131,1468,654],{"class":137},[131,1470,1471],{"class":133,"line":575},[131,1472,1473],{"class":137},"        )\n",[131,1475,1476],{"class":133,"line":596},[131,1477,917],{"class":137},[131,1479,1480,1482,1484,1486,1488,1490,1492,1494,1496,1498,1500,1502,1504,1506],{"class":133,"line":620},[131,1481,1236],{"class":578},[131,1483,415],{"class":137},[131,1485,438],{"class":157},[131,1487,161],{"class":137},[131,1489,1245],{"class":650},[131,1491,171],{"class":137},[131,1493,249],{"class":137},[131,1495,252],{"class":144},[131,1497,255],{"class":137},[131,1499,758],{"class":151},[131,1501,415],{"class":137},[131,1503,70],{"class":151},[131,1505,154],{"class":137},[131,1507,572],{"class":137},[131,1509,1510,1512,1514,1516,1518,1520,1522,1524,1526,1528,1530],{"class":133,"line":657},[131,1511,1268],{"class":578},[131,1513,415],{"class":137},[131,1515,84],{"class":157},[131,1517,750],{"class":137},[131,1519,252],{"class":144},[131,1521,255],{"class":137},[131,1523,758],{"class":151},[131,1525,415],{"class":137},[131,1527,70],{"class":151},[131,1529,154],{"class":137},[131,1531,572],{"class":137},[131,1533,1534,1536,1538,1540,1542,1544,1547,1549,1551,1553,1555,1557],{"class":133,"line":663},[131,1535,806],{"class":578},[131,1537,415],{"class":137},[131,1539,74],{"class":157},[131,1541,161],{"class":137},[131,1543,815],{"class":137},[131,1545,1546],{"class":818},"Ship to",[131,1548,815],{"class":137},[131,1550,171],{"class":137},[131,1552,826],{"class":578},[131,1554,415],{"class":137},[131,1556,845],{"class":157},[131,1558,848],{"class":137},[131,1560,1561,1563,1565,1567,1569,1571,1574,1576],{"class":133,"line":682},[131,1562,806],{"class":578},[131,1564,415],{"class":137},[131,1566,74],{"class":157},[131,1568,161],{"class":137},[131,1570,815],{"class":137},[131,1572,1573],{"class":818},"Same as billing",[131,1575,815],{"class":137},[131,1577,183],{"class":137},[131,1579,1580],{"class":133,"line":687},[131,1581,1358],{"class":137},[131,1583,1584,1586,1588,1590,1592,1594,1596,1598,1600,1602,1604,1606,1608,1610],{"class":133,"line":693},[131,1585,1363],{"class":578},[131,1587,415],{"class":137},[131,1589,1446],{"class":157},[131,1591,161],{"class":137},[131,1593,609],{"class":578},[131,1595,415],{"class":137},[131,1597,636],{"class":157},[131,1599,161],{"class":137},[131,1601,609],{"class":578},[131,1603,415],{"class":137},[131,1605,645],{"class":157},[131,1607,161],{"class":137},[131,1609,868],{"class":650},[131,1611,654],{"class":137},[131,1613,1614],{"class":133,"line":699},[131,1615,1473],{"class":137},[131,1617,1618],{"class":133,"line":705},[131,1619,917],{"class":137},[131,1621,1622],{"class":133,"line":711},[131,1623,1624],{"class":137},"})\n",[19,1626,1627,450,1629,1631,1632,1635,1636,1638,1639,1642],{},[23,1628,84],{},[23,1630,453],{},", which means everything stacked inside is ",[64,1633,1634],{},"vertical",". You can't split a Box horizontally either — for that, you go back to Idiom 1. But for the \"card\" pattern that nested-row syntax often gets reached for, this is the right tool. The ",[23,1637,1194],{}," line in ",[23,1640,1641],{},"gpdf/template/grid.go:246"," is the only nesting the grid does, and it's deliberately one-dimensional.",[14,1644,1646],{"id":1645},"idiom-3-plan-the-sub-grid-into-12-columns-directly","Idiom 3 — Plan the sub-grid into 12 columns directly",[19,1648,1649,1650,1653,1654,1657],{},"Sometimes you genuinely want a 2-column layout inside what feels like a half-page section: a thumbnail and a caption inside the left half of the page, a paragraph on the right. The instinct is ",[23,1651,1652],{},"Col(6) > Row > Col(6) + Col(6)",". The flat equivalent is just ",[23,1655,1656],{},"Col(3) + Col(3) + Col(6)",":",[122,1659,1661],{"className":124,"code":1660,"language":126,"meta":127,"style":127},"page.AutoRow(func(r *template.RowBuilder) {\n    r.Col(3, func(c *template.ColBuilder) {\n        c.Image(thumbBytes)\n    })\n    r.Col(3, func(c *template.ColBuilder) {\n        c.Text(\"Photo by Ansel Adams\", template.Italic())\n        c.Text(\"1942\")\n    })\n    r.Col(6, func(c *template.ColBuilder) {\n        c.Text(\"The body paragraph fills the right half of the page.\")\n    })\n})\n",[23,1662,1663,1687,1718,1733,1737,1767,1795,1814,1818,1848,1867,1871],{"__ignoreMap":127},[131,1664,1665,1667,1669,1671,1673,1675,1677,1679,1681,1683,1685],{"class":133,"line":134},[131,1666,1211],{"class":578},[131,1668,415],{"class":137},[131,1670,98],{"class":157},[131,1672,750],{"class":137},[131,1674,753],{"class":144},[131,1676,255],{"class":137},[131,1678,758],{"class":151},[131,1680,415],{"class":137},[131,1682,763],{"class":151},[131,1684,154],{"class":137},[131,1686,572],{"class":137},[131,1688,1689,1691,1693,1695,1697,1700,1702,1704,1706,1708,1710,1712,1714,1716],{"class":133,"line":186},[131,1690,1236],{"class":578},[131,1692,415],{"class":137},[131,1694,438],{"class":157},[131,1696,161],{"class":137},[131,1698,1699],{"class":650},"3",[131,1701,171],{"class":137},[131,1703,249],{"class":137},[131,1705,252],{"class":144},[131,1707,255],{"class":137},[131,1709,758],{"class":151},[131,1711,415],{"class":137},[131,1713,70],{"class":151},[131,1715,154],{"class":137},[131,1717,572],{"class":137},[131,1719,1720,1722,1724,1726,1728,1731],{"class":133,"line":226},[131,1721,1268],{"class":578},[131,1723,415],{"class":137},[131,1725,78],{"class":157},[131,1727,161],{"class":137},[131,1729,1730],{"class":578},"thumbBytes",[131,1732,183],{"class":137},[131,1734,1735],{"class":133,"line":272},[131,1736,917],{"class":137},[131,1738,1739,1741,1743,1745,1747,1749,1751,1753,1755,1757,1759,1761,1763,1765],{"class":133,"line":321},[131,1740,1236],{"class":578},[131,1742,415],{"class":137},[131,1744,438],{"class":157},[131,1746,161],{"class":137},[131,1748,1699],{"class":650},[131,1750,171],{"class":137},[131,1752,249],{"class":137},[131,1754,252],{"class":144},[131,1756,255],{"class":137},[131,1758,758],{"class":151},[131,1760,415],{"class":137},[131,1762,70],{"class":151},[131,1764,154],{"class":137},[131,1766,572],{"class":137},[131,1768,1769,1771,1773,1775,1777,1779,1782,1784,1786,1788,1790,1793],{"class":133,"line":351},[131,1770,1268],{"class":578},[131,1772,415],{"class":137},[131,1774,74],{"class":157},[131,1776,161],{"class":137},[131,1778,815],{"class":137},[131,1780,1781],{"class":818},"Photo by Ansel Adams",[131,1783,815],{"class":137},[131,1785,171],{"class":137},[131,1787,826],{"class":578},[131,1789,415],{"class":137},[131,1791,1792],{"class":157},"Italic",[131,1794,848],{"class":137},[131,1796,1797,1799,1801,1803,1805,1807,1810,1812],{"class":133,"line":389},[131,1798,1268],{"class":578},[131,1800,415],{"class":137},[131,1802,74],{"class":157},[131,1804,161],{"class":137},[131,1806,815],{"class":137},[131,1808,1809],{"class":818},"1942",[131,1811,815],{"class":137},[131,1813,183],{"class":137},[131,1815,1816],{"class":133,"line":423},[131,1817,917],{"class":137},[131,1819,1820,1822,1824,1826,1828,1830,1832,1834,1836,1838,1840,1842,1844,1846],{"class":133,"line":541},[131,1821,1236],{"class":578},[131,1823,415],{"class":137},[131,1825,438],{"class":157},[131,1827,161],{"class":137},[131,1829,1245],{"class":650},[131,1831,171],{"class":137},[131,1833,249],{"class":137},[131,1835,252],{"class":144},[131,1837,255],{"class":137},[131,1839,758],{"class":151},[131,1841,415],{"class":137},[131,1843,70],{"class":151},[131,1845,154],{"class":137},[131,1847,572],{"class":137},[131,1849,1850,1852,1854,1856,1858,1860,1863,1865],{"class":133,"line":551},[131,1851,1268],{"class":578},[131,1853,415],{"class":137},[131,1855,74],{"class":157},[131,1857,161],{"class":137},[131,1859,815],{"class":137},[131,1861,1862],{"class":818},"The body paragraph fills the right half of the page.",[131,1864,815],{"class":137},[131,1866,183],{"class":137},[131,1868,1869],{"class":133,"line":556},[131,1870,917],{"class":137},[131,1872,1873],{"class":133,"line":561},[131,1874,1624],{"class":137},[19,1876,1877,1880,1881,1883,1884,1887],{},[23,1878,1879],{},"3 + 3"," together equal ",[23,1882,1245],{},", so the thumbnail/caption pair occupies the left half exactly. Twelve factors into 2, 3, 4, and 6, so a nested grid almost always collapses cleanly. If your nested grid was ",[23,1885,1886],{},"Col(8) > Row > Col(7) + Col(5)",", that doesn't collapse — but those numbers don't mean anything in a real document either. Pick the flat version that does.",[14,1889,1891],{"id":1890},"why-no-nesting","Why no nesting",[19,1893,1894,1895,1898,1899,1902,1903,1906],{},"A flat grid resolves widths in one pass. The row is a percentage of the page width minus margins. Each ",[23,1896,1897],{},"Col(span)"," is ",[23,1900,1901],{},"span / 12"," of that. Done. There is no recursion, no width-of-a-width-of-a-width, no parent context to thread through the layout engine. The line in ",[23,1904,1905],{},"grid.go"," that computes column width is exactly one line:",[122,1908,1910],{"className":124,"code":1909,"language":126,"meta":127,"style":127},"Width: document.Pct(float64(col.span) / float64(gridColumns) * 100),\n",[23,1911,1912],{"__ignoreMap":127},[131,1913,1914,1917,1919,1921,1923,1926,1928,1931,1933,1936,1938,1940,1942,1945,1948,1950,1953,1955,1957,1960],{"class":133,"line":134},[131,1915,1916],{"class":578},"Width",[131,1918,1657],{"class":137},[131,1920,412],{"class":578},[131,1922,415],{"class":137},[131,1924,1925],{"class":157},"Pct",[131,1927,161],{"class":137},[131,1929,1930],{"class":167},"float64",[131,1932,161],{"class":137},[131,1934,1935],{"class":578},"col",[131,1937,415],{"class":137},[131,1939,131],{"class":578},[131,1941,154],{"class":137},[131,1943,1944],{"class":137}," /",[131,1946,1947],{"class":167}," float64",[131,1949,161],{"class":137},[131,1951,1952],{"class":578},"gridColumns",[131,1954,154],{"class":137},[131,1956,255],{"class":137},[131,1958,1959],{"class":650}," 100",[131,1961,617],{"class":137},[19,1963,1964,1965,1183,1968,1183,1971,1974,1975,1977],{},"Add nesting and that line becomes a tree walk. Suddenly you need to decide what ",[23,1966,1967],{},"Col(6)",[23,1969,1970],{},"Col(8)",[23,1972,1973],{},"Col(12)"," means — is ",[23,1976,1245],{}," 50% of the parent column, or 50% of the row, or 50% of the page? Bootstrap chose \"50% of the parent\" and added breakpoints and gutters to make that bearable. PDFs don't have breakpoints. PDFs don't have a fluid container. Borrowing the nesting idiom would import three problems we don't have, in exchange for syntactic shorthand we don't need.",[14,1979,1981],{"id":1980},"but-i-really-want-syntactic-locality","\"But I really want syntactic locality\"",[19,1983,1984,1985,1987],{},"Fair. The downside of flattening is that two ",[23,1986,98],{}," calls that conceptually belong together can drift apart in the source as you edit. A small helper closes that gap:",[122,1989,1991],{"className":124,"code":1990,"language":126,"meta":127,"style":127},"func card(page *template.PageBuilder, title, body string) {\n    page.AutoRow(func(r *template.RowBuilder) {\n        r.Col(12, func(c *template.ColBuilder) {\n            c.Text(title, template.Bold())\n        })\n    })\n    page.AutoRow(func(r *template.RowBuilder) {\n        r.Col(12, func(c *template.ColBuilder) {\n            c.Text(body)\n        })\n    })\n}\n",[23,1992,1993,2028,2052,2083,2106,2110,2114,2138,2168,2183,2187,2191],{"__ignoreMap":127},[131,1994,1995,1997,2000,2002,2004,2006,2008,2010,2012,2014,2017,2019,2022,2024,2026],{"class":133,"line":134},[131,1996,138],{"class":137},[131,1998,1999],{"class":157}," card",[131,2001,161],{"class":137},[131,2003,1211],{"class":144},[131,2005,255],{"class":137},[131,2007,758],{"class":151},[131,2009,415],{"class":137},[131,2011,102],{"class":151},[131,2013,171],{"class":137},[131,2015,2016],{"class":144}," title",[131,2018,171],{"class":137},[131,2020,2021],{"class":144}," body",[131,2023,168],{"class":167},[131,2025,154],{"class":137},[131,2027,572],{"class":137},[131,2029,2030,2032,2034,2036,2038,2040,2042,2044,2046,2048,2050],{"class":133,"line":186},[131,2031,743],{"class":578},[131,2033,415],{"class":137},[131,2035,98],{"class":157},[131,2037,750],{"class":137},[131,2039,753],{"class":144},[131,2041,255],{"class":137},[131,2043,758],{"class":151},[131,2045,415],{"class":137},[131,2047,763],{"class":151},[131,2049,154],{"class":137},[131,2051,572],{"class":137},[131,2053,2054,2056,2058,2060,2062,2065,2067,2069,2071,2073,2075,2077,2079,2081],{"class":133,"line":226},[131,2055,773],{"class":578},[131,2057,415],{"class":137},[131,2059,438],{"class":157},[131,2061,161],{"class":137},[131,2063,2064],{"class":650},"12",[131,2066,171],{"class":137},[131,2068,249],{"class":137},[131,2070,252],{"class":144},[131,2072,255],{"class":137},[131,2074,758],{"class":151},[131,2076,415],{"class":137},[131,2078,70],{"class":151},[131,2080,154],{"class":137},[131,2082,572],{"class":137},[131,2084,2085,2087,2089,2091,2093,2096,2098,2100,2102,2104],{"class":133,"line":272},[131,2086,806],{"class":578},[131,2088,415],{"class":137},[131,2090,74],{"class":157},[131,2092,161],{"class":137},[131,2094,2095],{"class":578},"title",[131,2097,171],{"class":137},[131,2099,826],{"class":578},[131,2101,415],{"class":137},[131,2103,845],{"class":157},[131,2105,848],{"class":137},[131,2107,2108],{"class":133,"line":321},[131,2109,854],{"class":137},[131,2111,2112],{"class":133,"line":351},[131,2113,917],{"class":137},[131,2115,2116,2118,2120,2122,2124,2126,2128,2130,2132,2134,2136],{"class":133,"line":389},[131,2117,743],{"class":578},[131,2119,415],{"class":137},[131,2121,98],{"class":157},[131,2123,750],{"class":137},[131,2125,753],{"class":144},[131,2127,255],{"class":137},[131,2129,758],{"class":151},[131,2131,415],{"class":137},[131,2133,763],{"class":151},[131,2135,154],{"class":137},[131,2137,572],{"class":137},[131,2139,2140,2142,2144,2146,2148,2150,2152,2154,2156,2158,2160,2162,2164,2166],{"class":133,"line":423},[131,2141,773],{"class":578},[131,2143,415],{"class":137},[131,2145,438],{"class":157},[131,2147,161],{"class":137},[131,2149,2064],{"class":650},[131,2151,171],{"class":137},[131,2153,249],{"class":137},[131,2155,252],{"class":144},[131,2157,255],{"class":137},[131,2159,758],{"class":151},[131,2161,415],{"class":137},[131,2163,70],{"class":151},[131,2165,154],{"class":137},[131,2167,572],{"class":137},[131,2169,2170,2172,2174,2176,2178,2181],{"class":133,"line":541},[131,2171,806],{"class":578},[131,2173,415],{"class":137},[131,2175,74],{"class":157},[131,2177,161],{"class":137},[131,2179,2180],{"class":578},"body",[131,2182,183],{"class":137},[131,2184,2185],{"class":133,"line":551},[131,2186,854],{"class":137},[131,2188,2189],{"class":133,"line":556},[131,2190,917],{"class":137},[131,2192,2193],{"class":133,"line":561},[131,2194,1170],{"class":137},[19,2196,2197,2198,2201],{},"The locality lives in your function, not in the API. gpdf doesn't ship ",[23,2199,2200],{},"card"," because it's three lines and your version will fit your document better than ours would.",[14,2203,2205],{"id":2204},"related-recipes","Related recipes",[2207,2208,2209,2217,2227,2234],"ul",{},[2210,2211,2212,2216],"li",{},[41,2213,2215],{"href":2214},"/blog/12-column-grid","How does the 12-column grid work in gpdf?"," — the grid itself, in detail",[2210,2218,2219,2222,2223,2226],{},[41,2220,2221],{"href":2214},"How do I align a column to the right edge of a row?"," — empty ",[23,2224,2225],{},"Col(n)"," as a spacer trick",[2210,2228,2229,2233],{},[41,2230,2232],{"href":2231},"/blog/invoice-pdf-go-under-50-lines","Generate an invoice PDF in Go in under 50 lines"," — a flat-grid layout that handles a full document",[2210,2235,2236,2241],{},[41,2237,2240],{"href":2238,"rel":2239},"https://gpdf.dev/docs/guide/layout",[45],"Layout guide"," — full reference for rows, columns, and Box",[14,2243,2245],{"id":2244},"try-gpdf","Try gpdf",[19,2247,2248],{},"gpdf is a Go library for generating PDFs. MIT licensed, zero external dependencies, native CJK support.",[122,2250,2254],{"className":2251,"code":2252,"language":2253,"meta":127,"style":127},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","go get github.com/gpdf-dev/gpdf\n","bash",[23,2255,2256],{"__ignoreMap":127},[131,2257,2258,2260,2263],{"class":133,"line":134},[131,2259,126],{"class":151},[131,2261,2262],{"class":818}," get",[131,2264,2265],{"class":818}," github.com/gpdf-dev/gpdf\n",[19,2267,2268,2272,2273],{},[41,2269,2271],{"href":43,"rel":2270},[45],"⭐ Star on GitHub"," · ",[41,2274,2277],{"href":2275,"rel":2276},"https://gpdf.dev/docs/quickstart",[45],"Read the docs",[2279,2280,2281],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}",{"title":127,"searchDepth":186,"depth":186,"links":2283},[2284,2285,2286,2287,2288,2290,2291,2292,2293,2294],{"id":16,"depth":186,"text":17},{"id":58,"depth":186,"text":59},{"id":109,"depth":186,"text":110},{"id":464,"depth":186,"text":465},{"id":1190,"depth":186,"text":2289},"Idiom 2 — c.Box for visual grouping",{"id":1645,"depth":186,"text":1646},{"id":1890,"depth":186,"text":1891},{"id":1980,"depth":186,"text":1981},{"id":2204,"depth":186,"text":2205},{"id":2244,"depth":186,"text":2245},"You can't — ColBuilder has no Row method in gpdf. The 12-column grid is flat by design. Here are the three idioms that replace nested rows.",false,"md",{"name":2299,"totalTime":2300,"tools":2301,"steps":2303},"Replace a nested Row-in-Col layout in gpdf with a flat-grid idiom","PT10M",[2302,527],"Go 1.22+",[2304,2307,2310,2313,2316],{"name":2305,"text":2306},"Stop reaching for c.Row","ColBuilder has no Row or AutoRow method. page.AutoRow and page.Row only exist on PageBuilder. If your editor's autocomplete doesn't show c.Row, that's the API telling you no — not a missing import.",{"name":2308,"text":2309},"Decide what you actually needed the nested row for","Three cases cover almost everything. (1) Two visual rows that share a column boundary — you wanted a sub-layout. (2) A header and a body inside a card — you wanted visual grouping. (3) A 2×2 grid inside one column — you wanted a sub-grid.",{"name":2311,"text":2312},"For a sub-layout, use sibling AutoRows at the page level","Stack two page.AutoRow calls with the same Col spans. The columns line up visually because the row width is the same. You don't lose anything by flattening — rows are already independent.",{"name":2314,"text":2315},"For visual grouping, use c.Box inside the column","c.Box(fn, WithBoxBorder, WithBoxBackground, WithBoxPadding) wraps a stack of content in a styled container. It is not a sub-grid — it accepts Text, Image, Table, etc., not Row — but it gives you the card-with-border look that 80% of nested-row attempts were really chasing.",{"name":2317,"text":2318},"For a real sub-grid, plan it at finer 12-column spans","Instead of nesting a 6+6 inside a Col(6), express the whole layout as 3+3+6 at the top level. The 12-column grid factors into halves, thirds, quarters, and sixths — most nested patterns collapse cleanly into one flat row.",null,{},"/blog/nest-row-in-col",{"title":5,"description":2295},"blog/025.nest-row-in-col",[2325,2326,2327],"recipe","tutorial","templates","_Xl3YciuvNUOo4PaQExUwxF920y6ygRnp4p9dgcJkj0",1779199010118]