4

I would like to create an environment like this:

Box with fading shadow

which I have created with this code:

%
% Boxed environment with semi-transparent shadow.
%
\newlength{\boxw}
\newlength{\boxh}
\newlength{\shadowsize}
\newlength{\boxroundness}
\newlength{\tmpa}
\newsavebox{\shadowblockbox}

\setlength{\shadowsize}{6pt}
\setlength{\boxroundness}{3pt}

\newenvironment{shadowblock}[1]%
{\begin{lrbox}{\shadowblockbox}\begin{minipage}{#1}}%
{\end{minipage}\end{lrbox}%
\settowidth{\boxw}{\usebox{\shadowblockbox}}%
\settodepth{\tmpa}{\usebox{\shadowblockbox}}%
\settoheight{\boxh}{\usebox{\shadowblockbox}}%
\addtolength{\boxh}{\tmpa}%
\begin{tikzpicture}
\addtolength{\boxw}{\boxroundness * 2}
\addtolength{\boxh}{\boxroundness * 2}

\foreach \x in {0,.05,...,1}
{
\setlength{\tmpa}{\shadowsize * \real{\x}}
\fill[xshift=\shadowsize - 1pt,yshift=-\shadowsize + 
1pt,black,opacity=.04,rounded corners=\boxroundness] 
(\tmpa, \tmpa) rectangle +(\boxw - \tmpa - \tmpa, \boxh - \tmpa - 
\tmpa);
}

\filldraw[fill=yellow!50, draw=black!50, rounded corners=\boxroundness] (0, 
0) rectangle (\boxw, \boxh);
\draw node[xshift=\boxroundness,yshift=\boxroundness,inner sep=0pt,outer 
sep=0pt,anchor=south west] (0,0) {\usebox{\shadowblockbox}};
\end{tikzpicture}}

As you can see if you compile it has a fading shadow, however, as it uses \minipage in case the text is very long it doesn't split into 2 pages. I have though that this could be achieved with the environment mdframed, however, although it has shadows it doesn't have any fading effect. I have tried for example:

\begin{mdframed}[backgroundcolor=yellow!50,linecolor=black!50,roundcorner=10pt, % shadow=true,
     tikzsetting={shade,
      top color=yellow!50,
      bottom color=yellow!10,
      rounded corners=1pt,
      blur shadow={shadow blur steps=5,shadow blur extra rounding=1.3pt,shadow yshift=-0.5cm}
      }]
\lipsum[4-5]
\end{mdframed}

but when you compile it doesn't correcty draw the shadow:

enter image description here

Any ideas?

7

Update:

The default shadows produced either with mdframed or tcolorbox don't produce the desired effect if the frame splits; however, both packages are powerful enough to admit easy solutions.

Here's one possible solution using mdframed:

\documentclass{article}
\usepackage[a6paper]{geometry}
\usepackage[framemethod=tikz]{mdframed}
\usepackage{lipsum}

\newmdenv[
backgroundcolor=yellow!60,
roundcorner=4ptem,
middleextra={
\foreach \sshift/\svalue in {6/gray!10,5/gray!20,4/gray!30,3/gray!40,2/gray!50,1/gray!60}
  {
  \fill[\svalue] 
    (P) --
    ([xshift=\sshift pt]P) -- 
    ([xshift=\sshift pt]P|-O) --
    (P|-O) -- cycle;
  }
},
secondextra={
\foreach \sshift/\svalue in {6/gray!10,5/gray!20,4/gray!30,3/gray!40,2/gray!50,1/gray!60}
  {
  \fill[\svalue,rounded corners] 
    ([xshift=\sshift]O) --
    ([xshift=\sshift,yshift=-\sshift]O) --
    ([xshift=\sshift,yshift=-\sshift]P|-O)
    {[sharp corners] -- ([xshift=\sshift]P) -- 
    (P)} -- 
    (P|-O) -- ([xshift=\sshift]O);
  }
},
firstextra={
\foreach \sshift/\svalue in {6/gray!10,5/gray!20,4/gray!30,3/gray!40,2/gray!50,1/gray!60}
  {
  \fill[\svalue,rounded corners] 
    ([yshift=-\sshift]P) --
    ([xshift=\sshift,yshift=-\sshift]P) 
    {[sharp corners] -- ([xshift=\sshift]P|-O) -- 
    (P|-O)} -- ([yshift=-\sshift]P);
  }
},
singleextra={
\foreach \sshift/\svalue in {6/gray!10,5/gray!20,4/gray!30,3/gray!40,2/gray!50,1/gray!60}
  {
  \fill[\svalue,rounded corners] 
    ([xshift=\sshift]O) --
    ([xshift=\sshift,yshift=-\sshift]O) --
    ([xshift=\sshift,yshift=-\sshift]P|-O) --
    ([xshift=\sshift,yshift=-\sshift]P) -- +(-6pt,0) --
    (P) -- 
    (P|-O) -- ([xshift=\sshift]O);
  }
},
]{mymdbox}

\begin{document}

\begin{mymdbox}
\lipsum[2]
\end{mymdbox}
\begin{mymdbox}
\lipsum[2]\lipsum[2]\lipsum[2]
\end{mymdbox}

\end{document}

enter image description here

And here's one possible solution using tcolorbox:

\documentclass{article}
\usepackage[a6paper]{geometry}
\usepackage[most]{tcolorbox}
\usepackage{lipsum}

\newtcolorbox{mytcbox}{
breakable,
enhanced,
colback=yellow!60,
overlay middle={
\foreach \sshift/\svalue in {6/gray!10,5/gray!20,4/gray!30,3/gray!40,2/gray!50,1/gray!60}
  {
  \fill[\svalue] 
    (frame.north east) --
    ([xshift=\sshift pt]frame.north east) -- 
    ([xshift=\sshift pt]frame.south east) --
    (frame.south east) -- cycle;
  }
},
overlay last={
\foreach \sshift/\svalue in {6/gray!10,5/gray!20,4/gray!30,3/gray!40,2/gray!50,1/gray!60}
  {
  \fill[\svalue,rounded corners] 
    ([xshift=\sshift]frame.south west) --
    ([xshift=\sshift,yshift=-\sshift]frame.south west) --
    ([xshift=\sshift,yshift=-\sshift]frame.south east)
    {[sharp corners] -- ([xshift=\sshift]frame.north east) -- 
    (frame.north east)} -- 
    (frame.south east) -- ([xshift=\sshift]frame.south west);
  }
},
overlay first={
\foreach \sshift/\svalue in {6/gray!10,5/gray!20,4/gray!30,3/gray!40,2/gray!50,1/gray!60}
  {
  \fill[\svalue,rounded corners] 
    ([yshift=-\sshift]frame.north east) --
    ([xshift=\sshift,yshift=-\sshift]frame.north east) 
    {[sharp corners] -- ([xshift=\sshift]frame.south east) -- 
    (frame.south east)} -- ([yshift=-\sshift]frame.north east);
  }
},
overlay unbroken={
\foreach \sshift/\svalue in {6/gray!10,5/gray!20,4/gray!30,3/gray!40,2/gray!50,1/gray!60}
  {
  \fill[\svalue,rounded corners] 
    ([xshift=\sshift]frame.south west) --
    ([xshift=\sshift,yshift=-\sshift]frame.south west) --
    ([xshift=\sshift,yshift=-\sshift]frame.south east) --
    ([xshift=\sshift,yshift=-\sshift]frame.north east) -- +(-8pt,0) --
    (frame.north east) -- 
    (frame.south east) -- ([xshift=\sshift]frame.south west);
  }
},
before={\vskip1em},
after={\vskip1em},
}

\begin{document}

\begin{mytcbox}
\lipsum[4]
\end{mytcbox}

\begin{mytcbox}
\lipsum[4]\lipsum[4]\lipsum[4]\lipsum[4]
\end{mytcbox}

\end{document}

enter image description here

  • Thanks for your answer, but there's a detail you hadn't caught. When mdframe splits a frame, in 2 pages for example, in the new page the box will not start with the rounded corners, and in the previous page the box will not finish with rounded corners. That is to note that there aren't 2 boxes but one that is splited. It's better understood in the documentation mirrors.ctan.org/macros/latex/contrib/mdframed/… in section 3 "The frames" (page 3) But thanks anyway :) – Álvaro Aug 8 '13 at 21:32
  • @Álvaro I am familiar with the documentation of mdframed. Perhaps you could have a look to the documentation of tcolorbox in search for a similar functionality. – Gonzalo Medina Aug 8 '13 at 21:36
  • @Álvaro I am doing some changes to the original code to produce the effect you want if the frame splits; as soon as it's ready I'll let you know. – Gonzalo Medina Aug 8 '13 at 22:35
  • Gracias, al final llegué a una solución como puedes ver en el post que acabo de publicar ^^ – Álvaro Aug 8 '13 at 23:08
  • @Álvaro en todo caso, he puesto una versión mejorada (aún hay detallitos que pulir), pero las sombras se interrumpen apropiadamente si el marco se parte. In any case, I've updated my answer with an improved version (some details can sill be improven) in which the shadows are interrupted at the proper locations when the frame splits. – Gonzalo Medina Aug 8 '13 at 23:51
0

Thanks to Gonzalo Medida's previous answer I have arrived to a good solution:

\documentclass{article}
\usepackage[a4paper]{geometry}
\usepackage[most]{tcolorbox}

\usepackage{tikz}
\usetikzlibrary{arrows,shadows} % for pgf-umlsd
\usetikzlibrary{shadows.blur}
\usetikzlibrary{shadings}
\usepackage{lipsum}

\newtcolorbox{myboxdos}{
    breakable,enhanced,
    boxrule=0.5pt,
    colback=yellow!50,
    %skin=freelance, % esto "estropea" los bordes cuando se divide un colorbox
    drop fuzzy shadow,
    before=\vspace{1em},
    after=\vspace{1em},
}

\begin{document}

\begin{myboxdos}
\lipsum[1-7]
\end{myboxdos}

\end{document}

The problem with his answer was the missing "enhanced" attribute and that it should not write "skin=XXX" as that overwrites the "enhanced" skin.

And about the shadow, instead of writing individual shadows the "fuzzy" option does that and with the "drop" it automatically places in the righ place.

Besides I have added some extra space before and after the box.

This is the final version: enter image description here

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.