line
is a block-level element, this means that it basically introduces a parbreak
if necessary. Usually, to put a block level element inline you wrap it in box
, which is the defacto inline container. However, this will actually require you to adjust the baseline of the line manually because it will be bottom aligned. You’re solution is already spot on.
The margins
at the top and bottom are introduced by block.spacing
as the grid itself is a block-level element, and the solution for this is to introduce a box to make it inline:
#box(grid(
columns: (auto, 1fr, auto),
align: horizon + center,
column-gutter: 5pt,
text(fill: red)[abc],
line(length: 100%, stroke: 0.5pt + red),
text(fill: red)[def],
))
This also has the effect of being able to put this within text if you add other fractionally spaced elements beside it.
Here’s an image showing the left side with the the box-wrapping and the right without it:
If that’s a common separator you can of course define a function that does it for you:
#let sep(left, right) = box(grid(
columns: (auto, 1fr, auto),
align: horizon + center,
column-gutter: 5pt,
left,
line(length: 100%, stroke: 0.5pt),
right,
))
Keep in mind that grid
is subject to set rules and something like grid.inset
may be something you want to explicitly set to nothing for this to avoid any other spacing issues.