SharePoint modern view formatting with JSON – part 1 of 2
At a Glance
- Target Audience
- SharePoint Admins, List Designers, M365 Developers
- Problem Solved
- Boring default SharePoint list views lacking custom design without heavy coding or governance risks
- Use Case
- Customizing lists into responsive card layouts like venue directories or product catalogs
<p>Stop settling for boring SharePoint lists. Most teams accept the default grid view because they think custom design requires heavy coding or breaks governance policies. It doesn't. You can completely redesign your lists using out-of-the-box JSON formatting.</p>
<p>By the end of this two-part guide, we are going to take this standard list...</p>
<p></p>
<p>And turn it into this responsive set of venue cards.</p>
<p></p>
<h3 id="the-hard-truth-about-json">The Hard Truth About JSON</h3><p>You don't need to be a full-stack developer to build this. You just need to sit down and learn the basic structure. JSON writes data in simple name/value pairs inside curly brackets.</p>
<pre><code class="hljs language-json"><span class="hljs-punctuation">{</span>
<span class="hljs-attr">"Name"</span> <span class="hljs-punctuation">:</span> <span class="hljs-string">"Alice"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"Department"</span> <span class="hljs-punctuation">:</span> <span class="hljs-string">"Accounts"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"PermissionLevel"</span> <span class="hljs-punctuation">:</span> <span class="hljs-string">"Edit"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"hideSelection"</span> <span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span>
<span class="hljs-punctuation">}</span>
</code></pre><p>If you have never touched it before, spend ten minutes with the JSON Syntax - W3 School guide or this JSON Tutorial: Learn JSON in 10 Minutes. You will also need a basic grasp of HTML - w3schools and CSS - w3schools to style the elements. It is not sexy work. It is just consistency.</p>
<h3 id="two-paths-to-format-a-view">Two Paths to Format a View</h3><p>When you format a view using JSON, you have two choices.</p>
<p><strong>1. additionalRowClass</strong><br>Use this when you only care about styling specific columns based on rules. Think highlighting a past-due date in red or forcing all profile pictures to be exactly 200px wide.</p>
<p><strong>2. rowFormatter</strong><br>Use this to completely rebuild the row layout. This creates a custom element for every single list item. If you use both methods together, <code>rowFormatter</code> overrides <code>additionalRowClass</code>. We are using <code>rowFormatter</code> to build our custom list view.</p>
<p>We also want to clean up the user interface. We will set <code>hideSelection</code> to true so users cannot click the raw list item, and <code>hideColumnHeader</code> to true to remove the default table headers.</p>
<h3 id="planning-the-data-structure">Planning the Data Structure</h3><p>First, build your list. Create a custom SharePoint list with these exact columns:</p>
<ul>
<li>Title (single line of text)</li>
<li>Address (single line of text)</li>
<li>Rating (choice)</li>
<li>Maximum capacity (number)</li>
<li>Venue link (hyperlink)</li>
<li>Price (currency)</li>
<li>Picture (picture)</li>
</ul>
<p>Fill it with dummy data.</p>
<p></p>
<h3 id="writing-the-json">Writing the JSON</h3><p>We need a container. We will use a main div (division) that holds three nested child divs. Those child elements will eventually hold our list values.</p>
<p></p>
<p>Download Visual Studio Code. It makes this process painless. Create a new file and save it as a JSON file.</p>
<p></p>
<p>Start with the Microsoft schema. This gives you Intellisense autocomplete.</p>
<pre><code class="hljs language-json"><span class="hljs-punctuation">{</span>
<span class="hljs-attr">"$schema"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json"</span>
<span class="hljs-punctuation">}</span>
</code></pre><p>Without the schema, you are flying blind.</p>
<p></p>
<p>With it, you press Ctrl+Space and get instant suggestions.</p>
<p></p>
<p>Add your UI rules and open the <code>rowFormatter</code>.</p>
<pre><code class="hljs language-json"><span class="hljs-punctuation">{</span>
<span class="hljs-attr">"$schema"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"hideSelection"</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"hideColumnHeader"</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"rowFormatter"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">}</span>
</code></pre><p>Hit Ctrl+Space inside the <code>rowFormatter</code> brackets. You will see your element options.</p>
<p></p>
<p>You have seven element types to choose from.</p>
<p></p>
<p>You can choose <code>div</code> for containers, <code>span</code> for text, <code>a</code> for hyperlinks, <code>button</code> for clickable actions, <code>img</code> for pictures, or <code>svg</code> and <code>path</code> for graphics. We are starting with a <code>div</code>.</p>
<p>JSON does not support standard inline comments. That gets messy fast when you build complex layouts. The workaround is creating a dummy property like <code>"_comment_": "MAIN DIV"</code>. VS Code will flag it as an error, but SharePoint ignores it completely.</p>
<p></p>
<p>Now we add the three child columns inside the main div.</p>
<p></p>
<p>You nest elements using the <code>children</code> array. Notice the square brackets.</p>
<pre><code class="hljs language-json"><span class="hljs-punctuation">{</span>
<span class="hljs-attr">"$schema"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"hideSelection"</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"hideColumnHeader"</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"rowFormatter"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">"elmType"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"div"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"_comment_"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"MAIN DIV"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"style"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span><span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"attributes"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span><span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"children"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
<span class="hljs-punctuation">{</span>
<span class="hljs-attr">"elmType"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"div"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"_comment_"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"DIV ONE"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"style"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span><span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-punctuation">{</span>
<span class="hljs-attr">"elmType"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"div"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"_comment_"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"DIV TWO"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"style"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span><span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-punctuation">{</span>
<span class="hljs-attr">"elmType"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"div"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"_comment_"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"DIV THREE"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"style"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span><span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">]</span>
<span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">}</span>
</code></pre><h3 id="styling-the-structure">Styling the Structure</h3><p>If you apply the code right now, your list will just go blank. It has structure but no style. You don't need to write CSS from scratch. Use a flexbox generator to build the layout visually. I used flexbox's properties to style each div and ensure the cards are responsive for mobile viewing. Just copy the generated CSS into your style attributes.</p>
<p>To make the cards pop, we need a background color. Instead of hardcoding hex values, use Microsoft SharePoint theme colours. Adding a class like <code>ms-bgColor-neutralTertiaryAlt</code> ensures your design natively matches the site theme.</p>
<pre><code class="hljs language-json"><span class="hljs-punctuation">{</span>
<span class="hljs-attr">"$schema"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"hideSelection"</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"hideColumnHeader"</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"rowFormatter"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">"elmType"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"div"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"_comment_"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"MAIN DIV"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"style"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">"display"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"flex"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"flex-wrap"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"wrap"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"align-items"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"stretch"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"flex-direction"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"row"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"padding"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"20px"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"margin-bottom"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"16px"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"max-width"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"930px"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"border-radius"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"8px"</span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"attributes"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">"class"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"ms-bgColor-neutralTertiaryAlt"</span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"children"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
<span class="hljs-punctuation">{</span>
<span class="hljs-attr">"elmType"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"div"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"_comment_"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"DIV ONE"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"style"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">"flex-grow"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"1"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"display"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"flex"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"flex-direction"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"column"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"flex-wrap"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"nowrap"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"align-items"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"stretch"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"max-width"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"260px"</span>
<span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-punctuation">{</span>
<span class="hljs-attr">"elmType"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"div"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"_comment_"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"DIV TWO"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"style"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">"flex-grow"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"1"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"display"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"flex"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"flex-direction"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"column"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"flex-wrap"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"nowrap"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"align-items"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"center"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"max-width"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"310px"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"min-width"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"205px"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"margin-top"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"8px"</span>
<span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-punctuation">{</span>
<span class="hljs-attr">"elmType"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"div"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"_comment_"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"DIV THREE"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"style"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">"flex-grow"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"1"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"display"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"flex"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"flex-direction"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"column"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"align-items"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"center"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"max-width"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"310px"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"min-width"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"155px"</span>
<span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">]</span>
<span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">}</span>
</code></pre><h3 id="applying-the-code">Applying the Code</h3><ol>
<li>Click on the view dropdown in SharePoint.</li>
<li>Select Format current view.</li>
<li>Paste the JSON in.</li>
<li>Click save.</li>
</ol>
<p></p>
<p></p>
<p>You will now see a stack of grey boxes. That is your main div layout working perfectly.</p>
<p></p>
<p>That is the foundation. We built the structure and styled the layout. In part 2, we will map the actual list data into these child divs to finish the cards.</p>
