|
55 | 55 | margin-inline-start: 0.5rem; // Additional spacing to prevent bullet collision (direct children only) |
56 | 56 | } |
57 | 57 | } |
| 58 | + |
| 59 | +// A CTA button written on its own line in markdown — `<a class="btn btn-primary |
| 60 | +// mt-3 …">` — becomes its own <p>, and that paragraph already carries the 16px |
| 61 | +// rhythm margin. The `mt-3` utility then stacks a second 16px inside it, so the |
| 62 | +// button ends up 32px below the preceding line but only 16px above the next one. |
| 63 | +// Drop the utility when the button is alone in its paragraph and let the |
| 64 | +// paragraph margin do the spacing, which puts the CTA on the same rhythm as |
| 65 | +// every other block. `!important` is required because Primer's spacing |
| 66 | +// utilities are themselves !important. |
| 67 | +// |
| 68 | +// `:only-child` is doing real work here — it is what keeps the two cases apart: |
| 69 | +// - CTA callouts (`product:`/`permissions:` frontmatter) put the button after |
| 70 | +// a <br> INSIDE the prose paragraph, so there is no paragraph margin above |
| 71 | +// it and `mt-3` is the only thing separating it from the text. |
| 72 | +// - The side-by-side Yes/No `.btn-outline` pairs are two buttons in one |
| 73 | +// paragraph. |
| 74 | +// Neither is an only child, so both keep their margin. |
| 75 | +.markdown-body p > a.btn:only-child { |
| 76 | + margin-top: 0 !important; |
| 77 | +} |
| 78 | + |
| 79 | +// @primer/css holds `.btn` at `white-space: nowrap`, which a button cannot |
| 80 | +// honour and still stay inside a narrow column. The longest CTA label — "Set up |
| 81 | +// a trial of GitHub Enterprise Cloud", 322px — is wider than the article column |
| 82 | +// below a ~420px viewport and wider than the callout's text column below ~390px, |
| 83 | +// so the button ran past the content edge and was clipped. |
| 84 | +// |
| 85 | +// Letting the label wrap fixes it with no breakpoint to guess at. An |
| 86 | +// inline-block is shrink-to-fit — min(max-content, available) — so |
| 87 | +// `white-space: normal` changes nothing until max-content exceeds the space |
| 88 | +// available: at every width where the button already fits it still renders on |
| 89 | +// one line, byte-identical. That also makes it self-correcting for longer |
| 90 | +// translated labels and for the narrower column a callout gives the same button. |
| 91 | +.markdown-body a.btn, |
| 92 | +.permissions-statement a.btn, |
| 93 | +.product-statement a.btn { |
| 94 | + white-space: normal; |
| 95 | + |
| 96 | + // Wrapping alone orphaned the trailing octicon on a line of its own: the |
| 97 | + // space between the label <span> and the icon is a valid break point, and the |
| 98 | + // label filled the first line exactly. Laying the button out as a flex row |
| 99 | + // instead lets the label wrap within itself and keeps the icon beside it, |
| 100 | + // vertically centred. At widths where nothing wraps the result is within a |
| 101 | + // pixel of the inline-block it replaces: same 17px left inset, same 21px |
| 102 | + // right inset, same 32px height, still one line. The `gap` below covers the |
| 103 | + // one thing that does change. |
| 104 | + display: inline-flex; |
| 105 | + align-items: center; |
| 106 | + |
| 107 | + // Flex layout eats the one thing that was separating the label from the icon. |
| 108 | + // The markup is `<span>Label</span> {% octicon "link-external" %}`, and that |
| 109 | + // literal space does survive Liquid and the markdown pipeline as a real text |
| 110 | + // node — but a whitespace-only text node between two flex items is not itself |
| 111 | + // a flex item, so no box is generated for it and the label ends up touching |
| 112 | + // the icon. `gap` puts the space back. |
| 113 | + // |
| 114 | + // 4px rather than the measured width of that space glyph, because a space is |
| 115 | + // font- and locale-dependent — it measures differently on two machines here — |
| 116 | + // while 4px is the value Primer itself already uses between a button's icon |
| 117 | + // and its label. The button ends up a fraction of a pixel wider than it was |
| 118 | + // rather than most of a space narrower, on a number the design system owns. |
| 119 | + // |
| 120 | + // Only the label/icon gap is restored. Primer's `.btn .octicon` also carries |
| 121 | + // `margin-right: 4px`, which assumes a LEADING icon and so lands outside the |
| 122 | + // trailing icon on these CTAs, giving them 21px of inset on the right against |
| 123 | + // 17px on the left. That asymmetry is what ships today, so it stays — zeroing |
| 124 | + // it would restyle every CTA on the site, which is a different change from |
| 125 | + // keeping a long label inside its column. |
| 126 | + gap: 4px; |
| 127 | + |
| 128 | + // The octicon is a flex item now, and flex items shrink before their container |
| 129 | + // overflows. Once the label wraps, the icon is the only thing left to give, so |
| 130 | + // the 16px glyph was rendering at 11px in a 240px callout column. It is a |
| 131 | + // fixed-size icon; the label is what should absorb a narrow column. |
| 132 | + .octicon { |
| 133 | + flex-shrink: 0; |
| 134 | + } |
| 135 | +} |
0 commit comments