7

I want to create the following:

enter image description here

That is, a rectangle with partly invisible edges.

How can I do that?

What I have now:

\documentclass{article}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
\node[draw,rectangle,minimum width=8cm,minimum height=2cm] {lorem ipsum};
\end{tikzpicture}
\end{document}

5 Answers 5

9

Less elegant than Jasper Habicht's answer, but if you only need that box maybe it is simpler.

\documentclass{article}
\usepackage{tikz}

\newcommand{\mybox}[2][black]{%
  \begin{tikzpicture}
    \node[rectangle,minimum width=8cm,minimum height=2cm, font=\Large] (A) {#2};
    \draw[#1, line width = 3pt] 
      (A.north west) -- +(.3,0) -- (A.north west) -- +(0,-.4) 
      (A.north east) -- +(-.3,0) -- (A.north east) -- +(0,-.4) 
      (A.south west) -- +(.3,0) -- (A.south west) -- +(0,.4) 
      (A.south east) -- +(-.3,0) -- (A.south east) -- +(0,.4) 
      ;
   \end{tikzpicture}%
}

\begin{document}
\mybox{lorem ipsum}
\vspace{1cm}

\mybox[red]{lorem ipsum}
\end{document}

enter image description here

EDIT: parametric length

\documentclass{article}
\usepackage{tikz}

\newcommand{\mybox}[3][black]{%
  \begin{tikzpicture}
    \node[rectangle,minimum width=8cm,minimum height=2cm, font=\Large] (A) {#2};
    \draw[#1, line width = 3pt] 
      (A.north west) -- +(#3,0) -- (A.north west) -- +(0,-#3) 
      (A.north east) -- +(-#3,0) -- (A.north east) -- +(0,-#3) 
      (A.south west) -- +(#3,0) -- (A.south west) -- +(0,#3) 
      (A.south east) -- +(-#3,0) -- (A.south east) -- +(0,#3) 
      ;
   \end{tikzpicture}%
}

\begin{document}
\mybox{lorem ipsum}{.3}
\vspace{1cm}

\mybox[red]{lorem ipsum}{.3}
\vspace{1cm}

\mybox{lorem ipsum}{.4}
\vspace{1cm}

\mybox[green]{lorem ipsum}{.4}
\vspace{1cm}

\mybox{lorem ipsum}{.7}
\vspace{1cm}

\mybox[cyan]{lorem ipsum}{.7}
\end{document}

enter image description here

9
  • I am looking for a way to change the lengths .3 and .4 more quickly. Can you show me a way to define a new "dimensionless" length to be used instead of the explicit numbers that are used now? Doing \newlength demands a unit to be assigned to the new length. There isn't any unit in this case. I also want to define this length locally - only inside the current tikzpicture.
    – tush
    Commented Apr 19, 2023 at 11:27
  • @tush How does this length be? A proportion of the segments?
    – CarLaTeX
    Commented Apr 19, 2023 at 15:01
  • Well that's what I am questioning myself. When you say \draw (0,0) -- (0.3,0);, 0.3 points, or cm, or what unit?
    – tush
    Commented Apr 19, 2023 at 15:04
  • @tush The default is cm, but you can use any units you like
    – CarLaTeX
    Commented Apr 19, 2023 at 15:08
  • Well then, how can I define a length in the tikzpicture so I can make changes to the many .3 sizes at once?
    – tush
    Commented Apr 19, 2023 at 15:09
11

The best thing would probably be to create your own shape.

Here, it's also much easier to take the outer seps into account.

\documentclass{article}
\usepackage{tikz}
\pgfset{corners rectangle size/.initial=10pt}
\makeatletter
\pgfdeclareshape{corners rectangle}{%
    \inheritsavedanchors[from=rectangle]%
    \inheritanchorborder[from=rectangle]%
    \inheritanchor[from=rectangle]{north}%
    \inheritanchor[from=rectangle]{north west}%
    \inheritanchor[from=rectangle]{north east}%
    \inheritanchor[from=rectangle]{center}%
    \inheritanchor[from=rectangle]{west}%
    \inheritanchor[from=rectangle]{east}%
    \inheritanchor[from=rectangle]{mid}%
    \inheritanchor[from=rectangle]{mid west}%
    \inheritanchor[from=rectangle]{mid east}%
    \inheritanchor[from=rectangle]{base}%
    \inheritanchor[from=rectangle]{base west}%
    \inheritanchor[from=rectangle]{base east}%
    \inheritanchor[from=rectangle]{south}%
    \inheritanchor[from=rectangle]{south west}%
    \inheritanchor[from=rectangle]{south east}%
    \foregroundpath{
    % store lower right in xa/ya and upper right in xb/yb
      \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
      \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
      \pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/outer xsep}}%
      \pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/outer ysep}}%
      \advance\pgf@xa by \pgf@xc \advance\pgf@xb by -\pgf@xc
      \advance\pgf@ya by \pgf@yc \advance\pgf@yb by -\pgf@yc
      \pgfmathsetlength\pgfutil@tempdima{\pgfkeysvalueof{/pgf/corners rectangle size}}%
      \pgfpathmoveto{\pgfqpoint{\dimexpr\pgf@xa+\pgfutil@tempdima}{\pgf@ya}}%
      \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@ya}}%
      \pgfpathlineto{\pgfqpoint{\pgf@xa}{\dimexpr\pgf@ya+\pgfutil@tempdima}}%
      \pgfpathmoveto{\pgfqpoint{\dimexpr\pgf@xa+\pgfutil@tempdima}{\pgf@yb}}%
      \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}%
      \pgfpathlineto{\pgfqpoint{\pgf@xa}{\dimexpr\pgf@yb-\pgfutil@tempdima}}%
      \pgfpathmoveto{\pgfqpoint{\dimexpr\pgf@xb-\pgfutil@tempdima}{\pgf@ya}}%
      \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@ya}}%
      \pgfpathlineto{\pgfqpoint{\pgf@xb}{\dimexpr\pgf@ya+\pgfutil@tempdima}}%
      \pgfpathmoveto{\pgfqpoint{\dimexpr\pgf@xb-\pgfutil@tempdima}{\pgf@yb}}%
      \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}}%
      \pgfpathlineto{\pgfqpoint{\pgf@xb}{\dimexpr\pgf@yb-\pgfutil@tempdima}}%
      \pgfsetarrowsstart{}%
      \pgfsetarrowsend{}%
    }%
}%
\makeatother
\begin{document}
\begin{tikzpicture}[minimum width=8cm, minimum height=2cm, nodes=corners rectangle]
\node[draw] {lorem ipsum};
\node[corners rectangle size=15pt, draw=red, thick] at (0, -3) (a) {lorem ipsum};
\foreach \ang in {5,...,20} \draw (a.\ang) --+(\ang:.5);
\end{tikzpicture}
\end{document}

enter image description here


As an easy workaround, you can make use of append after command and the like.

With \pgfsettransform we make sure that the same transformation are used that were applied to the node, making this independently from the path those corners are drawn on.

There's no consideration for outer sep or the line width.

\documentclass{article}
\usepackage{tikz}
\tikzset{
  draw corners/.style={
    append after command={\bgroup
      \pgfextra{\pgfsettransform{\csname pgf@sh@nt@\tikzlastnode\endcsname}}
      [to path=|-(\tikztotarget)]
                   ([yshift=-\pgfkeysvalueof{/tikz/draw corners size}]\tikzlastnode.north west)
          edge[#1] ([xshift= \pgfkeysvalueof{/tikz/draw corners size}]\tikzlastnode.north west)
                   ([yshift=-\pgfkeysvalueof{/tikz/draw corners size}]\tikzlastnode.north east)
          edge[#1] ([xshift=-\pgfkeysvalueof{/tikz/draw corners size}]\tikzlastnode.north east)
                   ([yshift= \pgfkeysvalueof{/tikz/draw corners size}]\tikzlastnode.south east)
          edge[#1] ([xshift=-\pgfkeysvalueof{/tikz/draw corners size}]\tikzlastnode.south east)
                   ([yshift= \pgfkeysvalueof{/tikz/draw corners size}]\tikzlastnode.south west)
          edge[#1] ([xshift= \pgfkeysvalueof{/tikz/draw corners size}]\tikzlastnode.south west)
      \egroup}},
  draw corners size/.initial=10pt}
\begin{document}
\begin{tikzpicture}[rectangle, minimum width=8cm, minimum height=2cm]
\path[rotate=30]node[rotate=10, draw corners] at (0,0) {lorem ipsum};
\tikzset{draw corners size=15pt}
\node[scale=.5, draw corners={red, thick}] at (0,-3) {lorem ipsum};
\end{tikzpicture}
\end{document}

enter image description here


You could also use path picture to avoid nesting paths:

\documentclass{article}
\usepackage{tikz}

\tikzset{
    draw corners/.style={
        path picture={
            \draw[#1]
                (path picture bounding box.north west) 
                    +(\pgflinewidth,-\pgfkeysvalueof{/tikz/draw corners size}) |- 
                    +(\pgfkeysvalueof{/tikz/draw corners size},-\pgflinewidth)
                (path picture bounding box.south west) 
                    +(\pgflinewidth,\pgfkeysvalueof{/tikz/draw corners size}) |- 
                    +(\pgfkeysvalueof{/tikz/draw corners size},\pgflinewidth)
                (path picture bounding box.north east) 
                    +(-\pgflinewidth,-\pgfkeysvalueof{/tikz/draw corners size}) |- 
                    +(-\pgfkeysvalueof{/tikz/draw corners size},-\pgflinewidth)
                (path picture bounding box.south east) 
                    +(-\pgflinewidth,\pgfkeysvalueof{/tikz/draw corners size}) |- 
                    +(-\pgfkeysvalueof{/tikz/draw corners size},\pgflinewidth);
        }
    },
    draw corners size/.initial=10pt
}

\begin{document}
\begin{tikzpicture}

\node[draw corners, rectangle, minimum width=8cm, minimum height=2cm] 
    at (0,0) {lorem ipsum};

\end{tikzpicture}
\end{document}
3
  • One should not use paths in \pgfextra. To see why, add for instance rotate=30 to one of your nodes. You can use a path picture instead.
    – user294623
    Commented Apr 14, 2023 at 0:40
  • @Displayname You are right: transformations have to be handled with care this way (but you could say \node[rotate=10, draw corners={rotate=10}] {};). However, you cannot rotate the node when using path picture either without getting strange results, at least not when using path picture bounding box. Commented Apr 14, 2023 at 4:35
  • Thanks! The outer sep is my weak spot it seems =) Commented Apr 14, 2023 at 8:37
9

One option whithout tikz: just a table.

mwe

\documentclass[twocolumn]{article}
\usepackage{lipsum,parskip}
\usepackage{tabulary}
\def\notecorner#1{\medskip\par{\noindent\centering\begin{tabulary}{\linewidth}{cJc}
\cline{1-1}\cline{3-3}\multicolumn{1}{|c}{}&&\multicolumn{1}{c|}{}\\
&#1&\\\multicolumn{1}{|c}{} &  & \multicolumn{1}{c|}{}\\
\cline{1-1}\cline{3-3}\end{tabulary}\medskip\par}}
\begin{document}

\lipsum[1][1-5]

\notecorner{\lipsum[2][1]}

\lipsum[3][1-5]

\end{document}
5

Here you have two more solutions.

The first one uses path picture option to define a TiKZ style with all node's corners. This way the extra path proposed by CarlaTeX is not needed.

The second defines a tcolorbox instead of a TiKZ node.

\documentclass{article}
\usepackage{tikz}

\usepackage[most]{tcolorbox}

\usepackage{lipsum}

\newtcolorbox{corners}[1][]{%
    enhanced, colback=white, sharp corners,
    colframe=blue,
    frame code={%
        \draw[tcbcolframe] ([xshift=5mm]frame.north west)-|+(-5mm,-4mm);
        \draw[tcbcolframe] ([xshift=-5mm]frame.north east)-|+(5mm,-4mm);
        \draw[tcbcolframe] ([xshift=5mm]frame.south west)-|+(-5mm,4mm);
        \draw[tcbcolframe] ([xshift=-5mm]frame.south east)-|+(5mm,4mm);
    },
    #1
}

\tikzset{
    corners/.style={%
        path picture={%
            \draw[#1] ([xshift=5mm]path picture bounding box.north west)-|+(-5mm,-4mm);
            \draw[#1] ([xshift=-5mm]path picture bounding box.north east)-|+(5mm,-4mm);
            \draw[#1] ([xshift=5mm]path picture bounding box.south west)-|+(-5mm,4mm);
            \draw[#1] ([xshift=-5mm]path picture bounding box.south east)-|+(5mm,4mm);
        }
    },
    corners/.default={}
}
\newcommand{\mybox}[2][black]{%
\begin{tikzpicture}
\node[minimum width=8cm,minimum height=2cm, font=\Large, corners=#1] (A) {#2};
\end{tikzpicture}%
}

\begin{document}
\mybox{lorem ipsum}
\vspace{1cm}

\mybox[green, line width=1mm]{lorem ipsum}

\begin{corners}
\lipsum[1][1-3]
\end{corners}

\begin{corners}[colframe=red]
\lipsum[1][2-4]
\end{corners}
\end{document}

enter image description here

0

Based on @CarLaTeX's answer, this one

  • Supports using x=<dimen>, y=<dimen> to change the corner size,
  • Makes sure each line segment is drawn only once. (Previously horizontal segments were drawn twice.)
\documentclass{article}
\usepackage{tikz}

\newcommand{\mybox}[2][black]{%
  \begin{tikzpicture}
    \node[rectangle, minimum width=8cm, minimum height=2cm, font=\Large] (A) {#2};
    \draw[x=.3cm, y=.4cm, line width = 3pt, #1]
      (A.north west) +( 1,0) -- (A.north west) -- +(0,-1) 
      (A.north east) +(-1,0) -- (A.north east) -- +(0,-1) 
      (A.south west) +( 1,0) -- (A.south west) -- +(0, 1)
      (A.south east) +(-1,0) -- (A.south east) -- +(0, 1)
      ;
   \end{tikzpicture}%
}

\begin{document}
\mybox{lorem ipsum}
\bigskip

\mybox[red, x=1.5cm, y=.2cm]{lorem ipsum}
\bigskip

\mybox[cyan!50, dotted, x=.5cm, y=.5cm, rounded corners=.2cm]{lorem ipsum}
\end{document}

enter image description here

3
  • No. You introduce a coordinates distortion. I am looking for a way to do \draw (1cm,2pt) -- +(a,0) or \draw (3in,4mm) -- +(0,a) with a equal simply to .3. Perhaps I should ask a new question regarding this. I am afraid that your answer doesn't introduce a new way for the original question.
    – tush
    Commented Apr 19, 2023 at 20:27
  • muzimuzhiZ and @CarLaTeX Silly me. I just learned that I have already asked about it before.
    – tush
    Commented Apr 19, 2023 at 20:36
  • A coordinates distortion? only sort of. Any coordinates with explicit units are not distorted. To use a in \draw (1cm,2pt) -- +(a,0), a must be a pgfmath function declared either by \pgfmathdeclarefunction or tikz math libraray syntax or /tikz/declare function key. But if using \a is also supported, then \a can be either of a normal LaTeX command or length. Commented Apr 19, 2023 at 21:07

You must log in to answer this question.

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