40

I know that there is tikz, but also eso-pic and textpos. I'd like to see a list of possible ways (not necessarily packages) for absolute positioning of things (which I believe amounts to "boxes") on the page, together with their advantages and disadvantages (for instance: tikz's current page node is very easy to use, but usually requires two LaTeX runs, and overhead from loading tikz if you don't need it for any other things is considerable).

Both LaTeX and ConTeXt solutions are welcome

  • Good idea to have a reference with one method per answer. Can you please add whether this can disturb the positioning of other material on the page (unlike overlay option). Simple \put will also work BTW. – user11232 Apr 5 '14 at 22:40
  • \raisebox{\up}[0pt][0pt]{\rlap{\hspace{\right}{anything}}} will position anything relative to the starting position, so if you start at a known absolute position (such as the upper left corner of the text area) Bob is now your uncle. – John Kormylo Apr 6 '14 at 0:04
  • 1
    The ConTeXt way for absolute (or relative!) is using Layers. – Aditya Apr 7 '14 at 16:02
  • @Aditya: I know, I even used them once or twice;). But for this big-list question to be useful for newbies, could you provide an example? – mbork Apr 7 '14 at 16:11
  • @mbork: I'll try to add a detailed answer. If only a day had more than 24 hours. – Aditya Apr 7 '14 at 16:13
17

Here is the tikz method which uses current page.south west anchor to position the text:

enter image description here

The \AbsolutePosition places the given text at the offset specified relative to the bottom left margin (whose coordinates are determined via the output of the \layout on the first page of the output.

Notes:

  • The showframe package was used just to show the page margins. It is not needed in actual use.
  • The layout package was used to determine the various offsets to apply to make to coordinates relative to the bottom left margin as opposed to the actual bottom left of the page.
  • The lipsum package was used just to provide dummy text.

Code:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{lipsum,showframe,layout}

%% Following obtained from \layout. May need adjustment based on class and
%% page settings.  Alternatively, can set these to 0pt and then position will
%% be relative to bottom left of page.
\newcommand*{\BottomLeftX}{1.0in+\hoffset+\oddsidemargin}%
\newcommand*{\BottomLeftY}{\paperheight-1.0in-\voffset-\topmargin-\headheight-\headsep-\textheight}%

\newcommand*{\AbsolutePosition}[4][]{%
    % #1 = tikz options
    % #2 = x (from south west corner of page
    % #3 = y
    % #4 = text
    \begin{tikzpicture}[remember picture,overlay, ultra thick]
        %\draw [shift={(#2,#3)},#1]  (current page.south west) circle (2pt) 
        \draw [#1]  ($(current page.south west) + (\BottomLeftX,\BottomLeftY) + (#2,#3)$) circle (2pt) 
                node[above right] {#4};
    \end{tikzpicture}%
}


\begin{document}\layout
\lipsum[1-3]
\AbsolutePosition[fill=red,draw=red]{5.0cm}{6.0cm}{$(5,6)$}
\AbsolutePosition[fill=green,draw=green]{2.0cm}{2.0cm}{$(2,2)$}
\AbsolutePosition[fill=blue,draw=blue]{1.0cm}{0.0cm}{$(1,0)$}
\end{document}
17

A LaTeX kernel change from Dec 2018 caused different behavior in \smash, which affected this answer. Thanks to Ulrike for diagnosing the issue for me and providing the best fix at Change in everypage package behavior (which hasn't been revised since 2007)

This method allows you to position at any (x,y) location (relative to upper left corner of paper) on the page, and can be issued regardless of where the current location is. The only requirement is that you know what the top and left margins are, which are incorporated in \atxy. It uses the everypage package.

If you prefer the origin at a different location, for example, relative to the margins, that is a trivial change.

\documentclass{article}
\usepackage{everypage}
\usepackage{xcolor}
\usepackage{lipsum}
% THESE ARE LaTeX DEFAULTS; CAN CHANGE IF NEEDED.
\def\PageTopMargin{1in}
\def\PageLeftMargin{1in}

% ORIGINAL DEFINITION
\newcommand\atxy[3]{%
 \AddThispageHook{\hbox{\smash{\hspace*{\dimexpr-\PageLeftMargin-\hoffset+#1\relax}%
  \raisebox{\dimexpr\PageTopMargin+\voffset-#2\relax}{\textcolor{red}{#3}}}}}}
% VERIFIED THAT SETTING \hoffset AND \voffset DO NOT BREAK SOLUTION.
%\hoffset=0.4in
%\voffset=0.2in
\begin{document}
\atxy{6in}{4in}{(6,4)}
\lipsum[1]
\atxy{0in}{1in}{(0,1)}
\atxy{5in}{6in}{\textbullet(5,6)}
\atxy{5in}{6.2in}{\makebox[0pt]{centered at (5,6.2)}}
\end{document}

enter image description here

13

eso-pic provides hooks into specific page locations:

enter image description here

\documentclass{article}
\usepackage{geometry,lipsum,xcolor}
\geometry{showframe,margin=1in}% Just for this example
\usepackage{eso-pic}
\begin{document}
\AddToShipoutPictureBG*{%
  \AtPageUpperLeft{\raisebox{-\height}{\color{red}Page upper left}}%
  \AtPageLowerLeft{\color{blue}Page lower left}%
}%
\AddToShipoutPictureFG*{%
  \AtPageCenter{\makebox[0pt]{\color{green}\Huge DRAFT}}%
  \AtTextUpperLeft{\raisebox{-\height}{\color{brown}Text upper left}}%
  \AtTextLowerLeft{\color{purple}Text lower left}%
  \AtTextLowerLeft{\hspace*{-.5in}\raisebox{3\baselineskip}{$\bullet$}}
}%
\lipsum
\end{document}

Advantage(s):

  • Single compile;
  • Foreground and/or background placement;
  • Per-page or multiple pages

Disadvantage(s):

  • Absolute positioning requires one of the hooks as a starting point (very minor drawback)

Using the location-hooks as a starting point, one can position content across the page.

The starred [unstarred] versions add content to the current page only [every page from then onward].

0

Some packages wrap this in easier interfaces (notably eso-pic is close to this internally) but basically if you have a fixed point you can construct a TeX box/glue combination of a known size to reach any other point.

By default the known fixed points in latex are the page head and foot, so this takes as origin the left edge of the page head. It might be thought more convenient to take the top left page corner but (in theory) you know the page left and top margin as fixed quantities so that is just a matter of adjusting the coordinates by those fixed lengths.

The example here adds a diagonal line half way across the text block on every page:

enter image description here

\documentclass{article}

\def\z{\stepcounter{enumi}\Roman{enumi}, one two three four five six seven eight nine ten. }
\def\zz{\z\z\z\z\z\z\z\par Red yellow blue. \z Red yellow blue. \z\z Red yellow blue. \z\z\z\z}

\makeatletter
\def\@oddhead{%
\begin{picture}(0,0)
\put(0,0){\circle*{4}}
\put(0,0){\line(1,-1){\strip@pt\dimexpr.5\textwidth\relax}}
\put(\strip@pt\dimexpr.5\textwidth\relax,-\strip@pt\dimexpr.5\textwidth\relax){\circle*{4}}
\end{picture}\hfill
}
\makeatother
\begin{document}

\zz\zz\zz\zz\zz\zz\zz\zz
\end{document}

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.