How to remove top margin above \tableofcontents
In the standard document classes (like book
and report
), \tableofcontents
is set as a \chapter*
:
\newcommand\tableofcontents{%
\if@twocolumn
\@restonecoltrue\onecolumn
\else
\@restonecolfalse
\fi
\chapter*{\contentsname
\@mkboth{%
\MakeUppercase\contentsname}{\MakeUppercase\contentsname}}%
\@starttoc{toc}%
\if@restonecol\twocolumn\fi
}
So, it would be possible to temporarily modify the chapter heading macro to not insert as much vertical space. Here's a look at the \chapter*
heading macro \@makeschapterhead
:
\def\@makeschapterhead#1{%
\vspace*{50\p@}%
{\parindent \z@ \raggedright
\normalfont
\interlinepenalty\@M
\Huge \bfseries #1\par\nobreak
\vskip 40\p@
}}
Note the insertion of vertical space (\vspace*{50\p@}
) before setting the heading. So, we can temporarily redefine this macro to not insert the vertical space:
\documentclass{book}
\usepackage{showframe}% http://ctan.org/pkg/showframe
\begin{document}
\begingroup
\makeatletter
% Redefine the \chapter* header macro to remove vertical space
\def\@makeschapterhead#1{%
%\vspace*{50\p@}% Remove the vertical space
{\parindent \z@ \raggedright
\normalfont
\interlinepenalty\@M
\Huge \bfseries #1\par\nobreak
\vskip 40\p@
}}
\makeatother
\tableofcontents
\endgroup
\chapter{A chapter}\section{A section}\subsection{A subsection}
\chapter{A chapter}\section{A section}\subsection{A subsection}
\chapter{A chapter}\section{A section}\subsection{A subsection}
\chapter{A chapter}\section{A section}\subsection{A subsection}
\chapter{A chapter}\section{A section}\subsection{A subsection}
\chapter{A chapter}\section{A section}\subsection{A subsection}
\end{document}
The grouping of the redefinition makes it local. Therefore, all modifications are restored after \endgroup
.
Since the \chapter*
header macro only uses \vspace*{..}
to insert the gap between the text block and chapter header, you could also redefine \vspace
to gobble the two arguments (*
and {50\p@}
):
\documentclass{book}
\usepackage{showframe}% http://ctan.org/pkg/showframe
\begin{document}
\begingroup
\renewcommand{\vspace}[2]{}% Gobble 2 arguments after \vspace
\tableofcontents
\endgroup
\chapter{A chapter}\section{A section}\subsection{A subsection}
\chapter{A chapter}\section{A section}\subsection{A subsection}
\chapter{A chapter}\section{A section}\subsection{A subsection}
\chapter{A chapter}\section{A section}\subsection{A subsection}
\chapter{A chapter}\section{A section}\subsection{A subsection}
\chapter{A chapter}\section{A section}\subsection{A subsection}
\end{document}
The showframe
package highlights the text block boundary (in addition to other elements) and is therefore only used in this example to showcase the vertical alignment of the table of contents. It is not needed in your final document.
Perhaps a cleaner approach would be to use etoolbox
to patch \@makeschapterhead
. This would also allow you to separate document structure from content (making what resides in the document
environment only relate to the content). Add the following to your document preamble:
\usepackage{etoolbox}% http://ctan.org/pkg/etoolbox
\makeatletter
\let\oldtableofcontents\tableofcontents
\renewcommand{\tableofcontents}{\begingroup%
\patchcmd{\@makeschapterhead}% <cmd>
{\vspace*{50\p@}}% <search>
{}% <replace>
{}{}% <success><failure>
\oldtableofcontents%
\endgroup%
}
\makeatother
The above does a local search-and-replace within \@makeschapterhead
(replacing \vspace*{50\p@}
with nothing, before calling the regular table of contents. The redefinition (search-and-replace) is localized within the scope of the group.
Here's a tocloft
way that has not been mentioned so far:
tocloft
provides the \cftbeforeXtitleskip
and \cftafterXtitleskip
lengths, where X
stands for toc
, lof
or lot
, depending on the specific needs.
The advantage of using tocloft
is that it hides the specific class settings, however, don't use tocloft
with a KOMA class -- that's not recommended.
The values in the given example are just arbitrary!
\documentclass{book}
\usepackage{tocloft}
\usepackage{blindtext}
\setlength{\cftbeforetoctitleskip}{0pt}
\setlength{\cftaftertoctitleskip}{0pt}
\begin{document}
\tableofcontents
\blinddocument[2]
\end{document}