English-only | Jenom česky | Bilingual/Dvojjazyčně

CSS Technique: Photo Cards

Řešení CSS: Obrázky s popiskami

On the web, we often need to place a picture together with its description, caption etc. It's easy to place other elements around the image, but if the image is floating (left or right), it's a bit more complicated. In the pre-CSS era nested tables were used for it (as for everything). However, we can use CSS as well — maybe better than tables.

The solution is simple. Whole set of elements (image, cation, attached text) is enclosed in a block (e.g. DIV). Now we can style it and set float:left, or float:right as well. Though, we have to remember the width of floated blocks must be set (otherwise they may be spread to the full width and there's no floating). Of course, we can solve it by setting display:inline to the DIV — the width of floating element is then adjusted by its content. But we have to remove all blocks inside it (inline elenent must not contain blocks) and use only line breaks BR. Sometimes this simplified formatting may be sufficient.

Following example uses the width 170px.

Na webu často potřebujeme umístit k fotografii také její popisek, případně další informace (nadpis, autora, copyright atd.). Není jistě nic složitého umístit kolem obrázku nějaké další prvky, ale pokud se jedná o obrázek "zalomený" v textu (plovoucí vlevo či vpravo), už to tak prosté není. Dříve se to řešilo tabulkami (co se dříve neřešilo tabulkami?), s CSS to ale jde taky. Ne-li líp.

Postup je prostý — celou sadu informací (obrázek, nadpis, připojený text) uzavřeme do jednoho bloku (např. DIV), nastavíme mu potřebný vzhled a přidáme vlastnost float:left, nebo float:right. Nesmíme ovšem zapomínat, že plovoucí bloky musí mít explicitně nastavenu šířku (jinak se roztáhnou na celou šířku a je po obtékání). Pochopitelně to lze obejít, když tomuto DIVu nastavíme display:inline — plovoucí prvek pak svou šířku přizpůsobí šířce svého obsahu, ale musíme z něj odstranit všechny odstavce a další bloky, které se v inline prvku nesmí vyskytovat. Můžeme nanejvýš použít odřádkování BR. Je ale jistě řada případů, kdy i toto omezené formátování postačí.

V následujícím příkladu je použita šířka 170px.

    .card-left, .card-right {
       float: left;
       width: 170px;
       margin: 0 15px 15px 0;
       padding: 10px 0;
       text-align: center;
       background: white;
       border-right: 1px solid #ccc;
       border-bottom: 1px solid #ccc;
       font-size: 75%;
       }
    .card-right {
       float: right;
       margin: 0 0 15px 15px;
       }
...

   <div class="card-left">
      <h2 class="card-title">... title...</h2>
      <p class="card-photo"><img ... /></p>
      <p class="card-desc">... description...</p>
      <p class="card-info">... info...</p>
   </div>

Our Photo

Me and Mary in Venice. Summer 2004.

Photo by Bobbyinfo

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur vel lacus id odio eleifend varius. Donec id metus nec lorem consectetuer dictum. Curabitur tempus. Mauris gravida, dui eget adipiscing tincidunt, felis sapien feugiat justo, id bibendum odio tellus sit amet arcu. Nulla placerat, metus id viverra aliquam, libero ligula rutrum urna, non convallis ante nunc tincidunt dui. Pellentesque fermentum, leo id facilisis pulvinar, leo nunc consectetuer orci, vitae sollicitudin urna mauris ac urna. Etiam sollicitudin fringilla lectus. Donec ultricies interdum eros. Sed tincidunt diam in erat. In hac habitasse platea dictumst. In hac habitasse platea dictumst. Donec adipiscing leo lacinia wisi elementum mollis. Integer varius wisi quis elit. Suspendisse non turpis. Aliquam diam diam, elementum nec, vulputate nec, aliquet vel, erat. Phasellus eleifend sodales dui. Ut venenatis hendrerit ligula. Donec in nibh.

Our Photo

Second picture, this time on the right side.

Photo by Maryinfo

Proin ut libero. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla malesuada ultricies orci. Maecenas commodo wisi in ante. Fusce odio dolor, tincidunt quis, imperdiet a, interdum non, odio. Cras laoreet nisl vel erat mattis convallis. Etiam molestie. Nam massa tellus, semper vel, mollis id, euismod id, neque. Etiam convallis tempus elit. Proin fringilla bibendum nisl.

Curabitur feugiat enim eu felis. Vivamus massa odio, venenatis eget, ultricies iaculis, ullamcorper nec, est. Cras magna libero, convallis et, scelerisque ut, rhoncus quis, elit. Fusce mi. Fusce magna est, sodales a, suscipit in, lacinia et, nunc.


We can make simple photo album by placing more of these "cards" next to each other. Their content is formatted uniformly and thanks to the float:left they'll be formatted in a row until there's enough place for next card.

Everything's OK until all cards have the same height. If one of preceding elements is higher, we've got a problem: the next row of cards will start after this element. Try to see the example 1 changing the browser's window width (to change the count of cards in a row). You'll see how the floating elements are rearranging according to the available width.

Mostly, we can solve it easy. We may give the same height to all cards — probably by guessing, according to the height of the heighest card (320px in the next example). But because we often can't assure unique height (users can change the font size and font type etc.), we may want to set overflow:auto for the cards — in case there is not enough height, a scrollbar is displayed to scroll the content. See the example 2.

Pokud takových obrázkových "karet" dáme víc za sebe, můžeme tak vytvořit jednoduché fotoalbum. Obsah karet je formátovaný jednotně a díky float:left se budou řadit za sebe, dokud se vejdou na řádek. Pokud se další karta na řádek nevejde, posune se na řádek další — přesněji řečeno (a to je menší kámen úrazu) posune se na další řádek tam, kam ji "pustí" předchozí plovoucí "kartičky".

Pokud budou všechny stejně vysoké, nic se neděje. Problém ale nastane, když je jeden z předchozích plovoucích prvků vyšší než ostatní. Další řádek plovoucích kartiček proto začne až za tímto prvkem. Zkuste se podívat na příklad 1 s různou šířkou okna prohlížeče (aby se na řádek vešel vždy jiný počet karet), uvidíte, jak se plovoucí prvky přesypávají podle toho, jaké na ně zbude místo.

Ve většině případů to ale můžeme snadno vyřešit. Stačí všem "kartičkám" nastavit stejnou výšku — nejlépe odhadem, podle výšky nejvyšších kartiček (v našem příkladu 320px). A protože často nemůžeme jednotnou výšku zajistit (uživatelé si mohou změnit velikost a typ písma a mohou změnit i další hodnoty), tak pro případ, že by se do nejvyšších kartiček obsah náhodou nevešel, nastavíme jim ještě overflow:auto — to zajistí, že bude-li obsah vyšší než nastavená výška, zobrazí se na kartičce posuvník. Viz příklad 2.