The mdframed package implements a box environment that automatically breaks boxes across multiple pages. Moreover, it allows flexible box designs. An example from the documentation that I particularly like is titled: “Theorem with separate header and the help of TikZ (complex)”. In this article, I use the example to create environments for theorems, lemmas, and proofs, adding a few minor enhancements.

**The basics explained**

In the preamble, we load the `mdframed`

package and define the environments for theorem, lemma, and proof. AS we want to use TikZ syntax later on, we load the package with the `framemethod=TikZ`

option.

\usepackage[framemethod=TikZ]{mdframed}

Next, we define a counter for continuous numbering of the environment. Here, I will only show how to do so for theorems, but it is similar for lemmas and proofs. We might want the counter to be reset at the beginning of every `section`

. This is achieved through the optional argument of the `newcounter`

command. Also, we may decide the value of the counter to be displayed as: “section.theorem”. For that, we redefine the command that produces the counter value: `\thetheo`

. Alternatively, to reset the counter at every chapter and display “chapter.theorem”, use `chapter`

in the code instead.

\newcounter{theo}[section]\setcounter{theo}{0} \renewcommand{\thetheo}{\arabic{section}.\arabic{theo}}

With that, we are ready to define a new environment for theorem. This is slightly more complex, so I will go step-by-step and provide the complete code further below for those who are more interested in the complete code.

To define a new environment, we use the `newenvironment`

command. It takes three arguments plus an optional argument (`args`

) to define the number of parameters that we want our environment to take.

\newenvironment{name}[args]{begin_def}{end_def}

The first parameter `name`

is the name of the environment that we want to create. Here, we may choose may anything that has not been defined already. I use `theo`

, as we want to create a theorem environment. Moreover, we’d like to make use of the page break property provided by the `mdframed`

environment. Therefore, we use `\begin{mdframed}`

and `\end{mdframed}`

as begin and end definitions. Also, we define that the environment takes two arguments/parameters (`[2]`

). Of these two parameters, one is optional and empty by default (extra `[]`

) and the other is compulsory. The first, optional argument is for the title which the theorem may or may not have. The second argument, which has to be provided, is for the label to reference the environment. If you prefer, you can also make this an optional parameter.

At the beginning, we increase the theorem counter by one and make the counter available to the `\ref`

command for referencing. For that, we use `\refstepcounter`

.

\newenvironment{theo}[2][]{% \refstepcounter{theo} % Code for box design goes here. \begin{mdframed}[]\relax}{% \end{mdframed}}

The next step is to add code for the box design. We distinguish two cases: with and without title. We do this by checking if the first, optional argument is empty (`\ifstringempty{#1}`

). Next, we use the `mdfsetup`

command to change the default box design for both cases. The code is essentially the same, with the only difference that when a title is provided, it is printed. TikZ syntax makes it relatively easy to add a heading with a blue background. The heading contains the word “Theorem”, the counter value and, the title if available (else condition).

Through last bit of code, another `mdfsetup`

, we make some final changes. We add a frame around the entire box and raise the title slightly, such that it is placed on top of the frame rather than inside the box.

\ifstrempty{#1}% % if condition (without title) {\mdfsetup{% frametitle={% \tikz[baseline=(current bounding box.east),outer sep=0pt] \node[anchor=east,rectangle,fill=blue!20] {\strut Theorem~\thetheo};} }% % else condition (with title) }{\mdfsetup{% frametitle={% \tikz[baseline=(current bounding box.east),outer sep=0pt] \node[anchor=east,rectangle,fill=blue!20] {\strut Theorem~\thetheo:~#1};}% }% }% % Both conditions \mdfsetup{% innertopmargin=10pt,linecolor=blue!20,% linewidth=2pt,topline=true,% frametitleaboveskip=\dimexpr-\ht\strutbox\relax% }

We are now ready to use the newly defined theorem environment, as illustrated in the example below. Moreover, the example shows how we can reference the theorem in the text, using the `\ref`

command.

\begin{theo}[Pythagoras' theorem]{thm:pythagoras} In a right triangle, the square of the hypotenuse is equal to the sum of the squares of the catheti. $$a^2+b^2=c^2$$ \end{theo} In mathematics, the Pythagorean theorem, also known as Pythagoras' theorem (see theorem \ref{thm:pythagoras}), is a relation in Euclidean geometry among the three sides of a right triangle.

Text modified from Wikipedia: Pythagorean theorem.

With that, we are ready to put everything together and define similar environment for lemma and proof. Code for all three environments is provided below. Feel free to make use and change them to your liking.

**Theorem**

\newcounter{theo}[section]\setcounter{theo}{0} \renewcommand{\thetheo}{\arabic{section}.\arabic{theo}} \newenvironment{theo}[2][]{% \refstepcounter{theo}% \ifstrempty{#1}% {\mdfsetup{% frametitle={% \tikz[baseline=(current bounding box.east),outer sep=0pt] \node[anchor=east,rectangle,fill=blue!20] {\strut Theorem~\thetheo};}} }% {\mdfsetup{% frametitle={% \tikz[baseline=(current bounding box.east),outer sep=0pt] \node[anchor=east,rectangle,fill=blue!20] {\strut Theorem~\thetheo:~#1};}}% }% \mdfsetup{innertopmargin=10pt,linecolor=blue!20,% linewidth=2pt,topline=true,% frametitleaboveskip=\dimexpr-\ht\strutbox\relax } \begin{mdframed}[]\relax% \label{#2}}{\end{mdframed}}

**Lemma**

\newcounter{lem}[section]\setcounter{lem}{0} \renewcommand{\thelem}{\arabic{section}.\arabic{lem}} \newenvironment{lem}[2][]{% \refstepcounter{lem}% \ifstrempty{#1}% {\mdfsetup{% frametitle={% \tikz[baseline=(current bounding box.east),outer sep=0pt] \node[anchor=east,rectangle,fill=green!20] {\strut Lemma~\thelem};}} }% {\mdfsetup{% frametitle={% \tikz[baseline=(current bounding box.east),outer sep=0pt] \node[anchor=east,rectangle,fill=green!20] {\strut Lemma~\thetheo:~#1};}}% }% \mdfsetup{innertopmargin=10pt,linecolor=green!20,% linewidth=2pt,topline=true,% frametitleaboveskip=\dimexpr-\ht\strutbox\relax } \begin{mdframed}[]\relax% \label{#2}}{\end{mdframed}}

**Proof**

\newcounter{prf}[section]\setcounter{prf}{0} \renewcommand{\theprf}{\arabic{section}.\arabic{prf}} \newenvironment{prf}[2][]{% \refstepcounter{prf}% \ifstrempty{#1}% {\mdfsetup{% frametitle={% \tikz[baseline=(current bounding box.east),outer sep=0pt] \node[anchor=east,rectangle,fill=red!20] {\strut Proof~\theprf};}} }% {\mdfsetup{% frametitle={% \tikz[baseline=(current bounding box.east),outer sep=0pt] \node[anchor=east,rectangle,fill=red!20] {\strut Proof~\thetheo:~#1};}}% }% \mdfsetup{innertopmargin=10pt,linecolor=red!20,% linewidth=2pt,topline=true,% frametitleaboveskip=\dimexpr-\ht\strutbox\relax } \begin{mdframed}[]\relax% \label{#2}}{\end{mdframed}}

To automatically add the qed symbol, load the amsthm package and place the command `\qed`

just before `\end{mdframed}`

.

% Load package \usepackage{amsthm} % Change last line of above code \begin{mdframed}[]\relax% \label{#2}}{\qed\end{mdframed}}

**Complete code example**

\documentclass{article} \usepackage[framemethod=TikZ]{mdframed} \usepackage{amsthm} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %Theorem \newcounter{theo}[section] \setcounter{theo}{0} \renewcommand{\thetheo}{\arabic{section}.\arabic{theo}} \newenvironment{theo}[2][]{% \refstepcounter{theo}% \ifstrempty{#1}% {\mdfsetup{% frametitle={% \tikz[baseline=(current bounding box.east),outer sep=0pt] \node[anchor=east,rectangle,fill=blue!20] {\strut Theorem~\thetheo};}} }% {\mdfsetup{% frametitle={% \tikz[baseline=(current bounding box.east),outer sep=0pt] \node[anchor=east,rectangle,fill=blue!20] {\strut Theorem~\thetheo:~#1};}}% }% \mdfsetup{innertopmargin=10pt,linecolor=blue!20,% linewidth=2pt,topline=true,% frametitleaboveskip=\dimexpr-\ht\strutbox\relax } \begin{mdframed}[]\relax% \label{#2}}{\end{mdframed}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %Lemma \newcounter{lem}[section] \setcounter{lem}{0} \renewcommand{\thelem}{\arabic{section}.\arabic{lem}} \newenvironment{lem}[2][]{% \refstepcounter{lem}% \ifstrempty{#1}% {\mdfsetup{% frametitle={% \tikz[baseline=(current bounding box.east),outer sep=0pt] \node[anchor=east,rectangle,fill=green!20] {\strut Lemma~\thelem};}} }% {\mdfsetup{% frametitle={% \tikz[baseline=(current bounding box.east),outer sep=0pt] \node[anchor=east,rectangle,fill=green!20] {\strut Lemma~\thelem:~#1};}}% }% \mdfsetup{innertopmargin=10pt,linecolor=green!20,% linewidth=2pt,topline=true,% frametitleaboveskip=\dimexpr-\ht\strutbox\relax } \begin{mdframed}[]\relax% \label{#2}}{\end{mdframed}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %Proof \newcounter{prf}[section]\setcounter{prf}{0} \renewcommand{\theprf}{\arabic{section}.\arabic{prf}} \newenvironment{prf}[2][]{% \refstepcounter{prf}% \ifstrempty{#1}% {\mdfsetup{% frametitle={% \tikz[baseline=(current bounding box.east),outer sep=0pt] \node[anchor=east,rectangle,fill=red!20] {\strut Proof~\theprf};}} }% {\mdfsetup{% frametitle={% \tikz[baseline=(current bounding box.east),outer sep=0pt] \node[anchor=east,rectangle,fill=red!20] {\strut Proof~\theprf:~#1};}}% }% \mdfsetup{innertopmargin=10pt,linecolor=red!20,% linewidth=2pt,topline=true,% frametitleaboveskip=\dimexpr-\ht\strutbox\relax } \begin{mdframed}[]\relax% \label{#2}}{\qed\end{mdframed}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %Examples \begin{document} \section{Theorem and lemma examples with title} \begin{theo}[Pythagoras' theorem]{thm:pythagoras} In a right triangle, the square of the hypotenuse is equal to the sum of the squares of the catheti. \[a^2+b^2=c^2\] \end{theo} In mathematics, the Pythagorean theorem, also known as Pythagoras' theorem (see theorem \ref{thm:pythagoras}), is a relation in Euclidean geometry among the three sides of a right triangle. \begin{lem}[B\'ezout's identity]{lem:bezout} Let $a$ and $b$ be nonzero integers and let $d$ be their greatest common divisor. Then there exist integers $x$ and $y$ such that: \[ax+by=d\] \end{lem} This is a reference to Bezout's lemma \ref{lem:bezout} \section{Theorem and proof examples without title} \begin{theo}{thm:theorem1} There exist two irrational numbers $x$, $y$ such that $x^y$ is rational. \end{theo} \begin{prf}{prf:proof1} If $x=y=\sqrt{2}$ is an example, then we are done; otherwise $\sqrt{2}^{\sqrt{2}}$ is irrational, in which case taking $x=\sqrt{2}^{\sqrt{2}}$ and $y=\sqrt{2}$ gives us: \[\bigg(\sqrt{2}^{\sqrt{2}}\bigg)^{\sqrt{2}}=\sqrt{2}^{\sqrt{2}\sqrt{2}}=\sqrt{2}^{2}=2.\] \end{prf} \end{document}

For more details see the mdframed package documentation or drop me a comment below.

Torbjorn

It would be nice if you changed all the $$ .. $$ to \[ .. \], the former is not recommended to use in LaTeX.

tom

Thanks for the heads up. I changed to code accordingly.

Tien Kha Pham

The code above re-numbers the lemma from 1.1. How can I set the counter so that the lemma’s number continues the theorem’s number? (theorem 1.1, then lemma 1.2, then theorem 1.3, and so on). Thanks.

tom

Thanks for your question. I assume you refer to the complete code example at the bottom of the article. You’d just have to replace the lemma counter with the theorem counter. Please see the updated lemma code below.

Best, Tom

Tien Kha Pham

Thanks a lot, Tom. It works. I really appreciate your kindness ๐

Kim

If you don’t use the label part in the theorems the first letter in the output will missing.

Output

et $a$ and $b$ ….. No L!

Thanks a lot for the examples and good blog by the way.

-Kim

tom

Hi Kim,

Thanks for pointing this out. When the label is not used, just leave the curly brackets empty.

Alternatively, you can also change the

`lem`

environment definition.Best, Tom

Jens

Hi Tom,

Thank you for this great article! Since I found it early this year, I use these fancy boxes in every script I write (Iยดm a math student and make summaries).

Now I like to use such boxes formulas and have problem if my content starts with \[ … \] .

Then I have a blank line at the beginning.

If I write a text before \[ … \], then the formula is at the exact same point as without text.

Can you reproduce this issue? If not, I will make my first minimal example ๐

Best wishes

Jens

tom

Hi Jens,

I can reproduce the extra whitespace with the

`displaymath`

environment in the box. There seems to be an extra`baselineskip`

added within`mdframed`

.Although it is not an elegant solution, my suggestion would be to manually remove the whitespace where necessary.

HTH,

Tom

Jens

Hi Tom,

Thanks a lot for this workaround, that helps indeed.

In case someone finds an elegant solution it would be nice if you could share it here.

Bye,

Jens

tom

You are welcome! To stay informed of future replies, you can subscribe to comments on this article.

Best,

Tom