

<?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>css筆記 &#8211; Max的程式語言筆記</title>
	<atom:link href="https://stackoverflow.max-everyday.com/category/css/feed/" rel="self" type="application/rss+xml" />
	<link>https://stackoverflow.max-everyday.com</link>
	<description>我要當一個豬頭，快樂過每一天</description>
	<lastBuildDate>Thu, 18 Jun 2026 09:01:23 +0000</lastBuildDate>
	<language>zh-TW</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://stackoverflow.max-everyday.com/wp-content/uploads/2017/02/max-stackoverflow-256.png</url>
	<title>css筆記 &#8211; Max的程式語言筆記</title>
	<link>https://stackoverflow.max-everyday.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>CSP (Content Security Policy) 的網站要如何安全的使用 Inline script</title>
		<link>https://stackoverflow.max-everyday.com/2026/06/csp-content-security-policy-%e7%9a%84%e7%b6%b2%e7%ab%99%e8%a6%81%e5%a6%82%e4%bd%95%e5%ae%89%e5%85%a8%e7%9a%84%e4%bd%bf%e7%94%a8-inline-script/</link>
					<comments>https://stackoverflow.max-everyday.com/2026/06/csp-content-security-policy-%e7%9a%84%e7%b6%b2%e7%ab%99%e8%a6%81%e5%a6%82%e4%bd%95%e5%ae%89%e5%85%a8%e7%9a%84%e4%bd%bf%e7%94%a8-inline-script/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Thu, 18 Jun 2026 09:01:22 +0000</pubDate>
				<category><![CDATA[css筆記]]></category>
		<category><![CDATA[css]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=8583</guid>

					<description><![CDATA[當你在幫網站做健康檢查，看到弱掃報告（ 像是 Z...]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">當你在幫網站做健康檢查，看到弱掃報告（ 像是 ZAP ）跳出一個橘黃色的 Medium 警告，寫著 <code>style-src 'unsafe-inline'</code> 或是發現 <code>script-src</code> 滿是漏洞時，心裡是不是頓時涼了一半？</p>



<p class="wp-block-paragraph">簡單來說，如果你的 CSP （ 網頁安全政策 ）開了 <code>unsafe-inline</code> ，就等於是在大門裝了密碼鎖，卻把密碼用便利貼貼在門口一樣。駭客只要找到機會塞一段惡意腳本（ XSS 攻擊 ），你的網站就直接變成他的遊樂場。</p>



<p class="wp-block-paragraph">但是偏偏像是 Google Tag Manager （ GTM ）這種必裝的分析工具，官方給的程式碼裡面就是有一大段 Inline Script ：</p>



<p class="wp-block-paragraph">HTML</p>



<pre class="wp-block-code"><code>&lt;script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"&gt;&lt;/script&gt;
&lt;script&gt;
  window.dataLayer = window.dataLayer || &#91;];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'G-XXXXXXXXXX');
&lt;/script&gt;
</code></pre>



<p class="wp-block-paragraph">既想要防禦 XSS 攻擊，又不能把 GTM <sup></sup>拔掉，這時候你有兩條路可以走，讓我們來看看這兩個相愛相殺的解決方案。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">方案一：使用 Nonce （ 一次性密碼鎖 ）</h3>



<p class="wp-block-paragraph">這個方法就像是去看演唱會，每次進場工作人員都會在你的手上蓋一個當天限定、過期失效的印章。</p>



<p class="wp-block-paragraph">在 CSP 標頭（ Header ）裡，你可以這樣設定：</p>



<p class="wp-block-paragraph">HTTP</p>



<pre class="wp-block-code"><code>Content-Security-Policy: script-src 'nonce-每天換的神秘亂數密碼'; img-src www.googletagmanager.com
</code></pre>



<p class="wp-block-paragraph">然後在你的網頁程式碼中，那段 GTM 的標籤也必須帶上相同的密碼：</p>



<p class="wp-block-paragraph">HTML</p>



<pre class="wp-block-code"><code>&lt;script nonce='每天換的神秘亂數密碼'&gt;
  // GTM 的扣（Code）放這裡
&lt;/script&gt;
</code></pre>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 工程師真心話</h4>



<ul class="wp-block-list">
<li><strong>優點</strong>：超級安全。因為駭客根本猜不到你下一個 Request 的亂數密碼是什麼，就算他成功塞了惡意指令，也會因為沒有通關密碼而被瀏覽器直接擋在門外。</li>



<li><strong>缺點（ 也就是坑 ）</strong>：這非常考驗後端的大腦。你的伺服器必須在「 每次 」收到請求時，都用高強度的加密演算法生出一組全新的隨機字串。最慘的是，你的網頁從此跟「 回應快取 」（ Response Cache ）說再見，因為一旦網頁被快取，密碼就不會變了，那這個鎖就形同虛設。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">方案二：使用 Hash （ 驗收指紋認證 ）</h3>



<p class="wp-block-paragraph">如果你的網站是 SPA （ 單頁應用程式 ），或是部署在 GitHub Pages 這種根本沒有後端可以幫忙生密碼的靜態伺服器，那 Hash 就是你的救星。</p>



<p class="wp-block-paragraph">這個概念是，瀏覽器會直接去核對這段程式碼的「 指紋 」。</p>



<p class="wp-block-paragraph">步驟非常簡單，把 <code>&lt;script&gt;</code> 到 <code>&lt;/script&gt;</code> 之間的程式碼內容，丟到 <a target="_blank" rel="noreferrer noopener" href="https://stackoverflow.max-everyday.com/wp-admin/post.php?post=8583&amp;action=edit">SHA256 線上計算工具</a> 裡面去跑一下，會得到一串像是 <code>0bbd063b7...</code> 的雜湊值（ Hash ）。</p>



<p class="wp-block-paragraph">接著把這串指紋放進你的 CSP 設定裡：</p>



<p class="wp-block-paragraph">HTTP</p>



<pre class="wp-block-code"><code>Content-Security-Policy: script-src 'sha256-計算出來的那串指紋'; img-src www.googletagmanager.com
</code></pre>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 工程師真心話</h4>



<ul class="wp-block-list">
<li><strong>優點</strong>：前端自己就能搞定，不需要後端伺服器配合，而且網頁依然可以開開心心地做快取，提升載入速度。</li>



<li><strong>缺點（ 最雷的地方 ）</strong>：
<ol start="1" class="wp-block-list">
<li><strong>字元敏感度破表</strong>：SHA256 是一個極度龜毛的演算法。只要你的程式碼裡面多了一個空格、少了一個換行，甚至不同工程師的電腦存檔時，斷行符號一個是 LF （ <code>\n</code> ）一個是 CRLF （ <code>\r\n</code> ），算出來的指紋就完全不一樣。指紋一對不上，你的 GTM 就會直接被 CSP 射下來。</li>



<li><strong>維護地獄</strong>：哪天行銷團隊突然要求修改 GTM 裡面的參數，只要動到一個字，你就必須重新計算一次 Hash 值、重新更新 CSP 標頭。如果交接沒做好，後續接手的工程師改了程式碼發現網站功能壞掉，可能要在電腦前哭著找兇手找很久。</li>
</ol>
</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">總結防禦指南</h3>



<p class="wp-block-paragraph">想要高枕無憂、後端架構也撐得住，請選 <strong>Nonce</strong> 。</p>



<p class="wp-block-paragraph">如果是靜態網站、追求速度與快取，請選 <strong>Hash</strong> ，但每次改動程式碼時，請記得去燒香拜拜順便更新指紋。</p>



<p class="wp-block-paragraph">總之，快把 <code>unsafe-inline</code> 從你的 CSP 裡面拿掉，別再讓你的網站裸奔了。</p>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2026/06/csp-content-security-policy-%e7%9a%84%e7%b6%b2%e7%ab%99%e8%a6%81%e5%a6%82%e4%bd%95%e5%ae%89%e5%85%a8%e7%9a%84%e4%bd%bf%e7%94%a8-inline-script/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>網頁開發者必看！用白話秒懂 CSS Injection 與 CSP 防禦</title>
		<link>https://stackoverflow.max-everyday.com/2026/06/css-injection-csp-url/</link>
					<comments>https://stackoverflow.max-everyday.com/2026/06/css-injection-csp-url/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Thu, 18 Jun 2026 06:39:22 +0000</pubDate>
				<category><![CDATA[css筆記]]></category>
		<category><![CDATA[React 筆記]]></category>
		<category><![CDATA[css]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=8572</guid>

					<description><![CDATA[為什麼連寫個看起來無害的 CSS 都會被瀏覽器當...]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="572" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2026/06/css-injection-csp-url__clean-1024x572.jpg?v=1781764740" alt="" class="wp-image-8579" srcset="https://stackoverflow.max-everyday.com/wp-content/uploads/2026/06/css-injection-csp-url__clean-1024x572.jpg?v=1781764740 1024w, https://stackoverflow.max-everyday.com/wp-content/uploads/2026/06/css-injection-csp-url__clean-600x335.jpg?v=1781764740 600w, https://stackoverflow.max-everyday.com/wp-content/uploads/2026/06/css-injection-csp-url__clean-768x429.jpg?v=1781764740 768w, https://stackoverflow.max-everyday.com/wp-content/uploads/2026/06/css-injection-csp-url__clean.jpg?v=1781764740 1376w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">為什麼連寫個看起來無害的 CSS 都會被瀏覽器當成恐怖份子。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">瀏覽器的大內總管：CSP 到底在嚴格什麼？</h2>



<p class="wp-block-paragraph">各位前端與後端苦力們，有沒有遇過這種慘劇？</p>



<p class="wp-block-paragraph">當你興高采烈地在網站加上這行內容安全政策（CSP）：</p>



<pre class="wp-block-code"><code><code>Content-Security-Policy: default-src 'self';</code></code></pre>



<p class="wp-block-paragraph">本以為從此高枕無憂，結果下一秒打開網頁，發現自己寫的行內腳本（inline-script）全部陣亡：</p>



<pre class="wp-block-code"><code><code>&lt;script&gt;console.log('連我都不能跑是怎樣');&lt;/script&gt;</code></code></pre>



<p class="wp-block-paragraph">好啦，大家都知道 JavaScript 權限大、壞人最愛用，所以瀏覽器預設不讓它亂跑很合理。為了安撫大內總管，我們還得乖乖去算雜湊值（Hash）或是塞個 nonce 安全憑證，像是這樣：</p>



<pre class="wp-block-code"><code><code>Content-Security-Policy: default-src 'self'; script-src 'sha256-xxx...';</code></code></pre>



<p class="wp-block-paragraph">但是，最讓人傻眼的是，連單純想幫網頁化妝的行內樣式（inline-style）也被一起關進大牢了：</p>



<pre class="wp-block-code"><code><code>&lt;style&gt;h1 { color: yellow; }&lt;/style&gt;</code></code></pre>



<p class="wp-block-paragraph">CSS 到底做錯了什麼？它只是個孩子啊！</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">警匪片現場：當 CSS 變成滲透工具</h2>



<p class="wp-block-paragraph">資安世界有三大神聖支柱：機密性、完整性、可用性。而隨便亂加的 CSS，其實正在默默破壞這一切。</p>



<h3 class="wp-block-heading">疑犯一號：DOM 元素私生子（破壞完整性）</h3>



<p class="wp-block-paragraph">你可能會想：「這網頁是我寫的，裡面的 CSS 當然也是我寫的啊！」</p>



<p class="wp-block-paragraph">事情可沒那麼簡單。在 JavaScript 的世界裡，壞人可以用各種神奇手法動態產生元素：</p>



<p class="wp-block-paragraph">JavaScript</p>



<pre class="wp-block-code"><code>let style = document.createElement('style');
style.innerText = 'h1 { color: blue; }';
document.body.appendChild(style);
</code></pre>



<p class="wp-block-paragraph">這段程式碼一旦被惡意注入，它就能神不知鬼不覺地改掉你的網頁外觀。這就是為什麼瀏覽器乾脆一不做二不休，預設把所有沒登記過的行內樣式全部封鎖。</p>



<h3 class="wp-block-heading">疑犯二號：假藉美化名義的間諜（破壞機密性）</h3>



<p class="wp-block-paragraph">CSS 裡面有兩個看起來很無辜、但實際上超常被當作間諜的語法： <code>@import</code> 和 <code>url()</code> 。</p>



<p class="wp-block-paragraph">當你用了背景圖片：</p>



<pre class="wp-block-code"><code><code>background-image: url(https://example.com/spy.jpg);</code></code></pre>



<p class="wp-block-paragraph">瀏覽器看到這行，就會自動發出一個請求去下載圖片。這時候，壞人就可以利用這個機制搞鬼：</p>



<ul class="wp-block-list">
<li><strong>偷看你的行蹤（Beacon 技術）：</strong> 只要把圖片網址加上個人專屬的編碼，當你一打開網頁，壞人的伺服器收到圖片請求，就知道「喔！某某某在幾點幾分看了這個頁面！」</li>



<li><strong>Cookie 順風車：</strong> 如果網站沒設定好，這個請求甚至會順便把你的 Cookie 跨站送出去，直接把你的登入狀態雙手奉上。</li>
</ul>



<p class="wp-block-paragraph">所以，想要在有 CSP 的防護下安全地秀出圖片，你還必須跟總管報備圖片的白色名單：</p>



<pre class="wp-block-code"><code><code>Content-Security-Policy: default-src 'self'; style-src 'sha256-...'; img-src http://信任的圖片來源;</code></code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">結論</h2>



<p class="wp-block-paragraph">在這個壞人招數層出不窮的時代，網頁開發者真的不能只活在「CSS 只是用來排版」的粉紅泡泡裡。多了解一點 CSP 的龜毛規則，雖然設定時會寫到抓狂，但至少能保住大家的飯碗，不讓網站變成駭客的免費遊樂園！</p>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2026/06/css-injection-csp-url/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to Use the :has() Selector in CSS</title>
		<link>https://stackoverflow.max-everyday.com/2024/12/how-to-use-the-has-selector-in-css/</link>
					<comments>https://stackoverflow.max-everyday.com/2024/12/how-to-use-the-has-selector-in-css/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Thu, 05 Dec 2024 01:41:05 +0000</pubDate>
				<category><![CDATA[css筆記]]></category>
		<category><![CDATA[css]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=6035</guid>

					<description><![CDATA[之前使用過 :not() 覺得超級的實用，例如：...]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full"><img decoding="async" width="1024" height="1024" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2024/12/89ac7fc5-1ae6-4a94-b35c-144dd7704fdb.jpeg" alt="" class="wp-image-6037" srcset="https://stackoverflow.max-everyday.com/wp-content/uploads/2024/12/89ac7fc5-1ae6-4a94-b35c-144dd7704fdb.jpeg?v=1733363050 1024w, https://stackoverflow.max-everyday.com/wp-content/uploads/2024/12/89ac7fc5-1ae6-4a94-b35c-144dd7704fdb-600x600.jpeg?v=1733363050 600w, https://stackoverflow.max-everyday.com/wp-content/uploads/2024/12/89ac7fc5-1ae6-4a94-b35c-144dd7704fdb-300x300.jpeg?v=1733363050 300w, https://stackoverflow.max-everyday.com/wp-content/uploads/2024/12/89ac7fc5-1ae6-4a94-b35c-144dd7704fdb-768x768.jpeg?v=1733363050 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">之前使用過 :not() 覺得超級的實用，例如：選取所有checkbox 狀態是沒被打勾的。今天要來學習使用 :has().</p>



<h2 class="wp-block-heading">相關文章</h2>



<ul class="wp-block-list">
<li>:has()<br><a href="https://developer.mozilla.org/zh-CN/docs/Web/CSS/:has">https://developer.mozilla.org/zh-CN/docs/Web/CSS/:has</a></li>



<li>CSS :has() Pseudo-class<br><a href="https://www.w3schools.com/cssref/sel_has.php">https://www.w3schools.com/cssref/sel_has.php</a></li>



<li>:has() 個案研究<br><a href="https://developer.chrome.com/blog/css-ui-ecommerce-has?hl=zh-tw">https://developer.chrome.com/blog/css-ui-ecommerce-has?hl=zh-tw</a></li>



<li>How to Use the :has() Selector in CSS<br><a href="https://www.freecodecamp.org/news/how-to-use-the-has-selector-in-css/">https://www.freecodecamp.org/news/how-to-use-the-has-selector-in-css/</a></li>
</ul>



<p class="wp-block-paragraph">影片：Learn CSS :not() and :has() selector in 6 Minutes<br><a href="https://www.youtube.com/watch?v=-pQZLQakz-c">https://www.youtube.com/watch?v=-pQZLQakz-c</a></p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="Learn CSS :not() and :has() selector in 6 Minutes" width="640" height="360" src="https://www.youtube.com/embed/-pQZLQakz-c?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<p class="wp-block-paragraph">滿神奇的，居然完全沒使用 javascript 就到過 filter 功能。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2024/12/how-to-use-the-has-selector-in-css/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>左側分類欄位組合右側收合</title>
		<link>https://stackoverflow.max-everyday.com/2024/05/sidebar-with-collapse/</link>
					<comments>https://stackoverflow.max-everyday.com/2024/05/sidebar-with-collapse/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Tue, 07 May 2024 07:33:30 +0000</pubDate>
				<category><![CDATA[css筆記]]></category>
		<category><![CDATA[javascript筆記]]></category>
		<category><![CDATA[Bootstrap]]></category>
		<category><![CDATA[javascript]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=5717</guid>

					<description><![CDATA[在使用 clipchamp 時看到這一個功能，覺...]]></description>
										<content:encoded><![CDATA[<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="428" height="491" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2024/05/Screenshot-2024-05-07-at-3.14.17 PM.png?v=1715066261" alt="" class="wp-image-5718"/></figure>
</div>


<p class="wp-block-paragraph">在使用 clipchamp 時看到這一個功能，覺得很有趣。</p>



<p class="wp-block-paragraph">比較簡單的解法，是使用 sidebar + collapse  就可以做到，範例程式：<br><a href="https://getbootstrap.com/docs/5.3/examples/sidebars/">https://getbootstrap.com/docs/5.3/examples/sidebars/</a></p>



<p class="wp-block-paragraph">clipchame 的這個做法的優點是讓分類可以保持在左側sidebar 裡。</p>



<p class="wp-block-paragraph">實作的方式是，sidebar 使用 tab 來實作，收合使用。 collapse, 參考看看 bootstrap 範例：<br><a href="https://getbootstrap.com/docs/5.3/components/collapse/">https://getbootstrap.com/docs/5.3/components/collapse/</a></p>



<p class="wp-block-paragraph">一般 collapse 是上下收合，這個是左右收。</p>



<p class="wp-block-paragraph">一般 tab 是上下的版面，這個是左右版面。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph">實際上用的到html程式碼：</p>



<pre class="wp-block-code"><code>  &lt;div class="ifilter_chart"&gt;
      &lt;div class="ifitler_chart_left_side_bar"&gt;
          &lt;nav aria-label="左側導覽" class="ifilter_chart_left_nav normal" tabindex="0"&gt;
              &lt;div class="ifilter_chart_left_nav_grid"&gt;
                  &lt;div class="ifilter_chart_left_nav_item"&gt;
                      &lt;div role="tablist"&gt;
                          &lt;button aria-label="Filter" aria-selected="true" class="ifilter_chart_left_nav_btn active" data-bs-toggle="tab" href="#ifilter_tab_bar_filter" data-sidebar-tab="true" role="tab" tabindex="0"&gt;
                              &lt;i class="fs-3 bi bi-filter"&gt;&lt;/i&gt;
                              &lt;div class="ifilter_chart_left_nav_item_text"&gt;
                                  Filter
                              &lt;/div&gt;
                          &lt;/button&gt;
                          
                        &lt;button aria-label="Config" aria-selected="false" class="ifilter_chart_left_nav_btn" data-bs-toggle="tab" href="#ifilter_tab_bar_config" data-sidebar-tab="true" role="tab" tabindex="-1"&gt;
                            &lt;i class="fs-3 bi bi-grid-fill"&gt;&lt;/i&gt;
                            &lt;div class="ifilter_chart_left_nav_item_text"&gt;
                                Config
                            &lt;/div&gt;
                        &lt;/button&gt;                          
                      &lt;/div&gt;
                  &lt;/div&gt;
              &lt;/div&gt;
          &lt;/nav&gt;
          &lt;div style="position: relative;"&gt;
              &lt;div aria-label="左側內容" class="ifilter_chart_left_sidebar" style="height: 100%"&gt;
                  &lt;div class="ifilter_chart_left_sidebar_grid collapse show" id="collapse_bar_sidebar"&gt;
                      &lt;div class="tab-content ifilter_chart_left_sidebar_grid_container" style="position: relative; box-sizing: border-box; will-change: width; width: 280px; height: 100%; max-width: 50vw; min-width: 280px;"&gt;
                          &lt;div class="tab-pane fade active show" id="ifilter_tab_bar_filter" role="tabpanel"&gt;
&lt;!-- your filter block here --&gt;
                          &lt;/div&gt;
                          &lt;div class="tab-pane fade" id="ifilter_tab_bar_config"&gt;
&lt;!-- your config block here --&gt;
                          &lt;/div&gt;
                      &lt;/div&gt;
                  &lt;/div&gt;
              	  
              	  &lt;button aria-label="收合按鈕"
              	  	data-bs-toggle="collapse" data-bs-target="#collapse_bar_sidebar" aria-expanded="true" aria-controls="collapse_sidebar" 
              	  	class="btn btn-primary ifilter_chart_collapse_button ifilter_chart_collapse_icon ifilter_sidebar_button collapsed"&gt;
				    &lt;svg class="ifilter_chart_collapse_icon_svg" height="12" viewbox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"&gt;
				        &lt;path d="M2.22 4.47c.3-.3.77-.3 1.06 0L6 7.19l2.72-2.72a.75.75 0 0 1 1.06 1.06L6.53 8.78c-.3.3-.77.3-1.06 0L2.22 5.53a.75.75 0 0 1 0-1.06Z" fill="currentColor"&gt;
				        &lt;/path&gt;
				    &lt;/svg&gt;
				&lt;/button&gt;
              &lt;/div&gt;
          &lt;/div&gt;
      &lt;/div&gt;
      &lt;div class="ifilter_chart_canvas"&gt;
&lt;!-- your main canvas here --&gt;
      &lt;/div&gt;
  &lt;/div&gt;
</code></pre>



<p class="wp-block-paragraph">css:</p>



<pre class="wp-block-code"><code>div.ifilter_chart {
    display: flex;
    height: 100%;	
}

.ifitler_chart_left_side_bar{
    display: flex;
    /*
    // why remark this become height: 100% 
    height: 100%; */
    position: relative;
    z-index: 5;	
}

.ifilter_chart_left_nav {
    background-color: rgb(255, 255, 255);
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 64px;
    border-inline-end: 1px solid rgb(230, 230, 230);
}

.ifilter_chart_left_nav_grid {
    flex-grow: 1;
    align-self: stretch;
    position: relative;
    overflow: hidden;
}

.ifilter_chart_left_nav_item {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding-top: 0px;
    /* overflow-y: scroll; */
}

.ifilter_chart_left_nav_btn.active {
    opacity: 1;
    color: var(--primary) !important;
    background: var(--rgba-primary-1);
    font-weight: 600;
    box-shadow: none;    
}
.ifilter_chart_left_nav_btn {
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    background: none;
    border: none;
    color: #737B8B;
    line-height: 1.1;
    padding: 4px;
    width: 64px;
    height: 64px;
    font-weight: 400;
    cursor: pointer;
    /* transition: color 100ms ease-in-out 0s, background 100ms ease-in-out 0s; */
}

.ifilter_chart_left_nav_item_text {
    width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
}
    
.ifilter_chart_left_sidebar {
	position: relative;
    height: 100%;
}

.ifilter_chart_left_sidebar_grid {
    background-color: rgb(255, 255, 255);
    display: flex;
    flex-direction: column;
}

.ifilter_chart_left_sidebar_media {
    background-color: rgb(255, 255, 255);
    overflow: hidden overlay;
    flex-grow: 1;
}

.ifilter_chart_left_sidebar_section {
    position: relative;
    width: 100%;
    min-height: 100%;
    display: flex;
    flex-direction: column;
}

.ifilter_chart_left_sidebar_grid_container {
    padding: 16px;
    display: flex;
    flex-direction: column;
}

.ifilter_chart_collapse_icon {
    position: absolute;
    top: calc(50% - 38px);
    height: 76px;
    width: 16px;
    color: rgb(39, 40, 54);
    transition: color 150ms ease-out 0s;
}
.ifilter_sidebar_button {
    position: absolute;
    top: calc(50% - 38px);
    transition: color 150ms ease-out 0s;	
}

.ifilter_chart_collapse_icon {
    left: 100%;
}
.ifilter_chart_collapse_icon_svg:not(.collapsed) {
    transform: rotate(90deg);
}
.ifilter_chart_collapse_icon_svg.collapsed {
    transform: rotate(270deg);
}

.ifilter_chart_collapse_icon_svg {
    position: absolute;
    top: 50%;
    left: 50%;
    margin-left: -6px;
    margin-top: -6px;
}

.ifilter_chart_collapse_button {
    text-align: inherit;
    padding: 0px;
    border: none;
    font: inherit;
    color: inherit;
    cursor: pointer;
    display: flex;
    -webkit-box-pack: center;
    justify-content: center;
    -webkit-box-align: center;
    align-items: center;
}

.ifilter_chart_canvas {
	width: 100%;
	text-align: -webkit-center;
	padding-top: 3rem;
    margin-left: 20px;
}</code></pre>



<p class="wp-block-paragraph">javascript:</p>



<pre class="wp-block-code"><code>var collapseElementList = &#91;].slice.call(document.querySelectorAll('.ifilter_chart_left_nav_btn'));
collapseElementList.map(function (collapseEl) {
	collapseEl.addEventListener("click", function(event){
        let targetElement = event.target || event.srcElement;
        //console.log(targetElement);
        if(targetElement.tagName=="I" || targetElement.tagName=="DIV") {
        	targetElement = targetElement.parentNode;
            //console.log(targetElement);
        }
    	
        let btn_href = targetElement.getAttribute("href");
    	let btn_selector = "";
    	let collapse_id = "";
    	if(btn_href=="#ifilter_tab_bar_config" || btn_href=="#ifilter_tab_bar_filter") {
    		collapse_id = "collapse_bar_sidebar";
    		btn_selector = 'button&#91;data-bs-target="#'+ collapse_id +'"]';
    	}
    	const sidebar_btn = document.querySelector(btn_selector);
    	if(sidebar_btn) {
    		//console.log(sidebar_btn.getAttribute("class"));
    		if(sidebar_btn.getAttribute("class").indexOf("collapsed") > -1) {
    			const bsCollapse = new bootstrap.Collapse(document.querySelector('#'+collapse_id));
    			bsCollapse.toggle();
    		}
    	}
    });
});


var collapseElementList = &#91;].slice.call(document.querySelectorAll('.ifilter_chart_left_sidebar_grid'));
collapseElementList.map(function (collapseEl) {
	// hide.bs.collapse
	const element_selector = "button&#91;data-bs-target=\"#"+ collapseEl.getAttribute("id") +"\"] svg.ifilter_chart_collapse_icon_svg";
	collapseEl.addEventListener("hidden.bs.collapse", function(event){
		$(element_selector).addClass("collapsed");
	});

	// show.bs.collapse
	collapseEl.addEventListener("shown.bs.collapse", function(event){
		$(element_selector).removeClass("collapsed");
	});
});
</code></pre>



<p class="wp-block-paragraph">說明：你的使用情況可能比我簡單很多，我因為有多個圖表要共用 css, 所以程式碼會複雜一點點。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2024/05/sidebar-with-collapse/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>讓三欄式網格式的圖片自動縮小</title>
		<link>https://stackoverflow.max-everyday.com/2024/02/row-cols-md-3/</link>
					<comments>https://stackoverflow.max-everyday.com/2024/02/row-cols-md-3/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Mon, 05 Feb 2024 02:24:52 +0000</pubDate>
				<category><![CDATA[css筆記]]></category>
		<category><![CDATA[Bootstrap]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=5418</guid>

					<description><![CDATA[在套用bootstrap 時, 不小心把 img...]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">在套用bootstrap 時, 不小心把 img tag 放到 card 裡, 大多數的情況下, image 是以原圖方式顯示, 縮小的話, 需要自定寬度, 如果設定絕對的寬度, 就需要自義左右造成的空白間隙.</p>



<p class="wp-block-paragraph">比較方便的做法, 是直接填滿某一個網格, 然後再格子裡設定間距, 做出來的執行效果:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="999" height="867" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2024/02/chrome_2024-02-05_10-11_9t.png?v=1707099492" alt="" class="wp-image-5419" srcset="https://stackoverflow.max-everyday.com/wp-content/uploads/2024/02/chrome_2024-02-05_10-11_9t.png?v=1707099492 999w, https://stackoverflow.max-everyday.com/wp-content/uploads/2024/02/chrome_2024-02-05_10-11_9t-600x521.png?v=1707099492 600w, https://stackoverflow.max-everyday.com/wp-content/uploads/2024/02/chrome_2024-02-05_10-11_9t-768x667.png?v=1707099492 768w" sizes="auto, (max-width: 999px) 100vw, 999px" /></figure>
</div>


<p class="wp-block-paragraph">中間神奇的關鍵是 row-cols-md-3, 滿神奇的, 加了這個class , 圖片就自動縮到格子裡, 後面加 g-3 是要讓邊邊不要直接摸到圖片的線條。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2024/02/row-cols-md-3/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>bootstrape validation 使用心得</title>
		<link>https://stackoverflow.max-everyday.com/2023/09/bootstrape-validation/</link>
					<comments>https://stackoverflow.max-everyday.com/2023/09/bootstrape-validation/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Tue, 26 Sep 2023 09:23:59 +0000</pubDate>
				<category><![CDATA[css筆記]]></category>
		<category><![CDATA[javascript筆記]]></category>
		<category><![CDATA[Bootstrap]]></category>
		<category><![CDATA[javascript]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=5064</guid>

					<description><![CDATA[為什麼要使用 validation, 因為這個使...]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="831" height="652" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2023/09/2023-09-26-16_54_15-Window.jpg" alt="" class="wp-image-5066" srcset="https://stackoverflow.max-everyday.com/wp-content/uploads/2023/09/2023-09-26-16_54_15-Window.jpg?v=1695719684 831w, https://stackoverflow.max-everyday.com/wp-content/uploads/2023/09/2023-09-26-16_54_15-Window-600x471.jpg?v=1695719684 600w, https://stackoverflow.max-everyday.com/wp-content/uploads/2023/09/2023-09-26-16_54_15-Window-768x603.jpg?v=1695719684 768w" sizes="auto, (max-width: 831px) 100vw, 831px" /></figure>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">為什麼要使用 validation, 因為這個使用上很直覺, 可以直接跟user講那一個欄位分別是合法,還有各自的錯誤訊息, 也不會因讓畫面有奇怪的彈跳, 使用的效果相較於彈出式的alert/dialog/modal 而言, 比較推薦使用.</p>



<p class="wp-block-paragraph">在 input tag, 並不是使用 <code>onchange </code>來觸發每一個輸入的字元, <code>onchange </code>是在離開input 輸入框時, 才會觸發, 每打一個字, 使用的是事件是 <code>oninput</code>.</p>



<p class="wp-block-paragraph">在 input 的 parent 加入 <code>.was-validated</code> 就可以觸發讓輸入框有打勾與&#8221;必填&#8221;的視覺上的效果. 如果是要類似的 ajax 的使用方法, 必需在&#8221;完成檢查&#8221; 並且沒有錯誤, 才 addClass, 反之要 removeClasss, 就可以有上面的效果.</p>



<p class="wp-block-paragraph">但是, 如果是要在輸入框有值, 且要顯示為錯誤, 請手動讓正確的 form-control 加入 class <code>.is-valid</code> 有錯的 form-control 加入  <code>.is-invalid</code> .</p>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">官方的說明:<br><a href="https://getbootstrap.com/docs/5.3/forms/validation/">https://getbootstrap.com/docs/5.3/forms/validation/</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2023/09/bootstrape-validation/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>tabulator 的寬度無法overflow:hidden</title>
		<link>https://stackoverflow.max-everyday.com/2023/08/tabulator-width-overflow-hidden/</link>
					<comments>https://stackoverflow.max-everyday.com/2023/08/tabulator-width-overflow-hidden/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Fri, 04 Aug 2023 10:33:26 +0000</pubDate>
				<category><![CDATA[css筆記]]></category>
		<category><![CDATA[css]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=4968</guid>

					<description><![CDATA[正常情況下, overflow 的部分被隱藏, ...]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">正常情況下, overflow 的部分被隱藏, 並在內部元件產生橫向的scroll bar.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="535" height="578" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2023/08/2023-08-04-18_24_54-Window.jpg" alt="" class="wp-image-4970"/></figure>



<p class="wp-block-paragraph">異常情況, 是無法產生 scrollbar, 畫面變超大, </p>



<p class="wp-block-paragraph">努力地研究 tabulator 官方文件, 也看不出所以然:<br><a href="https://tabulator.info/docs/5.5/layout#fittowidth">https://tabulator.info/docs/5.5/layout#fittowidth</a></p>



<p class="wp-block-paragraph">手動調整 tabulator 的 table width:100% 也無解.</p>



<p class="wp-block-paragraph"><strong>產成的原因:</strong></p>



<p class="wp-block-paragraph">某一個爸爸 div 讓 tabulator 繼承到 display: grid;  而且上層又是用 flex, 交叉使用就掛掉.</p>



<p class="wp-block-paragraph">解法1: 避開 grid 就OK了. </p>



<p class="wp-block-paragraph">解法2: 在 tabulator 的上層設成 display: grid 居然也行, 真太神奇了, 呵呵. </p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2023/08/tabulator-width-overflow-hidden/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Left align and right align within div in Bootstrap</title>
		<link>https://stackoverflow.max-everyday.com/2023/07/left-align-and-right-align-within-div-in-bootstrap-2/</link>
					<comments>https://stackoverflow.max-everyday.com/2023/07/left-align-and-right-align-within-div-in-bootstrap-2/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Tue, 18 Jul 2023 10:04:52 +0000</pubDate>
				<category><![CDATA[css筆記]]></category>
		<category><![CDATA[Bootstrap]]></category>
		<category><![CDATA[css]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=4951</guid>

					<description><![CDATA[想把下面的按鈕們搬到右邊, 但都失敗, 成功後的...]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">想把下面的按鈕們搬到右邊, 但都失敗, 成功後的執行畫面:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="489" height="100" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2023/07/2023-07-18-17_59_38-Window.jpg" alt="" class="wp-image-4952"/></figure>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">解法:<br><a href="https://getbootstrap.com/docs/5.0/utilities/flex/">https://getbootstrap.com/docs/5.0/utilities/flex/</a></p>



<pre class="wp-block-code"><code>&lt;div class="d-flex justify-content-end"&gt;
  &lt;div class="mr-auto p-2"&gt;Flex item&lt;/div&gt;
  &lt;div class="p-2"&gt;Flex item&lt;/div&gt;
  &lt;div class="p-2"&gt;Flex item&lt;/div&gt;
&lt;/div&gt;</code></pre>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">直接下 <code>justify-content-end</code> , 沒有效果, </p>



<p class="wp-block-paragraph">使用 text-right 也失敗:<br><a href="https://getbootstrap.com/docs/4.0/utilities/text/">https://getbootstrap.com/docs/4.0/utilities/text/</a></p>



<pre class="wp-block-code"><code>&lt;p class="text-right">Right aligned text on all viewport sizes.&lt;/p></code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2023/07/left-align-and-right-align-within-div-in-bootstrap-2/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>css selector tester online: jsoup</title>
		<link>https://stackoverflow.max-everyday.com/2023/07/css-selector-tester-online-jsoup/</link>
					<comments>https://stackoverflow.max-everyday.com/2023/07/css-selector-tester-online-jsoup/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Fri, 14 Jul 2023 18:10:17 +0000</pubDate>
				<category><![CDATA[css筆記]]></category>
		<category><![CDATA[css]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=4945</guid>

					<description><![CDATA[今天要分享一個跟css selector 有關的...]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">今天要分享一個跟css selector 有關的網站:<br><a href="https://try.jsoup.org/">https://try.jsoup.org/</a></p>



<p class="wp-block-paragraph">我實際執行畫面：</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="722" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2023/07/Screen-Shot-2023-07-15-at-2.07.07-AM-1024x722.png?v=1689358063" alt="" class="wp-image-4946" srcset="https://stackoverflow.max-everyday.com/wp-content/uploads/2023/07/Screen-Shot-2023-07-15-at-2.07.07-AM-1024x722.png?v=1689358063 1024w, https://stackoverflow.max-everyday.com/wp-content/uploads/2023/07/Screen-Shot-2023-07-15-at-2.07.07-AM-600x423.png?v=1689358063 600w, https://stackoverflow.max-everyday.com/wp-content/uploads/2023/07/Screen-Shot-2023-07-15-at-2.07.07-AM-768x541.png?v=1689358063 768w, https://stackoverflow.max-everyday.com/wp-content/uploads/2023/07/Screen-Shot-2023-07-15-at-2.07.07-AM.png?v=1689358063 1375w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">原本的 css selector 是寫 tr.status_tr 但是，會連 Soldout 也一起被選到，改用 tr[class=&#8217;status_tr&#8217;] 就解決了，沒有使用到  :NOT().</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph">在網路上學習 css selector 的語法，想套用看看，例如我想試的是NOT 的用法：<br><a href="https://www.geeksforgeeks.org/how-to-use-a-not-equal-css-attribute-selector/">https://www.geeksforgeeks.org/how-to-use-a-not-equal-css-attribute-selector/</a></p>



<p class="wp-block-paragraph">相關討論：Can&#8217;t find a &#8220;not equal&#8221; css attribute selector<br><a href="https://stackoverflow.com/questions/25287229/cant-find-a-not-equal-css-attribute-selector">https://stackoverflow.com/questions/25287229/cant-find-a-not-equal-css-attribute-selector</a></p>



<p class="wp-block-paragraph">One problem with the accepted answer is that it will also select elements that do not have a&nbsp;<code>foo</code>&nbsp;attribute at all. Consider:</p>



<pre class="wp-block-code"><code>&lt;div&gt;No foo&lt;/div&gt;
&lt;div foo=""&gt;Empty foo&lt;/div&gt;
&lt;div foo="x"&gt;XXX&lt;/div&gt;
&lt;div foo="y"&gt;YYY&lt;/div&gt;
&lt;div foo="z"&gt;ZZZ&lt;/div&gt;
</code></pre>



<p class="wp-block-paragraph"><code>div:not([foo=''])</code>&nbsp;will select both the first and second&nbsp;<code>div</code>&nbsp;elements. If you only want&nbsp;<code>div</code>&nbsp;elements that have an attribute foo that is set to an empty string, you should use:</p>



<pre class="wp-block-code"><code>div&#91;foo]:not(&#91;foo=''])
</code></pre>



<p class="wp-block-paragraph">If you want all elements with attribute&nbsp;<code>foo</code>&nbsp;that is neither&nbsp;<code>y</code>&nbsp;nor&nbsp;<code>z</code>, you should use:</p>



<pre class="wp-block-code"><code>div&#91;foo]:not(&#91;foo='y']):not(&#91;foo='z'])
</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2023/07/css-selector-tester-online-jsoup/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Bootstrap Tabs Example</title>
		<link>https://stackoverflow.max-everyday.com/2023/04/bootstrap-tab-wizard-example/</link>
					<comments>https://stackoverflow.max-everyday.com/2023/04/bootstrap-tab-wizard-example/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Tue, 18 Apr 2023 07:41:44 +0000</pubDate>
				<category><![CDATA[css筆記]]></category>
		<category><![CDATA[javascript筆記]]></category>
		<category><![CDATA[Bootstrap]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[javascript]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=4741</guid>

					<description><![CDATA[最近有一個需求, 想做成 wizard 風格的操...]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">最近有一個需求, 想做成 wizard  風格的操作界面, 首先是在 google 下 keyword:</p>



<pre class="wp-block-code"><code>bootstrap tabs template</code></pre>



<p class="wp-block-paragraph">使用下面的範例來修改:<br><a href="https://colorlib.com/etc/bwiz/colorlib-wizard-30/index.html">https://colorlib.com/etc/bwiz/colorlib-wizard-30/index.html</a></p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="977" height="656" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2023/04/2023-04-18-15_23_13-Window.jpg" alt="" class="wp-image-4742" srcset="https://stackoverflow.max-everyday.com/wp-content/uploads/2023/04/2023-04-18-15_23_13-Window.jpg?v=1681802647 977w, https://stackoverflow.max-everyday.com/wp-content/uploads/2023/04/2023-04-18-15_23_13-Window-600x403.jpg?v=1681802647 600w, https://stackoverflow.max-everyday.com/wp-content/uploads/2023/04/2023-04-18-15_23_13-Window-768x516.jpg?v=1681802647 768w" sizes="auto, (max-width: 977px) 100vw, 977px" /></figure>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">實做的結果:</p>



<p class="wp-block-paragraph">Step 1:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="505" height="384" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2023/04/2023-04-18-15_16_55-Window.jpg" alt="" class="wp-image-4743"/></figure>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Step 2:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="506" height="451" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2023/04/2023-04-18-15_17_44-Window.jpg" alt="" class="wp-image-4744"/></figure>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Step 3:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="503" height="438" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2023/04/2023-04-18-15_17_56-Window.jpg" alt="" class="wp-image-4745"/></figure>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">使用的 html:</p>



<pre class="wp-block-code"><code>&lt;div id="form-total" role="application" class="form-register wizard clearfix"&gt;
	&lt;div class="steps clearfix"&gt;
		&lt;ul role="tablist"&gt;
			&lt;li role="tab" aria-disabled="false" class="first current" aria-selected="true" id="your_table_nav_1"&gt;
				&lt;div&gt;
				&lt;span class="title"&gt;1&lt;/span&gt;&lt;/div&gt;
			&lt;/li&gt;
			&lt;li role="tab" aria-disabled="false" class="" aria-selected="true" id="your_table_nav_2"&gt;
				&lt;div&gt;
				&lt;span class="title"&gt;2&lt;/span&gt;&lt;/div&gt;
			&lt;/li&gt;
			&lt;li role="tab" aria-disabled="false" class="last" id="your_table_nav_3"&gt;
				&lt;div&gt;
				&lt;span class="title"&gt;3&lt;/span&gt;&lt;/div&gt;
			&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/div&gt;

	&lt;div id="your_table_tab_1" class=""&gt;
                &lt;div class="col-12"&gt;
                  &lt;label for="your_table-field1-id" class="form-label"&gt;Field1&lt;/label&gt;
                    &lt;select class="form-select" aria-label="Default select" id="your_table-field1-id"&gt;
                    &lt;/select&gt;
                &lt;/div&gt;
	&lt;/div&gt;
	&lt;div id="your_table_tab_2" class="disappear"&gt;
                &lt;div class="col-12"&gt;
                  &lt;label for="your_table-field2-id" class="form-label"&gt;Field2&lt;/label&gt;
                    &lt;select class="form-select" aria-label="Default select" id="your_table-field2-id"&gt;
                    &lt;/select&gt;
                &lt;/div&gt;
                &lt;div class="col-12"&gt;
                  &lt;label for="your_table-field3-id" class="form-label"&gt;Field3&lt;/label&gt;
                    &lt;select class="form-select" aria-label="Default select" id="your_table-field3-id"&gt;
                    &lt;/select&gt;
                &lt;/div&gt;
	&lt;/div&gt;
	&lt;div id="your_table_tab_3" class="disappear"&gt;
                &lt;div class="row"&gt;
	                &lt;div class="col-3"&gt;
	                  &lt;label class="form-label"&gt;User&lt;/label&gt;
	                &lt;/div&gt;
	                &lt;div class="col"&gt;
	                  &lt;div id="your_table-user_name-confirm"&gt;&lt;/div&gt;
	                &lt;/div&gt;
                &lt;/div&gt;

                &lt;div class="row"&gt;
	                &lt;div class="col-3"&gt;
	                  &lt;label class="form-label"&gt;Field1&lt;/label&gt;
	                &lt;/div&gt;
	                &lt;div class="col"&gt;
	                  &lt;div id="your_table-field1-confirm"&gt;&lt;/div&gt;
	                &lt;/div&gt;
                &lt;/div&gt;

                &lt;div class="row"&gt;
	                &lt;div class="col-3"&gt;
	                  &lt;label class="form-label"&gt;Field2&lt;/label&gt;
	                &lt;/div&gt;
	                &lt;div class="col"&gt;
	                  &lt;div id="your_table-field2-confirm"&gt;&lt;/div&gt;
	                &lt;/div&gt;
                &lt;/div&gt;

                &lt;div class="row"&gt;
	                &lt;div class="col-3"&gt;
	                  &lt;label class="form-label"&gt;Field3&lt;/label&gt;
	                &lt;/div&gt;
	                &lt;div class="col"&gt;
	                  &lt;div id="your_table-field3-confirm"&gt;&lt;/div&gt;
	                &lt;/div&gt;
                &lt;/div&gt;
	&lt;/div&gt;

&lt;/div&gt;</code></pre>



<p class="wp-block-paragraph">下方的按鈕們:</p>



<pre class="wp-block-code"><code>&lt;button type="button" class="btn btn-secondary disappear" id='your_table-btn-previous_1' onclick="javascript:your_table_previous_1();"&gt;
	&lt;span&gt;Previous&lt;/span&gt;
&lt;/button&gt;

&lt;button type="button" class="btn btn-primary" id='your_table-btn-next_1' onclick="javascript:your_table_next_1();"&gt;
	&lt;span&gt;Next&lt;/span&gt;
&lt;/button&gt;

&lt;button type="button" class="btn btn-secondary disappear" id='your_table-btn-previous_2' onclick="javascript:your_table_previous_2();"&gt;
	&lt;span&gt;Previous&lt;/span&gt;
&lt;/button&gt;

&lt;button type="button" class="btn btn-primary" id='your_table-btn-next_2' onclick="javascript:your_table_next_2();"&gt;
	&lt;span&gt;Next&lt;/span&gt;
&lt;/button&gt;
</code></pre>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">使用的 css:</p>



<pre class="wp-block-preformatted"> .form-register .steps {
    margin-bottom: 33px;
    margin-top: 40px
}

.form-register .steps ul {
    display: flex;
    display: -webkit-flex;
    list-style: none;
    padding-left: 0;
    justify-content: center;
    -o-justify-content: center;
    -ms-justify-content: center;
    -moz-justify-content: center;
    -webkit-justify-content: center
}

.form-register .steps li,.form-register .steps li.current {
    outline: none;
    -o-outline: none;
    -ms-outline: none;
    -moz-outline: none;
    -webkit-outline: none
}

.form-register .steps li div {
    display: inline-block;
    width: 60px;
    height: 60px;
    border-radius: 50%;
    -o-border-radius: 50%;
    -ms-border-radius: 50%;
    -moz-border-radius: 50%;
    -webkit-border-radius: 50%;
    background: #ccc;
    margin-right: 143px;
    position: relative;
    outline: none
}

.form-register .steps li div::before {
    position: absolute;
    content: "";
    background: #e5e5e5;
    width: 143px;
    height: 2px;
    top: 50%;
    transform: translateY(-50%);
    -o-transform: translateY(-50%);
    -ms-transform: translateY(-50%);
    -moz-transform: translateY(-50%);
    -webkit-transform: translateY(-50%);
    left: 100%
}

.form-register .steps li.last div {
    margin-right: 0
}

.form-register .steps li.last div::before {
    content: none
}

.form-register .steps li.current div
,.form-register .steps li.current div:active
,.form-register .steps li.done div::before
,.form-register .steps li.done div
,.form-register .steps li.done div:active {
    background: #3760e5
}

.form-register .steps li .current-info {
    display: none
}

.form-register .steps li .title {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%,-50%);
    -o-transform: translate(-50%,-50%);
    -ms-transform: translate(-50%,-50%);
    -moz-transform: translate(-50%,-50%);
    -webkit-transform: translate(-50%,-50%);
    color: #fff;
    font-size: 24px;
    font-weight: 600;
    font-family: montserrat,sans-serif
}
</pre>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">使用到的 javascript:</p>



<p class="wp-block-paragraph">這段用來控制按鍵和區塊在切換時的顯示.</p>



<pre class="wp-block-code"><code>function switch_tab_step(table_name, active_at, tab_count) {
	for(let i=1; i&lt;=tab_count; i++){
		$("#"+ table_name +"_nav_"+i).removeClass("current");
		$("#"+ table_name +"_nav_"+i).removeClass("done");
		
		if(i&lt;active_at) {
			$("#"+ table_name +"_nav_"+i).addClass("done");
		}

		$("#"+ table_name +"_tab_"+i).addClass("disappear");

		$("#"+ table_name +"-btn-previous_"+i).addClass("disappear");
		$("#"+ table_name +"-btn-next_"+i).addClass("disappear");
	}

	$("#"+ table_name +"_nav_"+active_at).addClass("current");

	$("#"+ table_name +"_tab_"+active_at).removeClass("disappear");

	$("#"+ table_name +"-btn-previous_"+(active_at-1)).removeClass("disappear");
	$("#"+ table_name +"-btn-next_"+active_at).removeClass("disappear");
}</code></pre>



<p class="wp-block-paragraph">next 與 previous 的控制:</p>



<pre class="wp-block-code"><code>function your_table_next_1() {
	switch_tab_step('your_table',2,3);
}

function your_table_previous_1() {
	switch_tab_step('your_table',1,3);
}

function your_table_next_2() {
	switch_tab_step('your_table',3,3);
	
	// final step
    // your code here...
}

function your_table_previous_2() {
	switch_tab_step('your_table',2,3);
}</code></pre>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">大致上, 這樣就可以做出 wizard 效果.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2023/04/bootstrap-tab-wizard-example/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
