Unyson framework provides WordPress users a number of handy shortcodes for the visual editor. These shortcodes are great for non-technical content authors who need to do complex WordPress layout. One site I manage uses the Unyson Table shortcode to publish a contact list of volunteers. This works great, except it isn’t mobile-friendly. I decided to fix that.

First, I over-rode the shortcode by copying the Table shortcode folder from the Unyson plugin into my theme. Specifically, I copied everything in:

/wp-content/plugins/unyson/framework/extensions/shortcodes/shortcodes/table/*

to:

/wp-content/themes//framework-customizations/extensions/shortcodes/shortcodes

This allowed me to override the shortcode without directly modifying the plugin.

Next, beginning at line 9, I replaced the code in

/wp-content/plugins/unyson/framework/extensions/shortcodes/shortcodes/table/views/tabular.php

with:

Untitled3
Click to Zoom

This replaced the classic table code with a series of div blocks. With the data organized into div blocks I can do the rest in CSS. I also had to add a non-breaking space to each cell at the end of line 24 to keep the div from collapsing if the cell was empty.

Granted, my code hack makes a couple assumptions about the data. There will always be a header row, it will be the first row, and there will never be more than one header row. I don’t like being this lazy, but it fit my use case and my time was limited for this project. That’s my disclaimer.

I also wanted this approach to be flexible, so I targeted this particular table in my stylesheet by adding an ID of cc-contact-table to the containing column in the Unyson Page Builder. I use a prefix of “cc-” on all my CSS markup in my theme to differentiate it from other plugin and framework markup. By targeting in this way I can have multiple tables in the site with different number of columns and column titles.

This style sheet displays the div blocks as a table if the browser is wide enough, and pivots the data to single column if too narrow. When displayed as a single column, it hides the column title row and prepends the data elements with the old column headings. I also play with the fonts and do alternating row colors.

Here’s the result, skip to the end to see all the CSS.

Here’s the result in table mode (apologies for all the black bars – I redacted it for the customer):

Untitled4

Here’s the result in narrow column mode:

Untitled 5

Many thanks to Chris Coyier at css-tricks.com. I stole extensively from his posting “Responsive Data Tables“. I’d recommend reading his article as well, he explains some of the finer details and I see no sense in re-writing his excellent explanation. My contribution is combining his technique with individual table targeting and merging that technique into the Unyson framework override.

The full CSS as promised.

#cc-contact-table .cc-table {
    width: 100%;
    display: table;
}

#cc-contact-table .cc-headrow {
    display: table-header-group;
    background-color: #444;
    font-weight: bold;
    color: #FFF;
}

#cc-contact-table .cc-headcell {
    display: table-cell;
    padding: 8px;
    text-align: justify;
    border-bottom: 1px solid black;
}

#cc-contact-table .cc-datarowgroup {
    display: table-row-group;
}

#cc-contact-table .cc-datarow {
    display: table-row;
}

#cc-contact-table .cc-datarow:nth-child(even) {background: #EEE}
#cc-contact-table .cc-datarow:nth-child(odd) {background: #FFF}

#cc-contact-table .cc-datacell {
    display: table-cell;
    padding: 8px;
}

#cc-contact-table .cc-datacell:nth-of-type(1) {
    font-weight: bold;
}


@media
only screen and (max-width: 760px),
(min-device-width: 768px) and (max-device-width: 1024px)  {

/* Force table to not be like tables anymore */
#cc-contact-table .cc-table,
#cc-contact-table .cc-headrow,
#cc-contact-table .cc-headcell {
    display: block;
}

#cc-contact-table .cc-datarowgroup,
#cc-contact-table .cc-datarow,
#cc-contact-table .cc-datacell {
    display: block;
    padding: 4px;
}

/* Hide table headers (but not display: none;, for accessibility) */
#cc-contact-table .cc-headrow .cc-headcell {
position: absolute;
    top: -9999px;
    left: -9999px;
}

#cc-contact-table .cc-datarow { border: 1px solid #ccc; }
#cc-contact-table .cc-datacell:nth-of-type(1) {
    /* Behave  like a "row" */
    border: none;
    border-bottom: 1px solid #ccc;
    position: relative;
    padding-left: 50%;
}

#cc-contact-table .cc-datacell:nth-of-type(2) {
/* Behave  like a "row" */
    border: none;
    border-bottom: 1px solid #ccc;
    position: relative;
    padding-left: 50%;
    font-size: 80%;
}

#cc-contact-table .cc-datacell:nth-of-type(3) {
/* Behave  like a "row" */
    border: none;
    border-bottom: 1px solid #ccc;
    position: relative;
    padding-left: 50%;
    font-size: 80%;
}

#cc-contact-table .cc-datacell:nth-of-type(4) {
/* Behave  like a "row" */
    border: none;
    position: relative;
    padding-left: 50%;
    font-size: 80%;
}

#cc-contact-table .cc-datacell:before {
/* Now like a table header */
    position: absolute;
/* Top/left values mimic padding */
    top: 6px;
    left: 6px;
    width: 45%;
    padding-right: 10px;
    white-space: nowrap;
}

/*
Label the data
*/
#cc-contact-table .cc-datacell:nth-of-type(1):before { 
    content: "Position"; 
}
#cc-contact-table .cc-datacell:nth-of-type(2):before { 
    content: "Name"; 
}
#cc-contact-table .cc-datacell:nth-of-type(3):before { 
    content: "Contact"; 
}
#cc-contact-table .cc-datacell:nth-of-type(4):before { 
    content: "Notes"; 
}

}
<!--