# How to adjust the beamer block width to the size of its content?

I would like to define a nice beamer block environment with the following properties

a) it is always centered on the slide (horizontally) b) it is only slightly longer than its content

The aim is to put an equation inside the block and use the block as a highlighter for this equation. So in short, I want a block environment that adjusts its width to the content it contains. Does anybody know a solution?

This would be an example of what I want to achieve automatically:

\documentclass[slidestop]{beamer}
\begin{document}

\begin{frame}{Test}
\abovedisplayskip=0pt

\begin{center}
\begin{minipage}{0.2\textwidth}
\begin{block}{}
\begin{gather*}
c^2=a^2+b^2
\end{gather*}
\end{block}
\end{minipage}
\end{center}

\end{frame}
\end{document}


The environment should work similar like this manual hack with the improvement that the 0.2\textwidth is adjusted nicely according to the actual width of the formula.

Edit:

I am searching for a nice realization of the following workaround:

\documentclass[slidestop]{beamer}
\usepackage{calc}

\newcommand{\gatherblock}[1]{%
\vspace*{-5pt}
\begin{center}
\begin{minipage}{\widthof{$#1$}}
\begin{block}{}
\abovedisplayskip=0pt
\vspace*{-1pt}
\begin{gather*}
#1
\end{gather*}
\end{block}
\end{minipage}
\end{center}}

\begin{document}
\begin{frame}{Test}

\gatherblock{c^2=a^2+b^2}

\end{frame}

-
Welcome to TeX.SX. Please consider adding a MWE (starting from \documentclass{beamer}... and ending at \end{document}) so that those who try to help you are saved from some typing work. –  Harish Kumar Jan 19 '13 at 13:00
Dear Harish Kumar, –  7asd44 Jan 19 '13 at 13:03
Thank you for the code :-) –  Harish Kumar Jan 19 '13 at 13:14

If your aim is to highlight equations without having to care about its width you could use other approaches rather than blocks.

I propose here two methods:

### Solution with minimal spacing

This method needs the tikzmark library: it could be find at http://bazaar.launchpad.net/~tex-sx/tex-sx/development/files, then download the files tikzmark.dtx and tikzmark_example.pdf. Once put in a temporary directory compile with pdflatex, then install is as a package.

The code:

\documentclass[t]{beamer}
\usepackage{lmodern}

\usepackage{tikz}

% setting the block body color
\usebeamercolor{block body}
\definecolor{my block body}{named}{bg}

% Original by Peter Grill:
% http://tex.stackexchange.com/questions/35319/a-boxed-alternative-with-minimal-spacing/#35357

\makeatletter
\newcommand*{\@DrawBoxHeightSep}{0.3ex}%
\newcommand*{\@DrawBoxDepthSep}{0.1em}%
\newcommand{\@DrawBox}[6][fill=my block body,draw=my block body!50!black]{
%#1= style,#2=height, #3=depth, #4 left marker,
%#5= right marker, #6= content
\tikz[overlay,remember picture,baseline]
($(pic cs:#4)+(-0.2em,#2+\@DrawBoxHeightSep)$) rectangle
($(pic cs:#5)+(0.2em,-#3-+\@DrawBoxDepthSep)$);
\tikz[overlay,remember picture,baseline]
\node[anchor=base] at ($(pic cs:#4)!0.5!(pic cs:#5)$) {#6};
}

\newcounter{image}
\setcounter{image}{1}
\newdimen\@myBoxHeight%
\newdimen\@myBoxDepth%
\newcommand{\NiceBlock}[2][fill=my block body,draw=my block body!50!black]{%
\settoheight{\@myBoxHeight}{#2}% Height
\settodepth{\@myBoxDepth}{#2}% Depth
\tikzmark{l\theimage}#2\tikzmark{r\theimage}
\@DrawBox[#1]{\@myBoxHeight}{\@myBoxDepth}
{l\theimage}{r\theimage}{#2}
\stepcounter{image}
}
\makeatother

\begin{document}

\begin{frame}{Test}
\begin{gather*}
\NiceBlock{\ensuremath{c^2=a^2+b^2}}
\end{gather*}

\begin{gather*}
\NiceBlock{\ensuremath{x+z=100}}
\end{gather*}

\end{frame}
\end{document}


After two compilation runs, the result is:

### Solution with hf-tikz

The previous solution is completely automatic, but could have some problems. Suppose to box:

\begin{gather*}
\NiceBlock{\ensuremath{
\sum_{l _1+\dots+ l _p=l}\prod^p_{i=1} \binom{n_i}{l _i}
}
}
\end{gather*}


You will end up with:

This because of one cannot say:

\NiceBlock{
\begin{gather*}
\sum_{l _1+\dots+ l _p=l}\prod^p_{i=1} \binom{n_i}{l _i}
\end{gather*}
}


That's the reason why a semi-automatic package like hf-tikz IMHO provides a good alternative: markers fit pretty well the dimensions automatically, but when needed the user could shift and extend as he needs the highlighted area.

An example that shows how to highlight some equations with overlay specifications:

\documentclass[t]{beamer}
\usepackage{lmodern}
\usepackage[beamer,customcolors]{hf-tikz}

% setting the block body color
\usebeamercolor{block body}
\definecolor{my block body}{named}{bg}
\hfsetbordercolor{my block body!50!black}
\hfsetfillcolor{my block body}

\begin{document}

\begin{frame}{Test}
\begin{gather*}
\tikzmarkin<1->{a}(0.15,-0.1)(-0.15,0.4)c^2=a^2+b^2\tikzmarkend{a}
\end{gather*}

\begin{gather*}
\tikzmarkin<2->{x}x+z=100\tikzmarkend{x}
\end{gather*}

\begin{gather*}
\tikzmarkin<{1,3}>{c}(0.15,-0.6)(-0.15,0.7)
\sum_{l _1+\dots+ l _p=l}\prod^p_{i=1} \binom{n_i}{l _i}
\tikzmarkend{c}
\end{gather*}

\end{frame}
\end{document}


Also in this case two compilation runs are necessary; then the result is:

If instead you want to use blocks, there could be another solution, but is not automatic. Moreover, in contrast with hf-tikz where the overlay specification is just used to show or not the highlighting, here the equation is inside a block, so the overlay specifications show or not the equation with the block together.

Code:

\documentclass[t]{beamer}
\usepackage{lmodern}
% setting the block body color
\usebeamercolor{block body}
\definecolor{my block body}{named}{bg}
\setbordercolor{my block body}
\setblockcolor{my block body}

% new enviroment always centered
\newenvironment{cdynblock}{\begin{center}\begin{dynblock}}{\end{dynblock}\end{center}}

\begin{document}

\begin{frame}{Test}
\abovedisplayskip=0pt
\begin{cdynblock}
\opaqueblock<1->[0.2\textwidth]{
\begin{gather*}
c^2=a^2+b^2
\end{gather*}
}
\end{cdynblock}

\begin{cdynblock}
\opaqueblock<2->[0.2\textwidth]{
\begin{gather*}
x+y=400
\end{gather*}
}
\end{cdynblock}

\begin{cdynblock}
\opaqueblock<3->[0.3\textwidth]{
\begin{gather*}
\sum_{l _1+\dots+ l _p=l}\prod^p_{i=1} \binom{n_i}{l _i}
\end{gather*}
}
\end{cdynblock}
\end{frame}

\end{document}


The result:

Using the dynblocks and environ packages, allows to compute automatically the width of the formula.

Here is the key point:

% new enviroment always centered

\usepackage{environ}
\newsavebox\mybox
% new environment cdyn: #1 => overlay specification
\NewEnviron{cdyn}[1]{%
\sbox{\mybox}{$\BODY$}%
\begin{center}
\begin{dynblock}
\opaqueblock<#1>[\wd\mybox]{$\BODY$}
\end{dynblock}
\end{center}
}{}%


in which first I compute the width of the formula and then this width is passed to the \opaqueblock command.

The complete code:

\documentclass[t]{beamer}
\usepackage{lmodern}
% setting the block body color
\usebeamercolor{block body}
\definecolor{my block body}{named}{bg}
\setbordercolor{my block body}
\setblockcolor{my block body}

% new enviroment always centered

\usepackage{environ}
\newsavebox\mybox
% new environment cdyn: #1 => overlay specification
\NewEnviron{cdyn}[1]{%
\sbox{\mybox}{$\BODY$}%
\begin{center}
\begin{dynblock}
\opaqueblock<#1>[\wd\mybox]{$\BODY$}
\end{dynblock}
\end{center}
}{}%

\begin{document}

\begin{frame}{Test}
\abovedisplayskip=0pt

\begin{cdyn}{1-}
c^2=a^2+b^2
\end{cdyn}

\begin{cdyn}{2-}
x+y=400
\end{cdyn}

\begin{cdyn}{3-}
\sum_{l _1+\dots+ l _p=l}\prod^p_{i=1} \binom{n_i}{l _i} +
\sum_{l _1+\dots+ l _p=l}\prod^p_{i=1} \binom{n_i}{l _i}
\end{cdyn}

\begin{cdyn}{4-}
\begin{cases}
\end{cases}
\end{cdyn}

\end{frame}

\end{document}


The result:

-
Dear Claudio, thank you very much for the effort and the solution. The problem is, that I want the equations to look like my other block environments, so I guess I must tweak the tikz code around until I get the same look. I guess there should be a simpler solution by just adjusting the beamer code (e.g. if I change the beamer style, I would have to change my tikz code all the time). Do you know of any? In any case, your solution is already much more then I have sofar, so thank you again! –  7asd44 Jan 19 '13 at 14:55
Sorry, I now realize that the last suggestion is more like what I initially thought of. So if anybody could make the width adjustment automatic, I would be happy... :) thank you again for the effort to help me! –  7asd44 Jan 19 '13 at 15:04
@7asd44: I've provided an automatic solution :). As a new user, I would courteously suggest you for the future to upvote all answers you find useful, including those to others' questions and to check/accept the best answers to your own questions by clicking the green tick on the left-hand side of the answer. –  Claudio Fiandrino Jan 20 '13 at 11:23
thank you again for your help, I found your answer very useful, and thank you for the automatic version! –  7asd44 Jan 20 '13 at 12:05

tcolorbox includes command tcboxmath within theorems library. It allows to box and frame some part of math expression according to its width. With it it's easier to define something like gatherblock.

\documentclass[slidestop]{beamer}
\usepackage{tcolorbox}
\tcbuselibrary{theorems}
\tcbuselibrary{skins}

\newcommand{\gatherblock}[2][]{\begin{gather*}\tcboxmath[#1]{#2}\end{gather*}}

\begin{document}

\begin{frame}{Test}
\abovedisplayskip=0pt

\centering
\begin{minipage}{0.2\textwidth}
\begin{block}{}
\begin{gather*}
c^2=a^2+b^2
\end{gather*}
\end{block}
\end{minipage}

%Math box with similar to beamer block
\gatherblock[skin=beamer,beamer]{c^2=a^2+b^2}

%Math box with default tcolorbox options
\gatherblock{c^2=\tcbhighmath{a^2}+b^2}

%Math box with default tcolorbox options
% and colored background
\gatherblock[colback=red!30]{c^2=\tcbhighmath{a^2}+b^2}

\end{frame}
\end{document}


-