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.
It would be nice if you changed all the $$ .. $$ to \[ .. \], the former is not recommended to use in LaTeX.
Thanks for the heads up. I changed to code accordingly.
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.
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
Thanks a lot, Tom. It works. I really appreciate your kindness 🙂
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
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
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
Hi Jens,
I can reproduce the extra whitespace with the
displaymath
environment in the box. There seems to be an extrabaselineskip
added withinmdframed
.Although it is not an elegant solution, my suggestion would be to manually remove the whitespace where necessary.
HTH,
Tom
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
You are welcome! To stay informed of future replies, you can subscribe to comments on this article.
Best,
Tom
This theorem box style looks really good, but when i tried to implement this into my project the text above the theorem and the theorem frame gets mashed together. How can i get some vertical space?
https://postimg.org/image/hcrb27dex/
Hi there,
Thanks for your question. You can add extra vertical space before the box through the
skipabove
option.HTH,
Tom
Hi,
I just copy and pasted your code into a document, but now it looks strange – picture in the link below. I would love to use this setup in my maths report, but how do I fix this?
https://postimg.org/image/56gapx713/
Thank you in advance!
BR
Mads
Hi again.
I don’t know if you changed anything, but it works when I put it in ShareLaTeX 🙂
BR
Mads
Hi Mads,
Thanks for letting me know. Perhaps you can try to update your LaTeX distribution to the latest version. I’m happy to try it out, if you send me a minimal working example which produces the boxes in your posted figure.
HTH, Tom
Hi Tom,
I don’t want the numbering in the proofs. How do I remove that numbering?
Hi Sanjana,
Below’s the example from the article without numbering in the proofs.
Best wishes,
Tom
Thank you very much for these fancy boxes! I tried defining a definition (and also theorem, lemma and proof) environment using them. I then wrote two definitions in the same section and both are named ‘Definição 1.0’ (same numbering). Do you have any idea why? Maybe I messed the code up? I couldn’t quite understand the numbering code. Here’s my version of the code:
Thanks in advance!
Nevermind, found my mistake! The second \theteo was not replaced by \thedeff. Thank you very much again for this tip, I’m using it along with the fncychap package (using Bjornstrup as style) and they look good together. =)
Thanks for the feedback and for posting your solution. Best, Tom
Hi Tom,
I copied your original code and tried to run it (to see how it works, and then modify it to write my own notes), and I got the following:
https://www.dropbox.com/s/s9f0ym998fgywe2/TexCodeNotWorking.png?dl=0
No boxes and no colours.
Do you know what might be the problem?
Thank you for your time!
Nataliya
Hi Nataliya,
Thanks for getting in touch. Did you try to run the complete example at the end of the article? Please provide your code, so I can take a look.
Best,
Tom
Hi Tom,
I have been trying to use your code to write up note for my exams. My problem is that the text runs out outwidth the box and equations get messed up. I copied you code letter for letter and I have no idea what has gone wrong. Any help would be appreciated,
Kind Regards,
Kate
Hi Kate,
Please provide a minimal working example for me to reproduce the problem.
Thanks, Tom
This is awesome! I have a question: this doesn’t happen often, but some theorem titles are too long to fit into one line. How do I modify the code so that if the title is too long, it carries on to the next line and therefore maybe make the box taller?
Hi Harry,
Interesting question. Although not very elegant, you could place the title inside a
minipage
environment. See example below.Best, Tom
Hello Tom
Thanks for your great work on Latex.
I’m using your programs in editing a book, however, it appears
Package kvsetkeys Error: Undefined key `5pt ‘. … [Exponential Fundamental Limit 1] {LFE1}
even loaded the “kvsetkeys” package.
Would you help me?
Thank you very much.
Hi Eron,
Thanks for getting in touch. Please provide a minimal example so I can reproduce the problem and suggest a solution.
Thanks, Tom
Hi Tom, thank you!
This problem was solved but I have another qustion: “how to insert pictures in this enviroment?”
Hug
Eron
Just use the graphicx package, i.e.
Hello Tom,
I tried inserting a figure into the box, but I get an error: “Float(s) lost”. Is it not possible to insert figures into these boxes?
Thanks,
Hi Kaumudi,
I don’t know about floats, but if you just place the figure inside the box it works. See the minimal example below (with the theorem box definition omitted).
Best, Tom
Hello !
I want to cite the reference in the theorems . Can you help me?
Thank you very much!
Hi there,
Citation works exactly the same way as outside a theorem box. Below is a minimal example.
Best, Tom
Hello Tom
I have been tried your code. I copied and tried to run it, but I get some error.
The Error is “Package keyval Error: framemethod undefined. \ProcessKeyvalOptions*”
Can you help me to fix this problem.
Thank you
Hi there,
Thanks for your comment. I can’t reproduce the error. The code still works on my system in both,
article
andbeamer
document classes. First, I suggest to update to the latest distribution. If that doesn’t help, please provide a minimal working example for me to reproduce the problem.Thanks,
Tom
Thank you very much for answering my questions.
What do you means to update to the latest distribution? Am I need to up date my MikTex?
Thanks
Hi there,
You said you copied the code from the article above and I assume you referred to the complete example towards the end of the article. As I can run that code on my system, there is a possibility that your distribution is outdated. However, that doesn’t mean it will fix the problem. It’s just all I can say with the limited information I have. Again, it would be very helpful if you provided a minimal example to illustrate the error.
Best, Tom
This is really useful, thanks!
Thanks Tom for these excellent examples.
On exactly using these codes I could successfully run them, but when there is a break in page, the framed gets broken across places, sometimes only heading in bottom of one page and rest of the body text in next page and looks very bad formatting to read the book.
How can I stop the frame to get break across pages?
I want the frame to adjust in the same page or start from a new page if there is break in the frame. Can it be done.Please provide me the code as I am very new learner in LaTeX.
Is using
[nobreak=true]
in the mdframe ok??Did you try this? It would be great to hear if it worked.
Thanks, Tom
I had the same issue and using [nobreak=true] in the mdframe worked!
Hallo,
i use the package “arabtex” and “rydarab” to write araic mathematical document.
I want to write the theorem title from right to left, but i do not how??
Can you please help me?
Best Regards
Atef Abdel-Rahman
Hi Atef,
Thanks for your comment. Please provide a minimal working example.
Thanks, Tom
Hi Tom!
What a wonderful example, I am using it for the book I am writing. 🙂
I was wondering whether you have an easy solution for allowing line breaks in the theorem title because I have a case where the title is too long and no longer fits the page width…
Thanks a lot! Philipp
Hi Philipp,
Thanks for your feedback. I answered a similar question here. Please give it a try and let me know if you get stuck.
Best, Tom
Hello there, thanks for the great work.
I am having problem with putting several different boxes in my book.
I need the section number to be increasing, instead they are repeating. How could solve the problem. I need to use about 10 boxes for different purposes: examples. exercises, theorems, try this, problems, axioms, … and the list goes on
Please , how does one add a colored background in white space?
Hi Calvin,
Define the background color in the
mdfsetup
macro.Please see the package documentation for more details.
Best, Tom
Hi Calvin,
The easiest solution would be to define 10 different counters and styles. If you keep the code in a different file, it doesn’t clutter your preamble and you can reuse it if needed.
The section counter is increased by 1 every time you start a new section with
\section{...}
. In the example, I reset the counters when the section counter is increased, but you can omit this by not linking them to the section (\newcounter{theo}
instead of\newcounter{theo}[section]
).HTH, Tom
Hey Tom, these look really nice. Im compiling a set of course notes for publication, can I consent to use this source code in my latex documentation? (I would like to reference you in the Bibliography)
Sure, feel free to use the code/content in your publication.
Best, Tom
Hi! Thanks for the neat boxes, I really like how they can be modified using tikz.
One thing to note: This does not work well with tikzexternalize. If you are using tikzexternalize, make sure to turn off optimization (\tikzexternalize[optimize=false]). Otherwise, the title will be optimized away. Tikz does not realize that it is nested and thinks it is not used to produce an output.
Also, I need to manually force tikzexternalize to rebuild the figure after each change. I don’t know why.
thanks for the code you provided, this is really cool. I have multiple theorems one after another but the latex creates empty large spaces in between the theorems. Could you please help me with this problem? Thanks in advance.
Maybe the best boxes for theorem that I have seen online! thanks for sharing! I have some very long proofs and I was wondering if is it possible to remove the parallel lines and keep the vertical ones? Thanks in advance.