64

I come from a HTML / CSS background and am used to a particular way of setting margins, floats, etc. As a beginner in TeX, I am having a hard time positioning elements, probably because my mindset is still in CSS positioning and I do not yet grasp the TeX way. After struggling for two hours, I now more or less set up a letterhead that I soon want to set out as a background (which I just learned here). But I feel my code took way too long (I'm learning, but still) to write and not clean (I feel I'm using the wrong commands). So to get a better grasp on positioning, I would like to ask how I should get this done:

enter image description here

This is something I made in HTML and it is supposed to be the header of a letter (used a placeholder logo for this sample). From my standpoint, this is what I need to do:

  • Create a page with this particular height and width
  • Set the text to appear in the vertical center, and with a little distance from the left
  • Float the logo to the right hand side, with a little space from the top and right

After my struggle, this is the code I put together:

\documentclass[a4paper]{article}
\usepackage{graphicx}
\graphicspath{{./img/}}
\usepackage{color}
\usepackage{xcolor}
\definecolor{grey}{HTML}{F4F4F4}
\definecolor{darkgrey}{HTML}{333333}
\usepackage{wrapfig}
\usepackage{fullpage}
\usepackage[margin=0.1cm, paperwidth=497pt, paperheight=40mm]{geometry}

\begin{document}

\pagecolor{grey}

\begin{wrapfigure}{r}{3cm}
\includegraphics[height=3cm]{html5}
\end{wrapfigure}

\Large \textcolor{darkgrey}{\\ \\ \textbf{Our Company} \\ Our Slogan}

\end{document}

This is what I get:

enter image description here

My problems:

  • I had to use several newlines to get the text centered vertically. If I used vfill, my logo jumped away.
  • The logo borders are 'rugged', whereas they are smooth in the HTML version. The logo is high resolution and looks fine if I zoom in in the PDF to 500%, but it looks bad at 100%.
  • The way I float the image feels wrong. It's quite some code to just float it (remember, I come from float:right, so I am biased here, maybe this is the way to go)... is that how it should be?

Any other tips on better understanding floating and margins is appreciated, especially taking into consideration these kinds of 'designs' rather than articles and more standard text documents.

2
  • 6
    actually this question is neither about floats (in the TeX sense) nor about margins. It is in, my opinion, about how to position objects relative to each other with some defined spatial relationship. So I think both the title as well as the classification should change. Feb 11, 2012 at 0:46
  • This is similiar to my question link
    – s0rce
    Feb 15, 2012 at 21:25

5 Answers 5

55

In All(TeX), like in html/css everything is a box. When Håkon Wium Lie developed CSS he based a lot of the CSS concepts on TeX (see Wium Lie's phd thesis).

So in order to follow what is happening with the code we will do two things; first put everything in its own box and secondly frame everything using a LaTeX \fbox. TeX provides two major types of boxes \hbox and \vbox. LaTeX provides many more such as \parbox, \minipage, \fbox etc.

First you will need to place the image:

 \fbox{%
  \vbox to 0pt{\hbox to 12cm{\hfill \fbox{\includegraphics[height=3cm]{graphic}}}}
 }

enter image description here

The important thing to observe is that it is exactly the same concept used in html/css when you place an element in a div and that is why, you need to clear empty divs in html. In TeX we can get the same effect by using a \vbox of 0pt height. The floating to the right can be achieved using an \hfill. Depending on where you place the \hfill command the image can "float" left or right. Using \hfill\image commands\hfill will center it. But remember though that there is no such thing as a float, in (La)TeX.

If we modify the \vbox to 3.2cm, we can get the image to be as follows. This though will not be very useful, as we want to place the Company name and the slogan to start on "line 2".

enter image description here

At a general level you can think of \hbox and \vbox as being very similar to divs. Placing the Company name and slogan in similar boxes we can get the following.

enter image description here

We can move the elements vertically by using the TeX command \vskip which we set to zero in the above example. Setting it to a more suitable value, we get:

enter image description here

In the last example we set all the "padding" and "borders" to zero, by setting \fboxsep and \fboxrule to 0pt.

For code that you might encounter many times, is best to write macros rather than lump everything in long statements. This is good computer programming in general and follows the DRY Principle (do not repeat yourself).

\def\addslogan#1{%
  \fbox{\kern2pt \sloganfonthook #1}
}

Your suggestion that the code is longer than html/css/javascript is doubtful. I understand you coming from float:right, but you forgot all about having to clear divs etc and the pain the web went through with browser incompatibilities, starting from slicing everything and placing it in tables, and the almost impossible way to vertically center elements in html/css. When learning a new programming language you need to spend a bit of time to develop your own style and base knowledge.

And finally here is the MWE:

\documentclass[a4paper]{article}
\usepackage{graphicx}
\graphicspath{{./img/}}
%\usepackage{color}
\usepackage{xcolor}
\definecolor{grey}{HTML}{F4F4F4}
\definecolor{darkgrey}{HTML}{333333}
%\usepackage{wrapfig} not needed
%\usepackage{fullpage} not needed
\usepackage[paperwidth=130mm,top=10pt, paperheight=130mm,left=0.5cm,right=0.5cm]{geometry}
\parindent0pt

\def\addslogan#1{%
  \fbox{\kern2pt \sloganfonthook #1}
}

\def\sloganfonthook{\large\sffamily \color{darkgrey}}
\begin{document}
\pagecolor{grey}
\fboxsep0pt
\fboxrule0pt

\fbox{\vbox to 0pt{\hbox to 12cm{\hfill \fbox{\includegraphics[height=3cm]{image}}}}}
\vskip30pt
\fbox{\vbox{\fbox{\Large\textcolor{darkgrey}{\textbf{OUR COMPANY Inc.}}}\par
}}

\addslogan{Everything  about typesetting with \TeX\ and friends}
\end{document}

As a final remark, you do not need the wrapfig, color or the fullpage package to achieve what you want. The easiest way to set margins is with the geometry as you have done.

12
  • 1
    @Niriel The normal (La)TeX way is to put it in a box measure the box dimensions. My normal way and to keep things simple I estimate it and try it out a couple of times. As Ulrike Fischer pointed out in her answer one needs to do minor adjustments as the optical center is not always the same as the mathematical center. In a package or class I would definitely measure it and provide some means to adjust manually as well.
    – yannisl
    Feb 10, 2012 at 13:23
  • 1
    Awesome explanation. I'm working on this right now... but one question: why use \fbox if \mbox is borderless anyway? Is there an advantage of fbox over mbox?
    – user
    Feb 11, 2012 at 1:53
  • 1
    There is no advantage. I've used it to show borders so that I could explain what is happening. I do that in my own programs as well.
    – yannisl
    Feb 12, 2012 at 0:51
  • 1
    @MartinSchröder Thanks for your comment. In this particular example I thought the use of \vbox and \hbox were more appropriate rather than the longish minipages and parboxes or the horrendously obscure \hb@xt@. IMHO there is nothing wrong in mixing, as long as you aware of potential pitfalls (none in this case) or am I missing something? No-one will insist that you program in python only with the use of library commands, why so in LaTeX?
    – yannisl
    Feb 15, 2012 at 10:03
  • 3
    @MartinSchröder Me will probably be watching everything from greener pastures by the time LaTeX3 is officially launched with \let\l_v_box_:N\vbox, \let\vbox\undefined:)
    – yannisl
    Feb 15, 2012 at 17:43
39

As explained in the other answers TeX has a model through which you can place boxes inside boxes and somehow get your positioning done. For general graphics this is not really very satisfactory, even though in practice you can do essentially everything with enough effort.

LaTeX added to this a picture environment in which you are able to position according to some underlying "grapical coordination system. Again this isn't really what one is looking for in your example as one has to calculate the coordinate positions somehow for each object in the graphic.

What you really want instead is to specify the relations between objects, eg the right-hand center of object A is aligned with the bottom left of object B offset by some space, etc.

The LaTeX3 approach

So after having seen plain TeX and LaTeX kind of solutions let me offer you the LaTeX3 solution which is called "coffins": a coffin is a box with a large number of handles you can refer to and align with handles on other coffins. With this approach the solution to your problem could look like this:

\documentclass{article}

\usepackage{xcolor} \definecolor{darkgrey}{HTML}{333333}

\usepackage{xcoffins}

\begin{document}

  \NewCoffin \result
  \NewCoffin \aaa
  \NewCoffin \bbb
  \NewCoffin \ccc
  \NewCoffin \ddd

\SetHorizontalCoffin \result {}

\SetHorizontalCoffin \aaa {\Large\color{darkgray}\bfseries Our Company}
\SetHorizontalCoffin \bbb {\Large\color{darkgray}\bfseries Our Slogan}
\SetHorizontalCoffin \ccc  {\color{red}\rule{1.5cm}{3cm}}
\SetHorizontalCoffin \ddd {\small\color{blue}\sf\bfseries HTML}

% put \aaa into \result
\JoinCoffins \result \aaa

% align bottom-right of \aaa with top-right of \bbb (with 8pt vertical offset)
\JoinCoffins \result [\aaa-b,\aaa-r]  \bbb [t,r](0pt,-8pt)

% align vertical-center-left of current \result with vertical-center-right of \ccc (offset by \textwidth)
\JoinCoffins \result [vc,l]  \ccc [vc,r](\textwidth,0pt)

% center the word HTML directly on top of the logo 
\JoinCoffins \result [\ccc-t,\ccc-hc] \ddd [b,hc]

\noindent\TypesetCoffin \result

some sample text some sample text some sample text some sample text some sample text

\end{document}

This will lead to the following result:

enter image description here

A couple of notes here:

  • With just two or three objects to place it is a little bit more work than some of the other solutions.
  • However it comes with the inbuild flexibility to change the design in all aspects easily.
  • I aligned the slogan on the right deliberately just to show how easy you can alter your design
  • The result is a text object that explains the need for \noindent
  • The implementation of coffins for expl3 is stable. However the user-level interface isn't yet! Right now we have two alternatives, one with a keyval system and one just with optional arguments, I used the latter above. But both might get refinements, especially after we get feedback from people actually "designing" with it.

As a teaser I like to display a titlepage from a magazin by Tschichold from 1925 which I recreated using coffins for my talk about them at the TUG conference 2010.

I would be interested who would attempt to do that in the plain TeX box model approach:

enter image description here

This was achieved with setting up 10 coffins and joining them together at the right handles, i.e., 10 join commands.

2
  • 2
    Where can I learn more about coffins after watching the slides of the talk? I'm more interested in the algebra (elements, operations, properties) of coffins than the details of the implementation. Jan 2, 2013 at 21:36
  • 2
    @ChristianLindig there is not that much that has been written about it. But a starting point would be the documentation in xcoffins.dtx (which is the suggested user interface for the low-level functionality). you find this on CTAN in ctan.org/pkg/xcoffins if it isn't already part of your installation. In addition you need the expl3 base package to "use" it. Comments and suggestions are welcome! The high-level interface and functionality isn't yet carved in stone. Jan 2, 2013 at 22:03
29

The following is a rather plain-TeX way of doing it. I've removed everything but the essentials.

\documentclass{article}
\usepackage{graphicx}

\begin{document}

\hbox to \textwidth{%
 \hskip 2mm% For some space on the left
 \vbox to 3cm{%
  \vfil
  \hbox{\textbf{Our company}}
  \hbox{Our Slogan}
  \vfil
 }%
 \hfil
 \includegraphics[height=3cm]{html5}%
 \hskip 2mm% For some space on the right
}

\end{document}

I apologize for not doing it the "right" way in LaTeX; unfortunately, I am rather inept at using the LaTeX variants of plain TeX boxing and spacing constructs.

As for the logo being ragged: if it works at a higher resolution, I suspect it's just the limitations of your viewer's scaling. This happens a lot with graphics.

Edit: Maybe I should comment that your expectations of the word "float" are not quite how it is used in TeX. In particular, "float:right" is like \hfil(l)(l) (though it can get quite awful if you want to wrap text around it; hence wrapfig, as you no doubt discovered). A "float" in TeX is something that floats not only vertically, but also between pages. It's not really appropriate to use one for something like a letterhead, which has absolute positioning, but rather for a figure or table (like the LaTeX environments of the same names) that displays data that is referred to by the text but not necessarily synchronous with its flow.

1
  • 4
    I was just going to post exactly the same answer… :-) Feb 10, 2012 at 5:54
20

And here a more LaTeX-like solution

\documentclass[a4paper]{article}
\usepackage{xcolor,array}
\definecolor{grey}{HTML}{F4F4F4}
\definecolor{darkgrey}{HTML}{333333}
\usepackage[margin=0.1cm, paperwidth=497pt, paperheight=40mm]{geometry}
\setlength\topskip{0pt}
\begin{document}
\pagecolor{grey}
\vspace*{\fill}
\Large
\begin{tabular}{@{}>{\color{darkgrey}}l}
\bfseries Our Company \\    \normalsize Our Slogan
\end{tabular}   
\hfill\raisebox{-0.5\height}{\rule{2cm}{3cm}}

\vspace{\fill}

\end{document}

You should be aware that centering things vertically is not a very well defined concept. Characters (and so also lines of text) have a height and a depth and they are not very symmetric. How e.g. would you vertically center a large A? To get an optical pleasing result it is often sensible to move a text manually away from a mathematical center point.

enter image description here

14

As others have pointed out, in TeX terminology, what you want to achieve is not a float. ConTeXt provides a combinations environment to place objects side-by-side. This is primarily meant for subfloats, but works well for this example as well.

\definecombination[logo] 
                  [
                    distance={1pt plus 1fill},
                    location=middle,
                    width=\textwidth,
                  ]

\startbuffer[company-details]
\framed[frame=off, align=normal]
  {{\bfb Company Name} \crlf
    Company slogan
  }
\stopbuffer


\starttext
\startcombination[logo]
  {\getbuffer[company-details]}{}
  {\externalfigure[http://placekitten.com/g/200/300][method=png]}{}
\stopcombination
\stoptext

which gives

enter image description here

The main idea is to set distance={1pt plus 1fill}. This allows the space between the two objects to expand until the total space is equal to \textwidth (set using width=\textwidth).

The location=middle key ensures that the logo text and the logo image are vertically centred. If you want the logo to be top aligned or bottom aligned, you can set location=top or location=bottom.

Internally, this is same as the plain-TeX solution that Ryan Reich gave; ConTeXt just provides a nice key-value driven wrapper around it.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .