<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Austin D&#039;Acquisto, Author at DMC, Inc.</title>
	<atom:link href="https://static.dmcinfo.com/blog/author/austind/feed/index.xml" rel="self" type="application/rss+xml" />
	<link></link>
	<description></description>
	<lastBuildDate>Thu, 09 Jul 2026 18:40:10 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.2</generator>

<image>
	<url>https://static.dmcinfo.com/wp-content/uploads/2025/04/site-icon-150x150.png</url>
	<title>Austin D&#039;Acquisto, Author at DMC, Inc.</title>
	<link></link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Step-by-Step Guide: Building a CSS Skeleton in Ignition Perspective</title>
		<link>https://static.dmcinfo.com/blog/45780/ignition-perspective-loading-skeleton-css/</link>
		
		<dc:creator><![CDATA[Austin D'Acquisto]]></dc:creator>
		<pubDate>Thu, 18 Jun 2026 11:00:00 +0000</pubDate>
				<category><![CDATA[Ignition]]></category>
		<category><![CDATA[Manufacturing Automation & Intelligence]]></category>
		<category><![CDATA[Ignition Perspective]]></category>
		<category><![CDATA[UX/UI]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/?p=45780</guid>

					<description><![CDATA[<p>When an Ignition Perspective view takes a moment to load, a blank area can make the page feel unfinished or broken, even if everything is working normally. A loading skeleton solves that by showing a placeholder version of the content before the real data loads. Instead of staring at an empty space, the user sees [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/45780/ignition-perspective-loading-skeleton-css/">Step-by-Step Guide: Building a CSS Skeleton in Ignition Perspective</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">When an Ignition Perspective view takes a moment to load, a blank area can make the page feel unfinished or broken, even if everything is working normally.</p>



<p class="wp-block-paragraph">A loading skeleton solves that by showing a placeholder version of the content before the real data loads. Instead of staring at an empty space, the user sees the shape of the card, chart, or widget that is about to appear.</p>



<p class="wp-block-paragraph">In this post, I will show a straightforward way to build a shimmer loading skeleton in Ignition Perspective using a lightweight skeleton view, a loading Boolean, and a custom style class in the project stylesheet. No JavaScript or custom module is needed.</p>



<h2 class="wp-block-heading" id="h-what-we-are-building">What We are Building</h2>



<ul class="wp-block-list">
<li>Create a normal embedded view for the real content.</li>



<li>Create a second embedded view that is structurally identical but uses placeholder components instead of real data.</li>



<li>Apply the shimmer-style class to those placeholder components.</li>



<li>Toggle between the real view and the skeleton view using a loading Boolean.</li>
</ul>



<p class="wp-block-paragraph" style="padding-bottom:var(--wp--preset--spacing--30)">This works well for KPI cards, summary widgets, charts, tables, and other dashboard elements.</p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-0e47273b wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-image aligncenter size-full is-resized has-custom-border"><img fetchpriority="high" decoding="async" width="377" height="162" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/ignition-perspective-css-loading-skeleton-1.png" alt="Screenshot of a loading screen in Ignition Perspective without CSS overlay." class="wp-image-45828" style="border-top-left-radius:20px;border-top-right-radius:20px;border-bottom-left-radius:20px;border-bottom-right-radius:20px;aspect-ratio:2.327272727272727;object-fit:cover;width:400px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/ignition-perspective-css-loading-skeleton-1.png 377w, https://static.dmcinfo.com/wp-content/uploads/2026/06/ignition-perspective-css-loading-skeleton-1-300x129.png 300w" sizes="(max-width: 377px) 100vw, 377px" /><figcaption class="wp-element-caption"><em>Figure 1: Example metrics widget in its loaded state.</em></figcaption></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-image aligncenter size-full is-resized has-custom-border"><img decoding="async" width="377" height="162" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/main-widget-pretty-skeleton.gif" alt="Gif showing widgets with a CSS loading skeleton, indicating elements are still loading." class="wp-image-45878" style="border-top-left-radius:20px;border-top-right-radius:20px;border-bottom-left-radius:20px;border-bottom-right-radius:20px;width:400px"/><figcaption class="wp-element-caption"><em>Figure 2: The same widget showing the skeleton shimmer during loading.</em></figcaption></figure>
</div>
</div>



<h2 class="wp-block-heading">Step 1: Create a Skeleton Version of the View</h2>



<p class="wp-block-paragraph">Start with your normal view. For example, suppose you already have a card view called MetricCard. Create a second version of it called MetricCardSkeleton.</p>



<p class="wp-block-paragraph">The skeleton version should keep the same overall layout as the real one: the same containers, spacing, padding, alignment, and approximate component sizes.</p>



<p class="wp-block-paragraph">The goal is not to redesign the card. The goal is to make a lightweight placeholder that occupies roughly the same space as the real content.</p>



<p class="wp-block-paragraph">For example, if the real card includes a title, a large OEE number, and a small subtitle, the skeleton version should include placeholders in the same locations.</p>



<figure class="wp-block-image aligncenter size-full is-resized has-custom-border"><img decoding="async" width="917" height="199" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/ignition-perspective-css-loading-skeleton-2.png" alt="Screenshot of a panel outlining a MetricCardSkeleton element with child elements including a header, metric value (LblMetric), and a trend indicator." class="has-border-color has-custom-medium-gray-neutral-2-border-color wp-image-45840" style="border-width:1px;border-top-left-radius:20px;border-top-right-radius:20px;border-bottom-left-radius:20px;border-bottom-right-radius:20px;width:778px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/ignition-perspective-css-loading-skeleton-2.png 917w, https://static.dmcinfo.com/wp-content/uploads/2026/06/ignition-perspective-css-loading-skeleton-2-300x65.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/ignition-perspective-css-loading-skeleton-2-768x167.png 768w" sizes="(max-width: 917px) 100vw, 917px" /><figcaption class="wp-element-caption"><em>Figure 3: Skeleton view created by duplicating the original card and disabling its live bindings.</em></figcaption></figure>



<h2 class="wp-block-heading">Step 2: Use Static Placeholder Text for Sizing</h2>



<p class="wp-block-paragraph">For text-based placeholders, I used normal Label components and applied a custom style class to them.</p>



<p class="wp-block-paragraph">The label text itself is just there to help with spacing and sizing. It does not need to be meaningful, and it should not be bound to live data.</p>



<p class="wp-block-paragraph">For example, if the actual OEE typically shows 47.7%, the skeleton label might simply show 88.8%. That gives the label a realistic width and height while keeping the skeleton lightweight.</p>



<p class="wp-block-paragraph">The same idea applies to titles. You might use a short static label value just to preserve the shape of the final layout.</p>



<figure class="wp-block-image aligncenter size-full is-resized has-custom-border"><img decoding="async" width="405" height="191" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/ignition-perspective-css-loading-skeleton-3.png" alt="Screenshot of a loading screen at 88.8%" class="wp-image-45843" style="border-top-left-radius:20px;border-top-right-radius:20px;border-bottom-left-radius:20px;border-bottom-right-radius:20px;aspect-ratio:2.120432671833745;width:401px;height:auto" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/ignition-perspective-css-loading-skeleton-3.png 405w, https://static.dmcinfo.com/wp-content/uploads/2026/06/ignition-perspective-css-loading-skeleton-3-300x141.png 300w" sizes="(max-width: 405px) 100vw, 405px" /><figcaption class="wp-element-caption"><em>Figure 4: Static placeholder values preserve the size and spacing of the final content</em>.</figcaption></figure>



<h2 class="wp-block-heading">Step 3: Add a Loading Boolean</h2>



<p class="wp-block-paragraph">This is the part that makes the whole pattern actually usable.</p>



<p class="wp-block-paragraph">You need some Boolean value that tells Perspective whether the real content is ready yet. A simple example would be <code>view.custom.isLoading</code>.</p>



<p class="wp-block-paragraph">Set that Boolean however it makes sense for your view. Common options include setting it true until a query returns, until required params are present, until a custom property is populated, or until a dataset or object has usable data.</p>



<p class="wp-block-paragraph">For a simple setup, <code>isLoading</code> should be true while the data is not ready and false once the data is ready.</p>



<p class="wp-block-paragraph">Then bind visibility like this:</p>



<ul class="wp-block-list">
<li>Real view visible when <code>!view.custom.isLoading</code></li>



<li>Skeleton view visible when <code>view.custom.isLoading</code></li>
</ul>



<p class="wp-block-paragraph">This makes the skeleton show first, then disappear once the real content is ready.</p>



<h2 class="wp-block-heading" id="h-step-4-add-a-css-shimmer-style-class-in-perspective">Step 4: Add a CSS Shimmer Style Class in Perspective</h2>



<p class="wp-block-paragraph">In Perspective, style classes can be created in the project stylesheet. I used a single general-purpose class for shimmer text placeholders.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">CSS</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>:root{
  --sk-base:   #FFFFFF1A;
  --sk-radius: 8px;
  --sk-clear:  #FFFFFF00;
}

@keyframes shimmer {
  from { background-position: 200% 0; }
  to   { background-position: -200% 0; }
}

.psc-skeletonTextShimmer {
  background:
    linear-gradient(
      90deg,
      var(--sk-clear) 0%,
      var(--sk-clear) 35%,
      var(--sk-base) 50%,
      var(--sk-clear) 65%,
      var(--sk-clear) 100%
    ),
    var(--sk-base);
  background-size: 200% 100%;
  background-repeat: no-repeat;
  border-radius: var(--sk-radius);
  min-height: 14px;
  animation: shimmer 1.4s ease-in-out infinite both;
  color: #FFFFFF00;
  user-select: none;
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D7BA7D">:root</span><span style="color: #D4D4D4">{</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #9CDCFE">--sk-base</span><span style="color: #D4D4D4">:   </span><span style="color: #CE9178">#FFFFFF1A</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #9CDCFE">--sk-radius</span><span style="color: #D4D4D4">: </span><span style="color: #B5CEA8">8px</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #9CDCFE">--sk-clear</span><span style="color: #D4D4D4">:  </span><span style="color: #CE9178">#FFFFFF00</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #C586C0">@keyframes</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">shimmer</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">  from { </span><span style="color: #9CDCFE">background-position</span><span style="color: #D4D4D4">: </span><span style="color: #B5CEA8">200%</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">; }</span></span>
<span class="line"><span style="color: #D4D4D4">  to   { </span><span style="color: #9CDCFE">background-position</span><span style="color: #D4D4D4">: </span><span style="color: #B5CEA8">-200%</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">; }</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D7BA7D">.psc-skeletonTextShimmer</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #9CDCFE">background</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">linear-gradient</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #B5CEA8">90deg</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #DCDCAA">var</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">--sk-clear</span><span style="color: #D4D4D4">) </span><span style="color: #B5CEA8">0%</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #DCDCAA">var</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">--sk-clear</span><span style="color: #D4D4D4">) </span><span style="color: #B5CEA8">35%</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #DCDCAA">var</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">--sk-base</span><span style="color: #D4D4D4">) </span><span style="color: #B5CEA8">50%</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #DCDCAA">var</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">--sk-clear</span><span style="color: #D4D4D4">) </span><span style="color: #B5CEA8">65%</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #DCDCAA">var</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">--sk-clear</span><span style="color: #D4D4D4">) </span><span style="color: #B5CEA8">100%</span></span>
<span class="line"><span style="color: #D4D4D4">    ),</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">var</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">--sk-base</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #9CDCFE">background-size</span><span style="color: #D4D4D4">: </span><span style="color: #B5CEA8">200%</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">100%</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #9CDCFE">background-repeat</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">no-repeat</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #9CDCFE">border-radius</span><span style="color: #D4D4D4">: </span><span style="color: #DCDCAA">var</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">--sk-radius</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #9CDCFE">min-height</span><span style="color: #D4D4D4">: </span><span style="color: #B5CEA8">14px</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #9CDCFE">animation</span><span style="color: #D4D4D4">: shimmer </span><span style="color: #B5CEA8">1.4s</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ease-in-out</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">infinite</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">both</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #9CDCFE">color</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">#FFFFFF00</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #9CDCFE">user-select</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">none</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">A quick Ignition-specific note: if your Perspective style class is named <code>skeletonTextShimmer</code>, the selector in the stylesheet needs the <code>.psc-</code> prefix: <code>.psc-skeletonTextShimmer</code>.</p>



<p class="wp-block-paragraph">For a deeper dive into this code, see the section <strong><a href="#how-the-css-works">How the CSS Works</a></strong>.</p>



<h2 class="wp-block-heading" id="h-step-5-apply-the-style-class-to-placeholder-labels">Step 5: Apply the Style Class to Placeholder Labels</h2>



<p class="wp-block-paragraph">In the skeleton view, apply the style class to the labels you want to shimmer.</p>



<pre class="wp-block-code"><code>props.style.classes = skeletonTextShimmer</code></pre>



<p class="wp-block-paragraph">You can keep normal label styling for things like:</p>



<ul class="wp-block-list">
<li>font size</li>



<li>font weight</li>



<li>margin</li>



<li>padding</li>



<li>alignment</li>
</ul>



<p class="wp-block-paragraph">The text itself becomes transparent due to CSS, but the label retains its size and layout behavior. That is what makes this pattern so convenient: you are still working with ordinary Perspective components, just styled to look like placeholders.</p>



<p class="wp-block-paragraph"><strong>Tip:</strong> If the shimmer does not appear right away in the Designer, try closing and reopening the view.</p>



<figure class="wp-block-image aligncenter size-full is-resized has-custom-border"><img decoding="async" width="773" height="243" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/ignition-perspective-css-loading-skeleton-4.png" alt="Screenshot showing a view of the CSS panel applying a shimmer overlay to widgets loading in the front end." class="has-border-color has-custom-medium-gray-neutral-2-border-color wp-image-45853" style="border-width:1px;border-top-left-radius:20px;border-top-right-radius:20px;border-bottom-left-radius:20px;border-bottom-right-radius:20px;aspect-ratio:3.1633736172389537;width:778px;height:auto" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/ignition-perspective-css-loading-skeleton-4.png 773w, https://static.dmcinfo.com/wp-content/uploads/2026/06/ignition-perspective-css-loading-skeleton-4-300x94.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/ignition-perspective-css-loading-skeleton-4-768x241.png 768w" sizes="(max-width: 773px) 100vw, 773px" /><figcaption class="wp-element-caption"><em>Figure 5: Apply the skeletonTextShimmer style class to the placeholder label in the Property Editor</em>.</figcaption></figure>



<h2 class="wp-block-heading">Step 6: Show the Skeleton While the Real View Loads</h2>



<p class="wp-block-paragraph">A simple and maintainable way to do this is to use two embedded views in a parent container: one embedded view for <code>MetricCard</code> and one embedded view for <code>MetricCardSkeleton</code>. Then bind each view’s visible property to your loading Boolean.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">JavaScript</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>Skeleton embedded view:
visible = view.custom.isLoading

Real embedded view:
visible = !view.custom.isLoading</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #9CDCFE">Skeleton</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">embedded</span><span style="color: #D4D4D4"> </span><span style="color: #C8C8C8">view</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #9CDCFE">visible</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">view</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">custom</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">isLoading</span></span>
<span class="line"></span>
<span class="line"><span style="color: #9CDCFE">Real</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">embedded</span><span style="color: #D4D4D4"> </span><span style="color: #C8C8C8">view</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #9CDCFE">visible</span><span style="color: #D4D4D4"> = !</span><span style="color: #9CDCFE">view</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">custom</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">isLoading</span></span></code></pre></div>



<p class="wp-block-paragraph">That gives you a very readable setup: when loading is true, show the skeleton; when loading is false, show the real widget. This is often easier to maintain than trying to make one view serve both purposes.</p>



<h2 class="wp-block-heading">Why This Works Well</h2>



<p class="wp-block-paragraph">This pattern gives the user immediate visual structure instead of a blank area.</p>



<p class="wp-block-paragraph">It also reduces layout shift because the skeleton uses the same approximate spacing as the real content.</p>



<p class="wp-block-paragraph">Just as importantly, it stays simple. You are not adding much scripting or frontend complexity. You are duplicating the layout, replacing live content with static placeholders, toggling visibility with a Boolean, and using one reusable CSS class.</p>



<h2 class="wp-block-heading">A Few Practical Tips</h2>



<p class="wp-block-paragraph"><strong>Keep the skeleton lightweight:</strong> Do not bind the placeholder labels to live data. Their job is just to hold space and show the shimmer effect.</p>



<p class="wp-block-paragraph"><strong>Match the real layout closely:</strong> The closer the skeleton matches the final card, the smoother the transition feels.</p>



<p class="wp-block-paragraph">Use realistic placeholder lengths: For percentages, use something like 88.8%. For short titles, use placeholder text of similar length. That helps preserve spacing.</p>



<p class="wp-block-paragraph"><strong>Hide overflow if needed:</strong> If a placeholder label could get awkwardly sized, setting overflow-related text styling can help keep the skeleton clean.</p>



<h2 class="wp-block-heading" id="how-the-css-works">How the CSS Works</h2>



<p class="wp-block-paragraph">If you mainly want the implementation, you can stop after applying the class and wiring up the loading Boolean. If you are curious about how the shimmer works, here is the breakdown.</p>



<h3 class="wp-block-heading">Root Variables</h3>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">CSS</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>:root{
  --sk-base:   #FFFFFF1A;
  --sk-radius: 8px;
  --sk-clear:  #FFFFFF00;
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D7BA7D">:root</span><span style="color: #D4D4D4">{</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #9CDCFE">--sk-base</span><span style="color: #D4D4D4">:   </span><span style="color: #CE9178">#FFFFFF1A</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #9CDCFE">--sk-radius</span><span style="color: #D4D4D4">: </span><span style="color: #B5CEA8">8px</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #9CDCFE">--sk-clear</span><span style="color: #D4D4D4">:  </span><span style="color: #CE9178">#FFFFFF00</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">These are reusable values for the skeleton effect.</p>



<ul class="wp-block-list">
<li><code>--sk-base</code> is the main placeholder color</li>



<li><code>--sk-radius</code> keeps the skeleton corners rounded</li>



<li><code>--sk-clear</code> is a fully transparent color used inside the shimmer gradient</li>
</ul>



<p class="wp-block-paragraph">Using CSS variables makes it easier to tweak the look later without rewriting the whole class.</p>



<h3 class="wp-block-heading">Keyframe Animation</h3>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">CSS</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>@keyframes shimmer {
  from { background-position: 200% 0; }
  to   { background-position: -200% 0; }
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #C586C0">@keyframes</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">shimmer</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">  from { </span><span style="color: #9CDCFE">background-position</span><span style="color: #D4D4D4">: </span><span style="color: #B5CEA8">200%</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">; }</span></span>
<span class="line"><span style="color: #D4D4D4">  to   { </span><span style="color: #9CDCFE">background-position</span><span style="color: #D4D4D4">: </span><span style="color: #B5CEA8">-200%</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">; }</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">This animation moves the background image from right to left.</p>



<p class="wp-block-paragraph">The shimmer effect is not a separate moving object. It is just the background gradient sliding across the component over time.</p>



<h3 class="wp-block-heading">The Background Layers</h3>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">CSS</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>background:
  linear-gradient(
    90deg,
    var(--sk-clear) 0%,
    var(--sk-clear) 35%,
    var(--sk-base) 50%,
    var(--sk-clear) 65%,
    var(--sk-clear) 100%
  ),
  var(--sk-base);</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">background:</span></span>
<span class="line"><span style="color: #D4D4D4">  linear-gradient(</span></span>
<span class="line"><span style="color: #D4D4D4">    90deg,</span></span>
<span class="line"><span style="color: #D4D4D4">    var(--sk-clear) 0%,</span></span>
<span class="line"><span style="color: #D4D4D4">    var(--sk-clear) 35%,</span></span>
<span class="line"><span style="color: #D4D4D4">    var(--sk-base) 50%,</span></span>
<span class="line"><span style="color: #D4D4D4">    var(--sk-clear) 65%,</span></span>
<span class="line"><span style="color: #D4D4D4">    var(--sk-clear) 100%</span></span>
<span class="line"><span style="color: #D4D4D4">  ),</span></span>
<span class="line"><span style="color: #D4D4D4">  var(--sk-base);</span></span></code></pre></div>



<p class="wp-block-paragraph">There are two background layers here:</p>



<ol class="wp-block-list">
<li>A <code>linear gradient</code> (…) that creates the moving shimmer band</li>



<li>A solid var(<code>--sk-base</code>) layer underneath it</li>
</ol>



<p class="wp-block-paragraph">The gradient is mostly transparent, with a slightly visible band in the middle. As it moves, that band creates the shimmer effect.</p>



<h3 class="wp-block-heading">Background Size and Repeat</h3>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">CSS</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>background-size: 200% 100%;
background-repeat: no-repeat;</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">background-size</span><span style="color: #D4D4D4">: 200% 100%;</span></span>
<span class="line"><span style="color: #569CD6">background-repeat</span><span style="color: #D4D4D4">: </span><span style="color: #569CD6">no-repeat</span><span style="color: #D4D4D4">;</span></span></code></pre></div>



<p class="wp-block-paragraph"><code>background-size</code> makes the animated gradient wider than the component itself, which gives the shimmer room to move across the element instead of appearing static.</p>



<p class="wp-block-paragraph"><code>background-repeat</code>: no-repeat keeps the gradient from tiling in ways that look messy or unnatural.</p>



<p class="wp-block-paragraph"><code>border-radius </code>keeps the skeleton shape visually aligned with the rest of the UI.</p>



<p class="wp-block-paragraph"><code>min-height </code>helps prevent small labels from collapsing too much.</p>



<p class="wp-block-paragraph">The animation line applies the shimmer keyframes and controls the speed, easing, and repetition.</p>



<h3 class="wp-block-heading">Transparent Text and Text Selection</h3>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">CSS</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>color: #FFFFFF00;
user-select: none;</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">color: </span><span style="color: #F44747">#FFFFFF00;</span></span>
<span class="line"><span style="color: #569CD6">user-select</span><span style="color: #D4D4D4">: none;</span></span></code></pre></div>



<p class="wp-block-paragraph"><code>color</code> hides the label text without removing the label itself.</p>



<p class="wp-block-paragraph">That is important because the label is still doing layout work for us. It keeps its width, height, margins, padding, and font-based sizing, but the user sees only the animated background.</p>



<p class="wp-block-paragraph"><code>user-select: none</code> prevents users from accidentally highlighting invisible text while the skeleton is visible.</p>



<h2 class="wp-block-heading">Final Thoughts</h2>



<p class="wp-block-paragraph">This is a small UX improvement, but it makes a Perspective project feel much more polished.</p>



<p class="wp-block-paragraph">Instead of showing a blank region while data loads, you can show a placeholder that matches the real layout and communicates that the screen is actively loading.</p>



<p class="wp-block-paragraph" style="padding-bottom:var(--wp--preset--spacing--40)">The main pieces are simple: a real view, a skeleton view, static placeholder components, a loading Boolean, and one shimmer style class. Once you set up the pattern, it becomes easy to reuse across the rest of the project.</p>



<div class="wp-block-group alignwide has-custom-light-blue-background-color has-background is-layout-flow wp-container-core-group-is-layout-dbd34961 wp-block-group-is-layout-flow" style="border-radius:20px;margin-top:var(--wp--preset--spacing--50);margin-bottom:var(--wp--preset--spacing--50);padding-top:var(--wp--preset--spacing--50);padding-right:0;padding-bottom:var(--wp--preset--spacing--50);padding-left:0">
<div class="wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-43efaee5 wp-block-columns-is-layout-flex" style="padding-right:var(--wp--preset--spacing--60);padding-left:var(--wp--preset--spacing--60)">
<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:85%">
<h3 class="wp-block-heading has-text-align-left" id="h-have-an-upcoming-project-dmc-can-help-you-take-the-next-step"><strong>Ready to take your Ignition Perspective project to the next level?</strong></h3>



<p class="has-text-align-left wp-block-paragraph" id="h-need-help-turning-ideas-into-outcomes-automation-project-to-the-next-level-contact-us-today-to-learn-more-about-our-solutions-and-how-we-can-help-you-achieve-your-goals">Contact DMC to learn how our <a href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/">Automation</a> team can help you build polished, high-performance applications in <a href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/hmi-and-scada-programming/ignition-programming/">Ignition</a>.</p>
</div>



<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:15%">
<div class="wp-block-buttons is-horizontal is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-2236275c wp-block-buttons-is-layout-flex">
<div class="wp-block-button is-style-fill"><a class="wp-block-button__link has-base-contrast-color has-text-color has-link-color wp-element-button" href="https://static.dmcinfo.com/contact/">Contact Us</a></div>
</div>
</div>
</div>
</div>
<p>The post <a href="https://static.dmcinfo.com/blog/45780/ignition-perspective-loading-skeleton-css/">Step-by-Step Guide: Building a CSS Skeleton in Ignition Perspective</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
