I have a php application for a cookbook site. To make this application responsive for all devices, I need to convert the listing of ingredients from a table format to div's but I am having a challenge with how to set-up the div structure and css.

To better explain what I have presently and what I want, kindly .

This is a typical block of recipe ingredients:

<table id="recipe">
    <tr>
        <td class="ingramt">2½</td>
        <td class="ingred">cups flour</td>
        <td class="ingramt">1 tbsp</td>
        <td class="ingred">baking powder</td>
    </tr>
    <tr>
        <td class="ingramt">½ cup</td>
        <td class="ingred">butter or shortening</td>
        <td class="ingramt">1</td>
        <td class="ingred">egg</td>
    </tr>
    <tr>
        <td class="ingramt">1 tsp</td>
        <td class="ingred">salt</td>
        <td colspan="2" class="merged">some milk</td>
    </tr>
</table>

As you can see from the mark-up, I have four table columns to create two columns of data. For higher resolutions I want the div's and css to render the appearance much the same as the table method. Using media queries in the css for screen widths like smart-phones, I desire the two table columns of data on the right to appear below the two on the left but using divs. (Refer to the demo website stated above to see what I mean)

The mark-up for div's would appear much like:

<div id="recipe">
    <div class="ingredBlock">
        <div class="ingramt">2½</div>
        <div class="ingred">cups flour</div>
        <div class="ingramt">1 tbsp</div>
        <div class="ingred">baking powder</div>
    </div>
    <div class="ingredBlock">
        <div class="ingramt">½ cup</div>
        <div class="ingred">butter or shortening</div>
        <div class="ingramt">1</div>
        <div class="ingred">egg</div>
    </div>
    <div class="ingredBlock">
        <div class="ingramt">1 tsp</div>
        <div class="ingred">salt</div>
        <div class="merged">some milk</div>
    </div>
</div>

Can someone think of a better method for the desired effect? What would the css have to be for aligning divs as required?

Dani AI

Generated

A pragmatic, modern approach is CSS Grid: keep simple "pair" elements (quantity + name) in one flat sequence, let the grid lay them out into two visual columns on wide screens and stack them on small screens. This preserves reading order, makes colspan-like "full-width" lines easy to handle, and avoids fragile float hacks. (Agree with that real <table> is fine for tabular data, and with / that display:table can be useful — Grid just gives more predictable control for responsive reflow. is also right that a list is semantically cleaner than raw divs.)

Example (structure you can generate from PHP):

<div class="ingredients" style="grid-template-rows: repeat(3, auto);">
  <div class="pair"><span class="qty">2½</span><span class="name">cups flour</span></div>
  <div class="pair"><span class="qty">½ cup</span><span class="name">butter or shortening</span></div>
  <div class="pair"><span class="qty">1 tsp</span><span class="name">salt</span></div>

  <div class="pair"><span class="qty">1 tbsp</span><span class="name">baking powder</span></div>
  <div class="pair"><span class="qty">1</span><span class="name">egg</span></div>
  <div class="pair full"><span class="name">some milk</span></div>
</div>

CSS sketch:

.ingredients { display: grid; grid-template-columns: 1fr 1fr; grid-auto-flow: column; gap: .25rem 1rem; }
.pair { display: grid; grid-template-columns: auto 1fr; align-items: center; }
.qty { text-align: right; padding-right: .5rem; white-space: nowrap; }
.pair.full { grid-column: 1 / -1; grid-template-columns: 1fr; }
@media (max-width:640px){ .ingredients { grid-template-columns: 1fr; grid-auto-flow: row; grid-template-rows: none; } }

Server-side hint (PHP): build a flat array of "pairs", compute $rows = ceil(count($pairs)/2) and emit the inline style grid-template-rows: repeat($rows, auto) so Grid fills column-1 top-to-bottom then column-2. Mark any colspan items as full and output them as a normal pair (they will span both columns).

Troubleshooting tips: set white-space: nowrap or max-width on quantities to avoid wrapping; use overflow-wrap on ingredient text; test keyboard/screen-reader order (DOM order should be logical); if you must support ancient browsers, provide a simple float/flex fallback.

Recommended Answers

All 7 Replies

Nothing wrong with using tables in a responsive site. Just make sure that word wrap is on. Some data by its nature is not able to be completly responsive though, and thats ok ...

Another option would be to put it in a horizontal form with labels. These would stack nicely if the viewport was to small.

you should probably use the table & table-cell css 'display' parameters if needing to implement any grid-type layout with divs. Alternatively I would continue using tables if you need to display actual tabular data.

See http://ajaxian.com/archives/display-table for a good discussion of the 2 approaches!

You could try something like this.. you will need to change the css. I didn't test it out but you can get the just of it.

<form action="" method="" />
<h3 class="table-head">Table Header</h3>
<div class="table-row">
    <label class="row-label">Label</label>
    <div class="row-input">
    <input type="text" name="" value="" />
    </div>
</div>
<div class="table-row">
    <label class="row-label">Label</label>
    <div class="row-input">
    <input type="text" name="" value="" />
    </div>
</div>
<div class="table-row">
    <label class="row-label">Label</label>
    <div class="row-input">
    <input type="text" name="" value="" />
    </div>
</div>
<div class="table-row">
    <label class="row-label">Label</label>
    <div class="row-input">
    <input type="text" name="" value="" />
    </div>
</div>
</form>




.table-row {
    display:table;
    border-top:1px solid #dddddd;
    border-right:1px solid #dddddd;
    border-left:1px solid #dddddd;
    padding:5px 0;
    overflow:hidden
}

.table-row:last-child {
    border-bottom:1px solid #dddddd;
}

.row-label {
    display:table-cell;
    width:100px;
    line-height:1.5em;
}

.row-input {
    padding:10px 5px;
}

Could you not use an unordered list? Seems to suit the situation better

An unordered list would not suffice because of the need for consistent placement between the amount of the ingredient and the ingredient. A gutter/invisible cell-border is necessary.

I think using display:table on the <li> elements, and then display:table-cell on <span> elements inside each may allow you to use a ul (more semantically correct) with a grid layout (how you want it displayed)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.