How can I make it so all boxes have a border (stroke) around them?

I would like all boxes to have a red border around them. I have attempted to use

#show box: set stroke(red)

and I get the error message only element functions can be used in set rules.

I don’t really understand the message, and more to the point, how can I achieve what I want?

(Note: I don’t want to create a new box-like function, as I have a whole pile of #box later in the document, which I cannot easily change.)

In this case you don’t need the show rule, only set:

#set box(stroke: red)
1 Like

Thanks for the quick reply. What is the underlying principle that means you can set the box’s stroke directly but with other items you need to use the show/set combination?

I believe it has to do with what counts as an element. I don’t know all the details, but this capability is planned to be expanded so that even user defined things can have set rules applied to them. Others on the forum can provide a much more precise answer.

The compiler can tell us a little:

#show box: set stroke(red)
               ^^^^^^

Error: Only element functions can be used in set rules


stroke is not an element, so set stroke is never available.

box is an element, so set box() is available. To set box we can pass any of the documented arguments to box and this affects all boxes that follow the set rule, in the same scope.

Sometimes elements are nested. And sometimes style rules are nested too, like for example inside a figure there is a block. A general set block rule will not override some of the more specific defaults for a figure’s block. To override them we need to set them on the same level:

For example, to configure blocks inside figure:

#show figure: set block(spacing: 0pt)

figure and block are both element functions, so we can use them in show and set rules.


I wanted a more box centric example so here is one:

#let myfigure(a, b, c, ..args) = {
  // set our box defaults
  set box(inset: 0.5em, stroke: 1pt)  // the default
  figure({               // inside the figure
    table(columns: 3,
      box(a),
      box(b),
      box(c)
    )
  }, ..args)
}

#set box(stroke: 3pt) // A. no effect, because there is a more specific rule
#set box(stroke: red) // B. has effect, because it folds together with 1pt; (1pt + red == 1pt + red..)
#show figure: set box(stroke: 3pt) // C. has effect, because it is more specific
#myfigure(caption: "Easy as 1-2-3")[1][2][3]

myfigure[1][2][3] with “default style”

myfigure[1][2][3] with the set/show-set rules A, B, and C applied:

Why do we use the show figure: set box rule? Look at the marking inside the figure in the code. That’s where your rule ends up, with show figure: set box. And that’s “inside” or after the set box rule above it, so we can override that one completely.

5 Likes