22

In LaTeX Beamer, I'm trying to set \itemsep globally.

I've already tried the following, but it doesn't work:

\documentclass[14pt]{beamer}

\setbeamertemplate{itemize/enumerate body begin}{\setlength{\itemsep}{5ex}}

\begin{document}

\begin{frame}
    \begin{itemize}
%       \setlength{\itemsep}{5ex}  % this would work locally..
        \item Test1
        \item Test2
        \item Test3
    \end{itemize}

\end{frame} 

\end{document}

What am I doing wrong?

Edit:

I would prefer a solution that allows to define different spacing for body, subbody, subsubbody, etc., if possible.

30

Yout code won't work because the itemize/enumerate \beameritemnestingprefix body begin template is used before the \list internally used by itemize.

You can patch \itemize (original definition in beamerbaselocalstructure.sty):

\documentclass[14pt]{beamer}
\usepackage{xpatch}

\xpatchcmd{\itemize}
  {\def\makelabel}
  {\setlength{\itemsep}{5ex}\def\makelabel}
  {}
  {}

\begin{document}

\begin{frame}
    \begin{itemize}
        \item Test1
        \item Test2
        \item Test3
    \end{itemize}
\end{frame} 

\end{document}

enter image description here

Since \itemize as defined by beamer has an optional argument, using etoolbox's \patchcmd might produce undesired results. The \xpatchcmd from the xpatch package was designed to deal with these cases.

Update

In comments, it has been requested to be able to independently control the separation for the three allowed nesting levels; this can also be easily done using a conditional on \@itemdepth:

\documentclass{beamer}
\usepackage{xpatch}

\xpatchcmd{\itemize}
  {\def\makelabel}
  {\ifnum\@itemdepth=1\relax
     \setlength\itemsep{3ex}% separation for first level
   \else
     \ifnum\@itemdepth=2\relax
       \setlength\itemsep{2ex}% separation for second level
     \else
       \ifnum\@itemdepth=3\relax
         \setlength\itemsep{0.5ex}% separation for third level
   \fi\fi\fi\def\makelabel
  }
 {}
 {}

\begin{document}

\begin{frame}
\begin{itemize}
\item First item.
  \begin{itemize}
  \item First subitem.
  \item Second subitem.
    \begin{itemize}
    \item First subsubitem.
    \item Second subsubitem.
    \item Third subsubitem.
    \end{itemize}
  \item Third subitem.
  \end{itemize}
\item Second item.
\item Third item.
\end{itemize}
\end{frame}

\end{document}

enter image description here

15
  • Your one appeared while I was trying mine. Care to tell why \AtBeginEnvironment{itemize}{\setlength\itemsep{2.0em}} does not work?
    – Masroor
    Jan 30 '15 at 17:20
  • @Masroor Your try with \AtBeginEnvironment (from etoolbox) executes the code immediately before \itemize so it won't have effect. Jan 30 '15 at 17:24
  • So, etoolbox can not be used in this case?
    – Masroor
    Jan 30 '15 at 17:29
  • 2
    @Masroor since \itemize is defined in beamer with an optional argument, using etoolbox's \patchcmd might produce undesired results. \xpatchcmd was written to deal with those cases correctly. Jan 30 '15 at 17:33
  • 2
    @GonzaloMedina I would like to reproduce this for enumerate environments, can you help ?
    – BambOo
    Jul 5 '19 at 13:37
2

As an addition to Gonzalo Medina's answer, I use this:

\documentclass{beamer}
\usepackage{xpatch}

\makeatletter
\newcommand{\my@beamer@setsep}{%
\ifnum\@itemdepth=1\relax
     \setlength\itemsep{\my@beamer@itemsepi}% separation for first level
   \else
     \ifnum\@itemdepth=2\relax
       \setlength\itemsep{\my@beamer@itemsepii}% separation for second level
     \else
       \ifnum\@itemdepth=3\relax
         \setlength\itemsep{\my@beamer@itemsepiii}% separation for third level
   \fi\fi\fi}
\newlength{\my@beamer@itemsepi}\setlength{\my@beamer@itemsepi}{3ex}
\newlength{\my@beamer@itemsepii}\setlength{\my@beamer@itemsepii}{1.5ex}
\newlength{\my@beamer@itemsepiii}\setlength{\my@beamer@itemsepiii}{1.5ex}
\newcommand\setlistsep[3]{%
    \setlength{\my@beamer@itemsepi}{#1}%
    \setlength{\my@beamer@itemsepii}{#2}%
    \setlength{\my@beamer@itemsepiii}{#3}%
}
\xpatchcmd{\itemize}
  {\def\makelabel}
  {\my@beamer@setsep\def\makelabel}
 {}
 {}

\xpatchcmd{\beamer@enum@}
  {\def\makelabel}
  {\my@beamer@setsep\def\makelabel}
 {}
 {}
\makeatother


\begin{document}

\begin{frame}
    \begin{columns}[onlytextwidth, T]
        \begin{column}{.48\linewidth}
            % First column
            \begin{itemize}
                \item First item.
                    \begin{itemize}
                        \item First subitem.
                        \item Second subitem.
                            \begin{itemize}
                                \item First subsubitem.
                                \item Second subsubitem.
                                \item Third subsubitem.
                            \end{itemize}
                        \item Third subitem.
                    \end{itemize}
                \item Second item.
                \item Third item.
            \end{itemize}
        \end{column}%
        \hfill%
        \begin{column}{.48\linewidth}
            % second column
            \begin{enumerate}
                \item First item.
                    \begin{enumerate}
                        \item First subitem.
                        \item Second subitem.
                            \begin{enumerate}
                                \item First subsubitem.
                                \item Second subsubitem.
                                \item Third subsubitem.
                            \end{enumerate}
                        \item Third subitem.
                    \end{enumerate}
                \item Second item.
                \item Third item.
            \end{enumerate}
        \end{column}
    \end{columns}
\end{frame}

\end{document}

so that I can then do \setlistsep{2ex}{1ex}{1ex} in the slide where I need to change the values.

enter image description here

If you want also to add to the separation of the first item in a sublist, you can change the \my@beamer@setsep to:

\newcommand{\my@beamer@setsep}{%
\ifnum\@itemdepth=1\relax
     \setlength\itemsep{\my@beamer@itemsepi}% separation for first level
   \else
     \ifnum\@itemdepth=2\relax
       \setlength\itemsep{\my@beamer@itemsepii}% separation for second level
       \setlength\topsep{\my@beamer@itemsepii}% separation for second level
     \else
       \ifnum\@itemdepth=3\relax
         \setlength\itemsep{\my@beamer@itemsepiii}% separation for third level
         \setlength\topsep{\my@beamer@itemsepiii}% separation for second level
   \fi\fi\fi}

to obtain

enter image description here

...or maybe it's better to use the previous itemsep as topsep:

\newcommand{\my@beamer@setsep}{%
\ifnum\@itemdepth=1\relax
     \setlength\itemsep{\my@beamer@itemsepi}% separation for first level
   \else
     \ifnum\@itemdepth=2\relax
       \setlength\itemsep{\my@beamer@itemsepii}% separation for second level
       \setlength\topsep{\my@beamer@itemsepi}% separation for second level
     \else
       \ifnum\@itemdepth=3\relax
         \setlength\itemsep{\my@beamer@itemsepiii}% separation for third level
         \setlength\topsep{\my@beamer@itemsepii}% separation for second level
   \fi\fi\fi}

enter image description here

(just a matter of taste)

1
  • Very nice ! Thanks !
    – BambOo
    Nov 6 '20 at 11:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.