Blogger Contempo Light Theme: Challenges involved in providing light/dark mode support

Last updated on 29 Oct. 2025

Quick Info


Summary

Blogger does not seem to support light/dark mode. At least, its Contempo family of themes do not support switching between light/dark mode using Chrome browser's light/dark mode setting. 

I use Contempo Light theme for my Blogger blogs. There is a Contempo Light and a Contempo Dark theme but that applies all the time irrespective of browser's light/dark mode setting.

It is possible to provide an imperfect light/dark mode support by customizing the Contempo Light theme. However, to do it properly, it involves lot of effort in identifying which elements and CSS classes in Blogger have to be changed to dark mode styles and then coding in the CSS for that. Even after all that effort, some elements could be missed out and so the code may break.

With assistance from ChatGPT, we came up with a simple approach of changing colours using the universal selector * at a top level. This has the risk of tripping up some features of the theme. But the results are interesting and so I created a demo/test blog for it: Contempo Theme Toggle Light/Dark Test/Demo. However I am not using it for my regular Blogger blogs, as of now at least. The customization code has been published in a public GitHub repo whose link is given at the top of this post.

Chrome on mobile and desktop has an experimental feature called "Auto Dark Mode for Web Contents" which is by default disabled. It can be enabled by using chrome://flags/#enable-force-dark in browser address field and then choosing enabled for that experimental feature. 

On my Android mobile (Samsung M21) Chrome #enable-force-dark feature shows site in light/dark mode based on whether my mobile is in light/dark mode. That is good.

On my Windows 11 desktop PC, using Chrome #enable-force-dark feature results in sites being shown in dark mode irrespective of Chrome browser light/dark setting and irrespective of Windows Personalizaton -> Colors -> Light/Dark mode as well as Windows Theme being light/dark theme. That is a problem.

One advantage of customized Contempo Theme with light/dark support is that the developer doing the customization has more fine-grained control of what colors to use in dark mode. Chrome #enable-force-dark feature does provide a list of inversion options which I have not tried out but does not seem to provide specifying what colors should be used. Its enabled state without specifying inversion type, results in some elements having bright white text against a black background like this post's text as I am typing it into Blogger (I tried it out for initial part of this post) with Chrome #enable-force-dark feature enabled on my Windows 11 PC.

Another disadvantage of Chrome #enable-force-dark feature is that changing its value (say from Enabled to Disabled) requires a relaunch of Chrome for those values to be reflected. Whereas Contempo Theme with light/dark support should be able to dynamically change without need for even refresh of page, let alone relaunch of Chrome. The current customization code has that dynamic change feature which is nice.

Currently I use Windows High Contrast mode (easily done through Alt+Shift+PrtScr) as a sort-of dark mode for Blogger posts as well as Blogger dashboard and compose posts UI. But that has the disadvantage of impacting not only all browser tabs but also all program windows (like Windows File Explorer).

I also use a chrome dark mode extension [Dark Mode]. One issue is that it applies to all sites by default. It seems to have configuration to include or exclude sites but I have not checked that out.

The Blogger theme customization approach explored in this post has the advantage of upgrading the blog to have dark mode feature somewhat like that provided on some websites. That makes the blog more user/visitor friendly. Note that for this approach, the user/visitor does not have to install an extension or force dark mode on all Chrome (browser) tabs/windows or force high contrast mode on all open Windows programs. I have not tested for other browsers like Edge but there is a good probability that the customization will work on them too. The customization could also be extended to supporting three modes of device, light and dark instead of only providing a toggle of whether to follow system (device) light and dark mode.

One big disadvantage of this Blogger theme customization approach is that the blog visitors cannot choose to use the customizaton or go without customization. If this customized theme code breaks, the blog may not be usable partially or even fully, till the Blogger fixes it say by reverting to the default Contempo Light theme (thus discarding all the customization code). That is quite a worrying thing about these customizations. For individual operated blogs, especially blogs that are not administered regularly, that seems to me to be a very big risk due to which I am not using the customized theme approach covered in this post, in my regular blogs. For organization or team operated blogs with regular oversight and administration, this may not be a major issue as the maintenance person(s) can quickly revert to the default Blogger theme and thereby make the blog accessible (but without dark mode feature).

================================
================================

Details

Given below are notes from chats with ChatGPT (CG) on this topic and also fair amount of reading up and experimentation with code that I had to do.

CG provided an initial version of the customize Contempo Light theme approach which involved:
  • Adding CSS (put this in Theme → Customize → Advanced → Page Text → Add CSS or directly in HTML header)
  • Toggle Button (place somewhere visible in your blog, e.g., header gadget, top post area)
  • JavaScript to switch modes (put right before </body> in Theme HTML or via gadget)
I did not want to edit the Theme HTML directly. So I used the Add CSS via Blogger Theme UI, used an HTML/JS gadget for the toggle button and also used an HTML/JS gadget for the JS code.

There were many iterations and I had to do some debugging and fixing on my own (as CG virtually stopped responding after a point).

The summary section provides links to the code I used/developed till the point I stopped the work as I decided not to use it in my Blogger blogs, as of now.

[Simple approach using Chrome light/dark mode setting without having button and JS code:]

Me: The following worked:
@media (prefers-color-scheme: dark) {
  .post-body {
    background-color: black !important;
    color: white !important;
  }

CG: Perfect — that makes sense! ✅

In Contempo Light, the .post-body container has its own background and text color, which is why targeting just body didn’t work. By applying the CSS directly to .post-body with !important, you successfully overrode the theme styles.

  • Now your post content switches to dark mode correctly when the system prefers dark mode.

  • Later, you can extend this to links, blockquotes, headers, sidebar widgets, etc., to make a complete dark mode experience.

...

Me: Within each comment form there is an iframe which has a document with html and body. So whatever we have tried with #comment * does not apply to body elements within iframe.

CG: CSS from your main page cannot affect content inside an iframe, because each iframe runs in its own isolated document (different DOM and often a different origin for security reasons — the “same-origin policy”).

That means:

  • Your dark mode CSS (even with !important) won’t apply to the comment form fields that are loaded via the iframe (like Blogger’s embedded comment form).

  • You can confirm this by inspecting the iframe — you’ll see its own <html> and <body> inside a separate document.

[CG suggested some workarounds which I did not find appealing.]

Me: Hmm. So I guess it is best to ignore dark/light mode for comments (embedded) but that will look odd. A white rectangular patch at bottom of dark mode post.
...

Me: I think I have now understood why we do not have a Contempo theme with light/dark mode download or good article. It is too difficult to get a complete solution. You have to target individual items in the blog HTML and even then due to iframe kind of issues, you cannot fix everything. So whatever solution one may get, it will not be a profesisonal looking solution.

I think I will now drop the idea of having dark/light mode for my Blogger blogs as I don't want to risk an amateurish dark mode blog which may put off some readers.

CG: ... You’ve understood it perfectly — the Contempo theme (and Blogger overall) was never built with full dark-mode support in mind. It predates this whole “auto theme switching” era.

So yes, even though partial fixes (like custom CSS for .post-body, .sidebar, etc.) can make large parts of the blog look dark, you’ll always hit limitations such as:

  • The comment iframe (uncontrollable white patch)

  • Some widgets and theme-generated elements that inject inline styles

  • Images or text colors that don’t invert well

In short — a full, clean dark/light toggle needs theme-wide coordination, which Blogger simply doesn’t expose.

...

Me: I currrently use Windows High Contrast to see my blog posts in a sort-of dark mode which also works for most of Blogger post edit Compose mode  (does not work so well in HTML mode for editing posts). I will stick with that.

But with these efforts that I put in, I now have a clearer picture of why it is difficult to have a professional looking dark/light mode support for blogger blogs.

...

Me: I was thinking whether we could experiment with a different UI/UX. We could have a button that shows an alert/dialog which informs user about limitations of dark mode on the blog and then give him option to use system dark/light mode setting for the blog. By default the value will be off (don't use system dark/light mode setting). And, at least, initially we won't provide a button to directly switch between light/dark modes.

[CG provided some code for the above. ... Some iterations ...]

Me: That did not work - still positioned to right and below. Following also did not work:
<div style="display:inline-block; vertical-align:top; margin-left:4px;">
  T
</div>
-------------
I think Blogger Layout UI does not provide good enough control for placement of gadget just next to search icon.

If I want to control that, then I need to edit the Theme HTML where I am directly into the Theme HTML and so have control over how the search icon is positioned and how anything else that needs to come next to it can be coded in.

CG: Exactly, Ravi — you’ve diagnosed it correctly.

The Blogger Layout UI is convenient for simple placement, but it has limited control over horizontal alignment inside complex theme sections like the Contempo header. That’s why your inline-block approach didn’t work:

  • The Search (Top) group is structured so that each widget (BlogSearch, HTML) is a block-level div inside a parent container.

  • Block-level elements naturally stack vertically, and the Layout editor doesn’t let you inject CSS that changes the parent container’s layout or wraps widgets inline.

...

Me: But editing Theme HTML in such detail may not be appropriate or in line with what is typically done for such needs. I think instead using position:fixed in CSS and then position to top-right of window would be the typical way in which such dark/light mode icon buttons are positioned. What's ur view
...

Me: Tried it. The issue is that reducing window width brings in overlap with search icon, and switching to mobile layout in Chrome DevTools overlaps it completely. Z-order can ensure search icon is on top but overlap will still be there. That will not look good.

Hmm. I now understand why you chose bottom-right earlier. But I think on mobile even bottom-right will be an issue as it may overlap some text. 
...

Me: How about this approach:
1) Have a Blogger menu item entry that triggers action like button click. This menu item will be accessible on all device breakpoints (window widths).
2) Have floating icon button only for above mobile breakpoint window width. Further, position floating icon button below search icon (which is an important feature and should be clearly visible even at window widths like 800 px). Text that gets covered by the dark/light mode icon-button can be viewed by scrolling typically (except for some edge case of very short post and window width like 800 px). Perhaps from that point of view bottom right is best as it may allow for user to view all content through scrolling if needed including edge cases.
...

Me: Some additional possiblities:
1) Have a Blogger menu item entry that triggers action like button click. This menu item will always be accessible on all device breakpoints (window widths). 
2) Have icon button at bottom right for all breakpoints. But we will provide user the option to hide this button.
3) When user clicks menu item entry or floating icon-button, the dialog should have:
a) Message that dark-mode feature for this blog has some issues due to Blogger constraints.
b) Radio button for Enable/Disable system dark-mode support
c) Radio button to show/hide icon button. 
d) OK/Cancel buttons.
4) The default value for show/hide icon button should be hide for upto mobile breakpoint and show for above mobile breakpoint
What do u think?

[CG provided code.]
...
CG: ... Here’s a practical way to add a Blogger menu item that calls a JavaScript function like openModal() (the one that opens your dark-mode dialog).

1️⃣ Identify the menu you want to add the item to

  • Go to Blogger → Layout → Pages / Menu (depending on how you’ve set up your top navigation).

  • Usually, menu items are static pages or custom links.


2️⃣ Add a Custom Link menu item

  1. In the Pages / Menu widget, choose Add external link (or “Add Link”).

  2. Set:

    • Name: e.g., Dark Mode

    • URL: javascript:openModal()

...
[The code (CSS + JS) was not working. CG virtually stopped responding to issues I was stating ...]

Me: even in chrome is in light mode, the blog post is shown in dark mode. [This was the big issue with code CG provided. CG could not give a solution to it.]
...

Me: i am debugging above code. Chrome devtools shows that darkmode-optin is applied to body element:
<body class="item-view version-1-3-3 variant-indie_light darkmode-optin" data-js-state="loaded">

post-title is a class applied to an h3 element in above body element.
Will this h3 element also have darkmode-optin class applied to it?  I think no.

So how do I specify in CSS that some style should be applied to this h3 element only if its parent body element has darkmode-optin class?

CG: ✅ The <h3> element does not automatically get the darkmode-optin class — only the <body> has it.

So if you want to apply a style to that <h3> element only when its ancestor <body> has the darkmode-optin class,
you use a descendant selector in CSS.


✅ Correct CSS syntax

body.darkmode-optin .post-title { /* styles for h3.post-title when dark mode is ON */ color: white !important; }

Explanation:

  • body.darkmode-optin → targets the <body> only when it has that class.

  • .post-title → any descendant element (in your case, <h3 class="post-title">).

  • Together: this rule only applies when the dark-mode class is active.

...

Me: By "your .post-title elements will automatically pick the dark color." do u mean those elements within body who have post-title class assigned to them

CG: ✅ Exactly right — perfect understanding.

When I said “your .post-title elements will automatically pick the dark color”, I meant:

All elements inside the <body> that has the darkmode-optin class,
and that themselves have the class .post-title,
will use the dark color style.

...

Me: Add CSS:

@media (prefers-color-scheme: dark) {

  body.darkmode-optin .post-title {

    background-color: black !important;

    color: white !important;

  }

----

Works for post title element (h3 element). 

If darkmode-optin class is present in body (added by JS when darkModeEnabled local storage variable is true), then

CSS styles below are applied to post title if Chrome setting is dark mode.

CSS styles below are NOT applied to post title if Chrome setting is light mode.

If darkmode-optin class is absent in body (removed by JS when darkModeEnabled local storage variable is false), then

CSS styles below are NOT applied to post title irrespective of Chrome setting being light or dark mode.

CG: ✅ Excellent — your understanding and observations are 100% correct.

Let’s restate what’s happening — and why it’s working exactly as intended:


🧠 CSS Logic Recap

@media (prefers-color-scheme: dark) { body.darkmode-optin .post-title { background-color: black !important; color: white !important; } }

This means:

  • The outer condition@media (prefers-color-scheme: dark) — activates only when Chrome (or the system) is in dark mode.

  • The inner selectorbody.darkmode-optin .post-title — applies only when the <body> element has the class darkmode-optin.


⚙️ So the combined effect is:

Chrome/System Modedarkmode-optin class present on <body>?CSS applied?Explanation
Light mode❌ No❌ NoMedia query inactive
Dark mode❌ No❌ NoMedia query active, but selector doesn’t match
Light mode✅ Yes❌ NoMedia query inactive
Dark mode✅ Yes✅ YesMedia query active and selector matches

✅ Result

You’ve now got a two-condition control:

  1. User’s system preference (via prefers-color-scheme)

  2. Your own dark mode toggle (darkmode-optin class set via JS + localStorage)

That’s a robust design — gives full control both ways. 👏

Would you like me to show how you can extend this same logic to entire post area, not just .post-title (e.g., .post-body, .post-footer, etc.) — while keeping the same “both conditions must match” rule?

Me: yes ... I guess this has to be repeated for all those elements.

[... CG repeated the error it had made in previous version which I had to figure out.]

Me: I think it should be only this: ...

[CG validated the corrected code and said:]

✅ Yes — that’s a perfectly clean, minimal version for your use case.

This version does exactly what you want:

  • Keeps light mode completely untouched.

  • Only applies dark styling when:

    1. The user explicitly enables dark mode (darkmode-optin added to <body> by JS), and

    2. The system/browser prefers dark mode (prefers-color-scheme: dark).

That’s the safest, most predictable combination — no side effects, no flickering.

You can go ahead and replace your CSS block with exactly what you posted:

/* ============================================================ 🌚 Dark Mode Colors (used only when darkmode-optin is active) ============================================================ */ :root { --dark-bg: #121212; --dark-text: #e0e0e0; --dark-link: #bb86fc; --dark-blockquote-bg: #333333; --dark-blockquote-text: #e0e0e0; } /* ============================================================ 🖥️ System Dark Mode Support (auto-detect) Active only when user has opted in AND system prefers dark ============================================================ */ @media (prefers-color-scheme: dark) { body.darkmode-optin .post-body { background-color: var(--dark-bg) !important; color: var(--dark-text) !important; } body.darkmode-optin a { color: var(--dark-link) !important; } body.darkmode-optin blockquote { background-color: var(--dark-blockquote-bg) !important; color: var(--dark-blockquote-text) !important; } body.darkmode-optin .post-title { color: var(--dark-text) !important; } }

💡 Tip:
If later you want to darken sidebars or other areas, just add similar selectors under the same media query using the same variables — it’ll remain consistent and easy to adjust in one place.

...

Layout -> HTML/JavaScript Gadget :

<!-- Dark Mode Control Gadget -->
<div id="darkModeGadget"></div>

<style>
/* Floating icon button */
#themePromptBtn {
  position: fixed;
  bottom: 12px;
  right: 12px;
  z-index: 9999;
  background: #444;
  color: white;
  border: none;
  border-radius: 6px;
  padding: 6px 10px;
  cursor: pointer;
  font-size: 18px;
  display: block; /* default hidden, JS will control */
}

/* Modal overlay */
#themeModalOverlay {
  display: none;
  position: fixed;
  top:0; left:0; right:0; bottom:0;
  background: rgba(0,0,0,0.5);
  z-index: 10000;
}

/* Modal box */
#themeModal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: white;
  color: black;
  padding: 20px;
  border-radius: 8px;
  width: 300px;
  max-width: 90%;
}

/* Modal buttons */
#themeModal button {
  margin: 6px 6px 0 0;
  padding: 6px 10px;
  cursor: pointer;
}

</style>

<!-- Floating button -->
<button id="themePromptBtn">🌓</button>

<!-- Modal -->
<div id="themeModalOverlay">
  <div id="themeModal">
    <p>Dark-mode feature for this blog has some limitations due to Blogger constraints.</p>
    <form>
      <p><strong>System Dark Mode Support:</strong></p>
      <input type="radio" name="darkMode" value="enable" id="dmEnable" /><label for="dmEnable">Enable</label><br />
      <input type="radio" name="darkMode" value="disable" id="dmDisable" /><label for="dmDisable">Disable</label><br /><br />

      <p><strong>Show Icon Button:</strong></p>
      <input type="radio" name="iconBtn" value="show" id="iconShow" /><label for="iconShow">Show</label><br />
      <input type="radio" name="iconBtn" value="hide" id="iconHide" /><label for="iconHide">Hide</label><br /><br />

      <button type="button" id="modalOK">OK</button>
      <button type="button" id="modalCancel">Cancel</button>
    </form>
  </div>
</div>

<script>
// Default breakpoint for showing floating icon button
const iconBreakpoint = 800;

// Initialize settings from localStorage
let darkModeEnabled = localStorage.getItem('darkModeEnabled') === 'true';
let iconBtnVisible = localStorage.getItem('iconBtnVisible');

// Determine initial icon visibility based on window width
function updateIconVisibility() {
  const btn = document.getElementById('themePromptBtn');
  const w = window.innerWidth;
  if (iconBtnVisible === 'show' || (iconBtnVisible === null && w >= iconBreakpoint)) {
    btn.style.display = 'block';
  } else {
    btn.style.display = 'block';
  }
}

// Apply dark mode if enabled
function applyDarkMode() {
  const body = document.body;
  if (darkModeEnabled) {
    body.classList.add('darkmode-optin');
  } else {
    body.classList.remove('darkmode-optin');
  }
}

// Show modal and set radio buttons according to current settings
function openModal() {
  document.getElementById('themeModalOverlay').style.display = 'block';
  document.getElementById(darkModeEnabled ? 'dmEnable' : 'dmDisable').checked = true;
  const w = window.innerWidth;
  const showDefault = iconBtnVisible === 'show' || (iconBtnVisible === null && w >= iconBreakpoint);
  document.getElementById(showDefault ? 'iconShow' : 'iconHide').checked = true;
}

// Hide modal
function closeModal() {
  document.getElementById('themeModalOverlay').style.display = 'none';
}

// OK button handler
document.getElementById('modalOK').onclick = function() {
  darkModeEnabled = document.querySelector('input[name="darkMode"]:checked').value === 'enable';
  iconBtnVisible = document.querySelector('input[name="iconBtn"]:checked').value;

  localStorage.setItem('darkModeEnabled', darkModeEnabled);
  localStorage.setItem('iconBtnVisible', iconBtnVisible);

  applyDarkMode();
  updateIconVisibility();
  closeModal();
};

// Cancel button handler
document.getElementById('modalCancel').onclick = closeModal;

// Floating button click opens modal
document.getElementById('themePromptBtn').onclick = openModal;

// You can also link a menu item to call openModal() for all breakpoints
// Example: <a href="javascript:openModal()">Dark Mode</a>

// Initialize on page load
window.addEventListener('load', () => {
  applyDarkMode();
  updateIconVisibility();
});

// Update icon visibility on window resize
window.addEventListener('resize', updateIconVisibility);
</script>
----------------

Layout -> Pages gadget -> Entry:
  • Title: Dark Mode Settings
  • Page URL: javascript:openModal()
-----

Me: do we need to check if the CSS variable names we have added to root, are already used in Contempo Light theme
...

Me: --dark-  has no matches in source

CG: ... Your chosen variable names (--dark-bg, --dark-text, etc.) are unique to your gadget CSS and do not clash with any Contempo Light theme definitions.

So you can confidently keep this structure as-is — it’s clean, isolated, and future-proof.

...

--------------------

Works for many but not all elements in blog post page.

If darkmode-optin class is present in body (added by JS when darkModeEnabled local storage variable is true), then

CSS styles above are applied to many elements but not all if Chrome setting is dark mode.

CSS styles above are NOT applied to any elements if Chrome setting is light mode.

If darkmode-optin class is absent in body (removed by JS when darkModeEnabled local storage variable is false), then

CSS styles above are NOT applied to any elements irrespective of Chrome setting being light or dark mode.

So the elements to which the above styles are not getting added (in Chrome dark mode and darkModeEnabled in JS) have to be identified and then added to above CSS. I will do that a little later.

But now the basic approach seems to have got validated. Some issues remain including icon-button not showing for most window widths except close to max. width on PC (at which time menu bar is shown on left). But those are relatively smaller issues.

CG: 💯 Excellent summary — you’ve understood and validated the dark-mode logic perfectly.

Let’s confirm what’s happening:

Main dark-mode mechanism works correctly

  • darkmode-optin added → allows dark styling.

  • @media (prefers-color-scheme: dark) ensures those styles only apply if system (Chrome) is in dark mode.

  • If either condition fails, you get clean light mode.

Next debugging steps are clear

  1. Identify remaining elements whose colors stay light even in dark mode (e.g., header, sidebar, post-footer, gadgets).

  2. Add rules for them using the same variable set, under the same media query — keeping things modular.

The floating icon-button visibility issue
That’s indeed smaller and JS-related. The likely cause is this part: [CG did not get the problem code.] ....

So yes — you’ve now validated the core dark-mode framework 🎯
Next step (when ready): list or highlight a few elements that didn’t switch to dark mode, and I’ll help you write the corresponding CSS additions using your existing variable set.

[Later I explored the experimental chrome://flags/#enable-force-dark feature on my PC desktop. I was already using it on my mobile Chrome where it was aligned with device light/dark mode. Unfortunately on PC, it was ignoring Chrome and Windows (Colors) light mode. Also the colors in dark mode were bright white for key elements but it seemed to handle all elements. But I also had the Windows High Contrast mode feature as an alternative dark mode.... As this Contempo Light customization would involve lot more detective/debugging work to identify Blogger elements to have dark mode colors and for various webpages like post details, post snippets/overview etc., I decided to stop this activity here but record key parts of it for any future needs I may have.]

Some additional info. is given below.

Below videos use Contempo Light theme. They do not handle light/dark mode for comments and the procedure is quite involved. However, you can see changes made in CSS and effect of that. He also has a nice icon-button for light/dark mode.
  • How To Add Dark Mode For Your Blogger Website (Part I), https://www.youtube.com/watch?v=5f2IS-kztmw , 13 min. 23 secs., Sep. 2020
  • How To Add Dark Mode For Your Blogger Website (Part II), https://www.youtube.com/watch?v=bY2RDnnOd90 , 15 min. 11 secs., Sep. 2020
------------------------------------
Google search ai: css apply dark mode if class x is defined
CSS
Your standard (light) theme styles are declared normally. Then, add a new set of rules prefixed with the .dark-mode selector to define the dark theme. 
css
/* Default (Light Mode) styles */
body {
  background-color: #ffffff;
  color: #333333;
}
.card {
  background-color: #f0f0f0;
  border: 1px solid #ccc;
}

/* Dark Mode styles (applied when .dark-mode class is present on the body) */
body.dark-mode {
  background-color: #121212;
  color: #e0e0e0;
}
.dark-mode .card {
  background-color: #1e1e1e;
  border: 1px solid #333;
}
==========================

https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme
---------

position fixed trial that works:
https://playcode.io/css
body {
  background: #6e28d9;
  padding: 0 24px;
  color: rgb(226, 48, 48); /* Change my color to yellow */
  margin: 0;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}
.test {position: fixed;
bottom: 20px;
right: 40px; }

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="src/style.css">
  </head>
  <body>
   
    <h1 class='test'>Hi friend, try change my color!</h1>

  </body>
</html>
==============

Trial with test CSS in blog:
/* System dark-mode rules, only active when user has opted in */

@media (prefers-color-scheme: dark) {
  body.darkmode-optin, .post-outer.darkmode-optin, .post-outer-container.darkmode-optin, .post-title.darkmode-optin, .post-header.darkmode-optin, .post-header-line-1.darkmode-optin, .published.darkmode-optin, .post-body.darkmode-optin, .comment-form {
    background-color: black !important;
    color: white !important;
  }
}

----------
==============================================

Me: I am spending a little (time) on improving the code. To ensure all of a particular blog post of mine is visible, I need to use the following CSS:
:root {
  --dark-bg: #121212;
  --dark-text: #e0e0e0;
  --dark-link: #bb86fc;
  --dark-blockquote-bg: #333333;
  --dark-blockquote-text: #e0e0e0;
}
@media (prefers-color-scheme: dark) {
  body.darkmode-optin .post-body, body.darkmode-optin .post-title,
  body.darkmode-optin .published, body.darkmode-optin .post-outer,
  body.darkmode-optin .post-outer-container, body.darkmode-optin li,
  body.darkmode-optin p, body.darkmode-optin strong,
  body.darkmode-optin code, body.darkmode-optin h1,
  body.darkmode-optin h2, body.darkmode-optin h3
  {
    background-color: var(--dark-bg) !important;
    color: var(--dark-text) !important;
  }
  body.darkmode-optin a {
    color: var(--dark-link) !important;
  }
  body.darkmode-optin blockquote {
    background-color: var(--dark-blockquote-bg) !important;
    color: var(--dark-blockquote-text) !important;
  }
}
-------
I am having to target many HTML elements in the post (like p and h3). Isn't there a way I can use some wildcard like * to target all HTML descendents of body?

[CG provided code ... some iterations ... code is given below but first some details of that are given]
...

CG ... 

1️⃣ What * does

  • The universal selector * matches all elements, regardless of type, ID, or class.

  • It does not care whether the element has a class or not — it just selects every single element.

Me: As * selects everything I was able to simplify the CSS even further to:
:root {
  --dark-bg: #121212;
  --dark-text: #e0e0e0;
  --dark-link: #bb86fc;
  --dark-blockquote-bg: #333333;
  --dark-blockquote-text: #e0e0e0;
}
@media (prefers-color-scheme: dark) {
  body.darkmode-optin .post-outer-container,
  body.darkmode-optin .post-outer-container *
  {
    background-color: var(--dark-bg) !important;
    color: var(--dark-text) !important;
  }
  body.darkmode-optin a {
    color: var(--dark-link) !important;
  }
  body.darkmode-optin blockquote {
    background-color: var(--dark-blockquote-bg) !important;
    color: var(--dark-blockquote-text) !important;
  }
}
-----------------------
That seems to work as expected for the post content display.

[Then I studied the HTML of the blog post page and found out that key top-level element class for the main post area was page and for the sidebar menu was sidebar-container. Then I modified above CSS to target page and sidebar-container classes .]

Me: This handles dark mode for the side bar menu too:
:root {
  --dark-bg: #121212;
  --dark-text: #e0e0e0;
  --dark-link: #bb86fc;
  --dark-blockquote-bg: #333333;
  --dark-blockquote-text: #e0e0e0;
}
@media (prefers-color-scheme: dark) {
  body.darkmode-optin .page,
  body.darkmode-optin .page *,
  body.darkmode-optin .sidebar-container,
  body.darkmode-optin .sidebar-container *
  {
    background-color: var(--dark-bg) !important;
    color: var(--dark-text) !important;
  }
  body.darkmode-optin a {
    color: var(--dark-link) !important;
  }
  body.darkmode-optin blockquote {
    background-color: var(--dark-blockquote-bg) !important;
    color: var(--dark-blockquote-text) !important;
  }
}
-----------------
Links also show as close to white (like text) but that's not such a big issue.
...
Me: I mean, the dark-link color is NOT applied to links.
...
CG: ... You need to make the <a> selector more specific than the * rule.
...
body.darkmode-optin .page a,
body.darkmode-optin .sidebar-container a {
...
Me: Your suggestion fixed it for a elements. Now they appear in purple (or purple like) color. ...
...
Me: For blockquote what is happening is that there is para element within the blockquote - at least in one data case. So p elements colors get applied and blockquote colors don't seem to come into play.

CG: ... You need to target the child elements inside blockquotes explicitly.
...
body.darkmode-optin .page blockquote,
body.darkmode-optin .page blockquote * {
...

Me: That works. Now the blockquote background colour is shaded gray and so stands out slightly against darker (close to black) background. The css i used:
:root {
  --dark-bg: #121212;
  --dark-text: #e0e0e0;
  --dark-link: #bb86fc;
  --dark-blockquote-bg: #333333;
  --dark-blockquote-text: #e0e0e0;
}
@media (prefers-color-scheme: dark) {
  body.darkmode-optin .page,
  body.darkmode-optin .page *,
  body.darkmode-optin .sidebar-container,
  body.darkmode-optin .sidebar-container *
  {
    background-color: var(--dark-bg) !important;
    color: var(--dark-text) !important;
  }
  body.darkmode-optin .page a,
  body.darkmode-optin .sidebar-container a
  {
    color: var(--dark-link) !important;
  }
  body.darkmode-optin .page blockquote,
  body.darkmode-optin .page blockquote *,
  body.darkmode-optin .sidebar-container blockquote,
  body.darkmode-optin .sidebar-container blockquote *
  {
    background-color: var(--dark-blockquote-bg) !important;
    color: var(--dark-blockquote-text) !important;
  }
}
...

Me: There is a visible delay in dark mode being applied. The page is first shown in light mode and after a few noticeable seconds it turns dark

CG: Ah — that “flash of light mode” is a common issue when applying dark mode via JavaScript after page load. Let’s analyze what’s happening:

1️⃣ Why it happens

  • Your JS gadget checks localStorage and adds darkmode-optin only after window.load:

window.addEventListener('load', () => { applyDarkMode(); updateIconVisibility(); });
  • Until this runs, the <body> does not have darkmode-optin, so the browser applies default light-mode CSS.

  • Then after JS executes (a few hundred milliseconds to seconds, depending on network/JS execution), darkmode-optin is added → CSS for dark mode applies → you see the flash from light to dark.


...

✅ Recommended solution

  1. Add tiny inline JS in <head>, before your dark-mode CSS:

<script> if (localStorage.getItem('darkModeEnabled') === 'true') { document.body.classList.add('darkmode-optin'); } </script>
  1. Keep your current CSS as-is (with body.darkmode-optin ...).

  • Now the page renders in dark mode immediately if the user has dark mode enabled.

  • No more flash of light mode.

...

Me: Well in head means I have to edit the theme HTML. JS/HTML gadget can't do that 

CG: Exactly — that’s the catch. 😅

With a Blogger gadget, the HTML/JS runs after the page body has already started rendering, so you’ll always see a small delay (the “flash of light mode”) if you rely solely on the gadget. 

...

Me: Got the issue and HTML head solution. But how about the JS and CSS code we added. Will that slow things down

CG: Not really — your JS and CSS are very lightweight, so they won’t noticeably slow down page rendering. Here’s why:


1️⃣ CSS

body.darkmode-optin .page, 
body.darkmode-optin .page *,
body.darkmode-optin .sidebar-container,
body.darkmode-optin .sidebar-container * { ... }
  • Modern browsers are extremely fast at applying CSS, even with universal selectors (*).

  • The only minor cost is that using * for every descendant forces the browser to calculate styles for all child elements.

  • On a typical blog post page, this is imperceptible — your page won’t be slower for readers.


2️⃣ JS gadget

  • It only does a few things:

    1. Reads localStorage

    2. Adds/removes a class (darkmode-optin)

    3. Controls a floating button’s display

    4. Handles modal open/close

  • No heavy computations, no loops over many elements, no network requests.

  • Running this after page load is instant on modern devices.


3️⃣ What causes the visible delay

  • The “flash of light mode” is not due to JS or CSS being slow.

  • It’s because the darkmode-optin class is added only after the page has already painted.

  • Moving JS into <head> (or top of body, before main content) avoids the flash — that’s the main speed fix.


Conclusion

  • Your existing JS and CSS do not slow down page load in any noticeable way.

  • The only improvement needed is applying the darkmode class as early as possible (pre-head or early inline JS), not optimizing JS execution.


...

Me: Got it. Even local storage access would be cached by chrome i guess 

CG: Exactly ✅ — accessing localStorage is extremely fast and practically instantaneous.

  • Chrome (and all modern browsers) caches localStorage in memory, so reading or writing a small key like darkModeEnabled takes microseconds.

  • For your gadget:

let darkModeEnabled = localStorage.getItem('darkModeEnabled') === 'true';
  • This is not a performance bottleneck at all, even on slow devices.

The only reason you notice a delay is CSS not applying until the class exists, not the localStorage read itself.


If you combine early <head> JS with your current CSS, the dark mode will appear immediately, and the localStorage access won’t be perceptible at all.


Me: But our js code will run for every blog post load. .... This is where something like React does it more efficiently 

CG: Exactly — you’re thinking along the right lines. 😄


1️⃣ Current approach

  • Your JS gadget runs on every page load, yes.

  • It:

    1. Reads localStorage

    2. Adds/removes a class (darkmode-optin)

    3. Updates the floating button

    4. Hooks modal button events

  • Cost: very tiny — a few DOM reads/writes and event bindings. For a normal blog page, this is imperceptible.

  • The only “visual cost” is the flash of light mode, not CPU/memory usage.


2️⃣ How React (or frameworks like it) handle this

  • React is component-based and uses a virtual DOM.

  • Instead of running raw DOM queries and class toggles on page load, React:

    • Computes the DOM diff first

    • Only updates what actually changed

    • Can conditionally render parts of the page immediately

  • In a React app, your “dark mode enabled?” check could happen before the component mounts, so the page renders in the correct mode instantly, without flashes.

  • Also, React encapsulates logic per component, so repeated event binding across multiple components is avoided.


3️⃣ Key difference for your Blogger blog

  • You’re using plain JS in a gadget, which is lightweight, but:

    • It runs once per page load

    • No virtual DOM diffing → browser applies CSS to all descendants

  • On small pages, this is fine. On very large pages with lots of elements, the * selector and DOM reads/writes might take a few milliseconds, but still tiny compared to network load.


4️⃣ Conclusion

  • For your blog: current JS + CSS is fast enough.

  • The main issue is timing, not efficiency.

  • If you wanted React-like efficiency: you’d need to rebuild the blog UI in a SPA framework, which is overkill for Blogger.


...

Me: I think (I) will try the head option u gave. Now i understand why it is necessary in our case to fiddle with theme HTML....about chrome dark  mode extensions for this task vs our approach what r the pros and cons

CG: Exactly — using the <head> inline JS is the only way to eliminate the flash, because you can add the darkmode-optin class before the browser paints the page. Now let’s compare that approach with using Chrome dark-mode extensions.


1️⃣ Your approach (JS + CSS gadget + optional <head> tweak)

Pros:

  • Works for all visitors, not just you.

  • Fully customizable — you control exact colors, backgrounds, and link styles via CSS variables.

  • No dependency on external tools; works on any browser that supports CSS variables and prefers-color-scheme.

  • Can integrate a floating toggle button for users.

  • Supports system dark mode detection (prefers-color-scheme) plus manual override.

Cons:

  • Needs editing the theme <head> to remove flash completely.

  • Some extra JS running per page load (tiny, but still per visit).

  • Slightly more complex to maintain than using a pre-built extension.


2️⃣ Chrome dark-mode extensions

Pros:

  • Quick to install; no code changes to your blog.

  • Applies dark mode instantly for the user who installed it, even on sites that don’t have dark mode.

  • Often includes additional tweaks like invert images, tables, etc.

Cons:

  • Only works for the user who installed the extension. Your visitors will not see dark mode unless they also have it.

  • Extensions may override your blog’s styles unpredictably.

  • Harder to achieve precise control over colors (links, blockquotes, sidebar).

  • Sometimes adds performance overhead or visual glitches.

  • Not integrated with system dark mode preferences in a consistent way.


✅ Summary

Feature JS + CSS Gadget Chrome Extension
Works for all visitors
Custom colors & theme control ❌ / limited
Automatic system dark-mode support Depends on extension
Needs editing theme HTML ✅ (for head tweak)
Flash-free dark mode ✅ (with head tweak) Depends on extension
Quick setup ❌ (requires code)
Maintenance overhead Medium Low (per user)

Bottom line:

  • If your goal is consistent dark mode for all blog readers, your gadget + CSS is the right approach.

  • If your goal is just for yourself or a few users, a Chrome extension is simpler but limited.


...

Me: Interesting comparison.... I  use a chrome dark mode extension [Dark Mode]. One issue is that it applies to all sites by default. Though it may have configuration to include or exclude sites - (I) hv not checked..  . With this JS CSS approach we upgrade our blog to hv dark mode feature like say Whatsapp on web has. That makes the blog more user friendly 

CG: Exactly — that’s the key difference. 😄

  • A Chrome dark-mode extension is generic, applying a “one-size-fits-all” dark theme to every site you visit. Even if it allows site-specific exceptions, it’s still per-user and per-browser. Your blog readers mostly won’t have it installed.

  • With your JS + CSS gadget approach, you’re giving native dark mode support for all visitors:

    1. They can opt in via the floating toggle.

    2. System dark mode (prefers-color-scheme) is respected.

    3. Colors, background, and links are precisely controlled, just like WhatsApp Web or other modern web apps.

    4. Works on any modern browser, not just Chrome.

So your approach upgrades your blog’s UX in a way that browser extensions can’t: it’s built-in, configurable, and consistent for every reader.

The only trade-off is a tiny initial JS execution and possibly adding a small snippet to <head> to eliminate the flash, which is well worth it for a professional-looking dark mode experience.

It essentially turns your Blogger site into a mini web app with dark mode support, which is a modern, user-friendly feature.

Me: Btw the icon button visibility problem seems to be due to me adding the JS gadget in a menu sidebar. So the icon shows only when menu sidebar is open.

CG: Ah — that explains it perfectly. 😄

  • In Blogger, when a gadget is placed inside the menu sidebar, any elements it creates (like your floating #themePromptBtn) are technically children of the sidebar container.

  • If the sidebar is hidden (collapsed), its children are also hidden, so your floating button doesn’t appear.

  • That’s why you only see the icon when the sidebar is expanded.

...

====================
23 October 2025

I had a more general exchange with CG which I felt is appropriate to cover in another post: Exploratory chat with ChatGPT on Blogger as Free/Low-cost Static CMS possibility; Blogger LMS Education Templates. Please see section starting with "Me: 2025-10-23 13:31:00".

19:40, 23 October 2025
After the abovementioned general discussion, I got back to the topic covered by this post. ...

Me: BTW to debug this code, I guess I have to do it by trials within Blogger blog and use Chrome DevTools with the blog post as the source.

It will not be possible/easy to do such editing and debugging in VSCode environment. am i right

CG: Exactly right ✅

Here’s the breakdown:

🧩 Why debugging must be done directly in Blogger

  • Blogger themes are server-rendered XML/HTML templates.
    You can’t easily reproduce that environment (the <b:...> tags, widget includes, and template structure) in VSCode.

  • Even if you copy-paste the HTML into VSCode and open it locally,
    many things — like b:skin, b:section, and b:widget — won’t render properly outside Blogger.

  • The only true-to-reality way to test your <script> and <style> in context

    is to edit the live Blogger theme (or a test blog) and check the results in Chrome DevTools.

...

Me: Hmm. So as a middle ground, I can use VSCode for syntax highlighting and pointing out errors in syntax, which Blogger UI does not do or not do so well (Add CSS does not report syntax errors; the CSS silently fails).
Have created ThemeAdd.css, Gadget.html and InHead.css files which I have opened in VSCode and these files have the associated css or html fragments. VSCode shows the syntax highlighting and shows the CSS syntax errors. For non-trivial mods, I will do the editing here and once it does not report syntax errors, then copy it to Blogger Theme or Layout edit pages. Is that a good middle ground approach? Any suggestions?

CG: Yes — that’s an excellent middle-ground workflow 👏

You’re combining the strengths of VSCode (developer tooling) with the strengths of Blogger (hosted runtime).

Here’s why and how your setup works beautifully, plus a few fine-tuning tips:


Why your approach is solid

  1. Syntax safety:
    Blogger’s editor doesn’t validate CSS or HTML syntax — VSCode does (real-time linting + highlighting).
    You’ll catch missing braces, stray semicolons, or unclosed tags before Blogger swallows them silently.

  2. Version safety:
    Keeping snippets like ThemeAdd.css, Gadget.html, InHead.css in VSCode gives you a mini-version history.
    You can diff changes, backtrack, or experiment freely without risking the live blog.

  3. Focused debugging:
    You only need to switch to Blogger/DevTools when logic (not syntax) fails — e.g. when localStorage or CSS specificity behave unexpectedly.

-------

[Created local git repo in 202510-ContempoTheme-LightDarkMode folder. ... After some iterations ....]

Me: what does requestAnimationFrame do?

CG: requestAnimationFrame() (often shortened as rAF) is a browser API that asks the browser to call your function again just before the next screen repaint — typically about 60 times per second (≈ every 16 ms).

🔍 In our context

We use it here:

(function checkBody() { if (document.body) { if (localStorage.getItem('darkModeEnabled') === 'true') { document.body.classList.add('darkmode-optin'); } } else { requestAnimationFrame(checkBody); } })();

Here’s what happens step-by-step:

  1. The code runs immediately while the <head> is being processed.

  2. If <body> doesn’t exist yet (document.body is null),
    → it asks the browser: “Hey, run checkBody() again before you repaint the next frame.”

  3. The browser does that after it parses more of the HTML, usually within a few milliseconds.

  4. As soon as the <body> element appears, the condition succeeds, and the .darkmode-optin class is added instantly.

  5. The loop stops automatically (because it no longer calls requestAnimationFrame() once document.body exists).


⚡ Why it’s nice for this use

  • It’s non-blocking — doesn’t freeze the page.

  • It’s efficient — the browser only runs it at the best possible time to update the display.

  • It lets your script apply dark mode almost instantly — before the user sees the light-mode flash.


🧠 In short

requestAnimationFrame() lets you re-run a function right before the next screen draw — a smooth, efficient way to wait for something (like <body>) to exist.

...

Me: The following code defines the function and also invokes it. am i right?
  (function checkBody() {
    if (document.body) {
      if (localStorage.getItem('darkModeEnabled') === 'true') {
        document.body.classList.add('darkmode-optin');
      }
    } else {
      requestAnimationFrame(checkBody);
    }
  })();

CG: ✅ Perfectly right — you got it exactly! ...

Me: Now the light to dark mode flicker is gone. But the loading icon of the browser tab continues spinning for quite long as compared to my other blogs. How do I use Chrome DevTools to profile this case and find out which code is taking so much time for the loading?

Moved gadget code to Footer. Now icon button is shown at all window widths

When button is clicked can we position dialog to bottom right of window (this will avoid user having to move the mouse to center of window)?
Similarly when menu button is clicked can we position dialog to top left of window

Show/Hide for icon button is not working. It remains visible all the time.

[Switched to new chat ... many iterations ...]

Me: Dark mode hides the following menu drop-down button:
<svg class="svg-icon-24">
<use xlink:href="/responsive/sprite_v1_6.css.svg#ic_menu_black_24dp" xmlns:xlink="http://www.w3.org/1999/xlink"></use>
</svg>
-----------------
This is part of Blogger Contempo Light Theme code and not my code.
...

Me: Strangely the search icon which is also an SVG continues to show (as white outline):
<svg class="svg-icon-24 search-expand-icon">
<use xlink:href="/responsive/sprite_v1_6.css.svg#ic_search_black_24dp" xmlns:xlink="http://www.w3.org/1999/xlink"></use>
</svg>
----
Any idea why menu icon white color gets probably reset but not search icon?
...

Me: In Theme -> Edit HTML, I manually deleted the twice added 'Add CSS' stuff and then copy-pasted the current CSS code from my saved file (in VSCode) into it. Now the menu icon shows up in dark mode. Hmm. So Blogger Theme and Layout editing UI may trip up at times and surest way seems to be to directly edit the Theme HTML. Am i right?

CG: Exactly — you’ve hit the nail on the head. ✅
  • Blogger Theme → Customize → Add CSS UI is convenient, but it’s not always fully reliable:

    • It can duplicate CSS if you add the same rules multiple times.

    • It may not show all existing CSS in the editor, especially older blocks.

    • It can lead to conflicting or overwritten rules, which is what probably caused your menu icon to disappear earlier.

  • Direct Theme HTML editing is the most predictable approach:

...

[Positioning of modal code needed some iterations to get fixed.]

Commit: Dialog shown at bottom right; Show/Hide for icon button works
----------

Me: The app menu is in an aside element. Its CSS uses position: absolute. therefore when the dialog is opened, it is obscured by the menu. Is there a way to show the dialog on top of menu sidebar without changing menu sidebar position (of absolute)?
...

Me: I have placed the gadget code having the modal in the footer in Blogger Layout page.

CG: Ah — that explains the stacking issue.

Here’s why:

  • In Blogger Layout, when you place a gadget in the Footer, the generated HTML for that gadget is nested inside the footer container.

  • That container (and possibly its ancestors) may have position: relative/absolute or even its own stacking context.

  • Even though your modal has position: fixed and a high z-index, it is still constrained by the stacking context of its ancestors. That’s why it can appear behind the sidebar.

...

The typical fix

  1. Append the modal to <body>, not inside the footer or any gadget container.

...

Me: Moving gadget to top of page body did not solve the problem. Hmm. I think I have no option but to edit the Theme HTML directly.

CG: Yes — that makes sense. 😅

Here’s why moving the gadget in Layout UI didn’t solve it:

  1. Even in Page Body, the gadget’s HTML is still nested inside some <div> containers (like main-wrapper or content-wrapper) that may have:

    • position: relative or position: absolute

    • Their own stacking context

  2. Because of this, your modal’s position: fixed is still constrained by ancestor stacking contexts, so it can appear behind the sidebar.


✅ Conclusion

  • To guarantee the modal appears above all page elements, you need it to be a direct child of <body>.

  • The only reliable way in Blogger to do that is by editing Theme HTML and either:

    1. Pasting the modal + overlay <div> right before </body>, or

    2. Dynamically appending it to <body> via JavaScript (from a gadget)...

...

[Moving only modal code to before end body tag gave some error ...]
Me: Then I think it is better to move the whole gadget code to HTML directly just before end body tag.

CG: Yes — that’s actually the simplest and most reliable solution for Blogger:

Why moving the whole gadget to Theme HTML works best

  1. No timing issues:

    • Both the modal HTML and the JS are parsed together, so document.getElementById() calls always succeed.

  2. Stacking context is clean:

    • The modal and overlay are direct children of <body>, so they reliably appear above the sidebar and all other content.

  3. No dependency on Layout UI placement:

    • Footer, Page Body, or other gadget sections can create stacking conflicts.

    • Everything works regardless of page template structure.

...

[I moved the whole gadget code to HTML directly just before end body tag.]

Me: Blogger editor complains about && in:
      if (iconBtnVisible === 'show' || (iconBtnVisible === null && w >= iconBreakpoint)) {

CG: Ah — yes, that’s a quirk of the Blogger Theme HTML/JS editor.
  • Blogger sometimes treats && and || inside inline <script> as XML/HTML parsing errors, because it tries to parse it as invalid HTML rather than JavaScript.

  • This usually happens when editing directly in the Theme HTML editor, not in an external file.


✅ Workarounds

1️⃣ Use nested if instead of && / ||

Replace:

if (iconBtnVisible === 'show' || (iconBtnVisible === null && w >= iconBreakpoint)) { btn.style.display = 'block'; } else { btn.style.display = 'none'; }

With:

if (iconBtnVisible === 'show') { btn.style.display = 'block'; } else if (iconBtnVisible === null) { if (w >= iconBreakpoint) { btn.style.display = 'block'; } else { btn.style.display = 'none'; } } else { btn.style.display = 'none'; }
  • No && or || → Blogger editor will accept it.

  • Logic is identical.


2️⃣ Encode the JS with HTML entities (less readable)

if (iconBtnVisible === 'show' || (iconBtnVisible === null &amp;&amp; w >= iconBreakpoint)) { btn.style.display = 'block'; }
  • &amp;&amp; instead of &&

  • || usually works, but sometimes you also need | | → messy, not recommended.


✅ Recommendation

  • Use nested if style (#1).

  • It avoids Blogger parsing issues entirely and keeps your code readable.

...

Me: For time being, I used &amp;&amp;
That got past the error and file got saved. Next I will test it.
...

[If I recall correctly, that fixed the dialog being obscured by menu issue.]

Me:  The menu (hamburger) button shows in dark mode but once the menu is opened and closed, the menu (hamburger) button is not shown. Here is the related HTML code from Chrome DevTools.
<button class="svg-icon-24-button hamburger-menu flat-icon-button ripple"><div class="splash-wrapper"><span class="splash" style="height: 48px; width: 48px; left: -1px; top: 0px;"></span></div>
<svg class="svg-icon-24">
<use xlink:href="/responsive/sprite_v1_6.css.svg#ic_menu_black_24dp" xmlns:xlink="http://www.w3.org/1999/xlink"></use>
</svg>
</button>
-------------------Any idea?

[This turned out to be a very time-consuming effort (few hours). I tried many of CG's suggestions, did lot of Chrome DevTools playing around with CSS and also changes in Theme HTML but there was no success. CG could not spot the issue despite me sharing above code with it, which has the div element with splash-wrapper class that I was able finally figure out. I have given below some of the trials info. as it could be useful for future.]

CG ... 
  1. Select the <use> element (the one inside <svg>).

  2. In the Styles panel, scroll to the bottom.

  3. Click the “+” icon — it will create a new rule like:

    use { }
  4. Inside that rule, type:

    fill: #fff !important;

    (You can also try fill: currentColor !important; to test inherited color.)

This way, you’re forcing just this <use> element to appear white — good for quick verification.

...

Me: tried both of the above:
fill: currentColor !important;
  fill: #fff !important;
---- Neither worked.

[Modified Theme HTML and tried below stuff as it was not possible to do so directly in Chrome DevTools.]

CG: ...
body.darkmode-optin .page *:not(svg):not(use),
body.darkmode-optin .sidebar-container *:not(svg):not(use) {
...

Me: Doesn't work. Chrome Devtools shows that the background color for svg and use while not directly applied, is still inherited from rule: @media (prefers-color-scheme: dark) {
    body.darkmode-optin .page, body.darkmode-optin .page *:not(svg):not(use), body.darkmode-optin .sidebar-container, body.darkmode-optin .sidebar-container *:not(svg):not(use) {
        background-color: var(--dark-bg) !important;
        color: var(--dark-text) !important;
    }
}

CG ...
body.darkmode-optin .hamburger-menu,
body.darkmode-optin .hamburger-menu svg {
  background: none !important;
}
body.darkmode-optin .hamburger-menu svg use {
  fill: #fff !important; /* or #e0e0e0 to match text */
}
...

Me: didn't work ... Now in:
body.darkmode-optin .sidebar-container *:not(svg):not(use) { … }
---- you are excluding svg and use elements.
Can we similarly exclude a class like hamburger-menu

CG: Yes — in CSS, you can exclude elements by class using the :not() pseudo-class, just like we did for svg and use.

For example, if you want to exclude the .hamburger-menu element from your universal * rule, you can do:

body.darkmode-optin .sidebar-container *:not(svg):not(use):not(.hamburger-menu) { background-color: var(--dark-bg) !important; color: var(--dark-text) !important; }

Explanation:

  • *:not(svg) → excludes all <svg> elements

  • :not(use) → excludes <use> elements inside SVG

  • :not(.hamburger-menu) → excludes elements with class hamburger-menu

You can combine multiple :not() pseudo-classes in the same selector like this.


⚠️ Important caveat

This only excludes the specific element itself (<button class="hamburger-menu">).
If the <svg> inside it is still a descendant of another parent that has the universal * rule applied, its appearance may still be affected.

That’s why sometimes you also need explicit overrides for the <svg> or <use> inside .hamburger-menu, e.g.:

body.darkmode-optin .hamburger-menu svg use { fill: #fff !important; }

...

Me: in css can you prevent inheritence of a particular property for an element or class

CG: Yes — in CSS you cannot selectively “turn off inheritance” for a property globally, but you can override inherited values for specific elements or classes.

Here are the main ways:


1. Use initial

  • Sets the property to its initial value (the default defined by CSS, not inherited).

  • Example: prevent color inheritance:

.hamburger-menu { color: initial; background-color: initial; }

✅ Resets the property to the default (like black for color, transparent for background-color).


2. Use unset

  • Acts like initial if the property normally inherits and like inherit if it normally doesn’t.

  • Example:

.hamburger-menu { color: unset; }
  • For color (which normally inherits), this is equivalent to initial.

  • For background-color (which normally does NOT inherit), this is equivalent to inherit.


3. Use revert (modern browsers)

  • Resets the property to the value from the user-agent stylesheet or higher-level stylesheet, ignoring local overrides.

  • Example:

.hamburger-menu { color: revert; background-color: revert; }
  • Very useful if your dark-mode * rule is applying !important to everything — though !important may still override it unless you also use !important.


⚡ Practical use for your case

To stop the dark-mode universal * from coloring the hamburger menu, you could do:

body.darkmode-optin .hamburger-menu, body.darkmode-optin .hamburger-menu svg, body.darkmode-optin .hamburger-menu svg use { color: initial !important; background-color: transparent !important; fill: #fff !important; }
  • color: initial !important; → prevents inherited text color from affecting the icon.

  • background-color: transparent !important; → prevents parent backgrounds from “covering” it.

  • fill: #fff !important; → ensures the SVG shows in white.


...

Me: can we replace the hamburger menu svg with our own in dark mode?

...

Me: can u find an online hamburger menu icon suitable for dark mode

...

Me: so give me a good external url to use for hamburger icon in dark mode.

CG: Certainly! You can use the following external SVG URL for a white hamburger menu icon suitable for dark mode:

SVG URL:

https://www.svgrepo.com/show/524617/hamburger-menu.svg

Usage in HTML:

<button class="hamburger-menu flat-icon-button">
   <img src="https://www.svgrepo.com/show/524617/hamburger-menu.svg" alt="Menu"
     style="width:24px; height:24px;">
</button>

Usage in CSS:

body.darkmode-optin .hamburger-menu {
  background-image: url('https://www.svgrepo.com/show/524617/hamburger-menu.svg');
  background-size: contain;
  background-repeat: no-repeat;
  width: 48px;  /* match original button size */
  height: 48px;
}

This SVG icon is simple, clean, and designed to be visible on dark backgrounds. You can use it directly by referencing the URL in your HTML or CSS.

[IFIRC, I tried out only the CSS part which was odd as I needed the HTML too. The original Theme HTML button code did not have an img element IFIRC as it used an svg instead. The CSS resulted in the image being shown in gray but that too was getting obscured after menu open.]

[IFIRC, the code below was what I was trying out at above stage.]
Tried below; did not work:
      @media (prefers-color-scheme: dark) {
        body.darkmode-optin .page,
        body.darkmode-optin .page *:not(svg):not(use):not(.hamburger-menu):not(.centered-top),
        body.darkmode-optin .sidebar-container,
        body.darkmode-optin .sidebar-container *:not(svg):not(use):not(.hamburger-menu):not(.centered-top)
        {
          background-color: var(--dark-bg) !important;
          color: var(--dark-text) !important;
        }
        body.darkmode-optin .page a,
        body.darkmode-optin .sidebar-container a
        {
          color: var(--dark-link) !important;
        }
        body.darkmode-optin .page blockquote,
        body.darkmode-optin .page blockquote *,
        body.darkmode-optin .sidebar-container blockquote,
        body.darkmode-optin .sidebar-container blockquote *
        {
          background-color: var(--dark-blockquote-bg) !important;
          color: var(--dark-blockquote-text) !important;
        }
        body.darkmode-optin .hamburger-menu svg {
          display: none; /* hide original SVG */
        }
        body.darkmode-optin .hamburger-menu {
          background-image: url('https://www.svgrepo.com/show/524617/hamburger-menu.svg');
          background-size: contain;
          background-repeat: no-repeat;
          width: 48px;  /* match original button size */
          height: 48px;
        }
-------------

Me: Got some clue ... In the code below taken from Chrome DevTools:
<button class="svg-icon-24-button hamburger-menu flat-icon-button ripple"><div class="splash-wrapper"><span class="splash" style="height: 48px; width: 48px; left: 9px; top: 2px;"></span></div>
<svg class="svg-icon-24">
<use xlink:href="/responsive/sprite_v1_6.css.svg#ic_menu_black_24dp" xmlns:xlink="http://www.w3.org/1999/xlink"></use>
</svg>
</button>
-----
If I delete the <div class="splash-wrapper"><span class="splash" style="height: 48px; width: 48px; left: 9px; top: 2px;"></span></div>
element, then the hamburger icon is shown even in dark mode after the menu is opened and closed.

I also observed something like that even after deletion of the element, opening and closing the menu recreates it (no page refresh). But I will need to repeat the test to confirm it.
Does this give u any idea of what the issue is and how we can solve it?

[I did the deletion of the HTML in DevTools. IFIRC, it is not present in the Theme HTML though Theme HTML does have splash-wrapper CSS class. Perhaps the above div element is injected into the HTML by Blogger code.]

CG: Ah — now this makes things much clearer! 😯

Here’s what’s going on based on your observation:


🔍 Diagnosis

  1. The culprit: the splash-wrapper / splash element

    • This is part of Blogger’s ripple effect for buttons (flat-icon-button ripple).

    • When you click the hamburger menu, Blogger’s JS dynamically recreates the ripple elements (<div class="splash-wrapper"><span class="splash">…</span></div>).

    • The ripple element sits on top of the SVG, and in dark mode, it probably has a transparent or semi-transparent dark background that ends up obscuring the icon.

  2. Why the icon disappears after opening/closing

    • Blogger’s menu JS re-renders the ripple wrapper every time the menu is toggled.

    • The new splash element inherits styles from the dark-mode * rule (e.g., background-color: var(--dark-bg)), or the container overlay hides the icon visually.

    • That explains why simply deleting the element temporarily fixes it — but opening the menu recreates it.

  3. Why the search icon works

    • The search button likely does not have the ripple wrapper or is structured differently, so it’s unaffected.


💡 Possible Solutions

  1. Exclude the splash-wrapper from dark-mode styling

    • You can try this CSS:

body.darkmode-optin .hamburger-menu .splash-wrapper, body.darkmode-optin .hamburger-menu .splash-wrapper .splash { background: transparent !important; color: inherit !important; }
  • This ensures that the ripple container doesn’t get dark background or text color applied.

  • Add this after your dark-mode * rule.

  1. Optionally hide the ripple completely for the hamburger button

body.darkmode-optin .hamburger-menu .splash-wrapper { display: none !important; }
  • This prevents the ripple from ever appearing over the icon.

  • Drawback: you lose the ripple animation in dark mode, but functionally the menu works fine.

  1. Advanced JS approach

  • Use a MutationObserver to watch for dynamically added splash elements inside .hamburger-menu and immediately set display: none or background: transparent.

  • Ensures that even when Blogger re-creates the ripple wrapper, it won’t cover the icon.


⚡ Recommendation

The simplest and most reliable fix is to hide the ripple wrapper for the hamburger menu in dark mode:

body.darkmode-optin .hamburger-menu .splash-wrapper { display: none !important; }

This should make the hamburger icon always visible, even after opening/closing the menu, without affecting other buttons.


...

Me: That worked! [I used the recommended fix above.] Hmm. Now the back button on open menu in dark mode has same disappearing issue after menu open and close. let me study the HTML in devtools and find what it uses.

...

Me: btw please explain: body.darkmode-optin .hamburger-menu .splash-wrapper {
  display: none !important;
}

CG: Sure! Let’s break it down step by step:
body.darkmode-optin .hamburger-menu .splash-wrapper {
  display: none !important;
}

1️⃣ Selector: body.darkmode-optin .hamburger-menu .splash-wrapper

  • body.darkmode-optin

    • Selects the <body> element only if it has the class darkmode-optin.

    • This ensures the rule applies only in dark mode, not in light mode.

  • .hamburger-menu

    • Selects any element with class hamburger-menu inside that body.

    • In your case, that’s the menu button <button class="hamburger-menu">…</button>.

  • .splash-wrapper

    • Selects the child element inside .hamburger-menu with class splash-wrapper.

    • That’s the <div class="splash-wrapper"><span class="splash">…</span></div> that Blogger dynamically adds for the ripple effect.

So combined:

“Target the splash-wrapper inside the hamburger menu, but only when dark mode is active.”


2️⃣ Declaration: display: none !important;

  • display: none

    • Hides the element completely from the page.

    • It removes it from layout, so it won’t block or cover the SVG icon.

  • !important

    • Ensures this rule overrides any other CSS that might try to set display differently, including Blogger’s inline styles or dynamically added styles.


✅ Effect

  • The ripple <div> is completely hidden in dark mode.

  • The SVG icon underneath remains visible, so the hamburger button is always shown.

  • Ripple animation is gone for dark mode, but functionality is preserved.


If you want, I can write a universal dark-mode rule that automatically hides all .flat-icon-button .splash-wrapper elements to prevent disappearing icons for both hamburger and back buttons. This way you don’t have to fix each button individually.

Do you want me to do that?

Me:         body.darkmode-optin .sidebar-back .splash-wrapper {
          display: none !important;
        } 
fixed it. The class was sidebar-back.
...

Me: This gets so tied in to Blogger implementation of the theme. ... BTW does Blogger automatically update the core theme used by a blog? Probably not as that would break customization.

CG: Exactly — you’re right. 😅

Blogger does not automatically update the core theme once you have customized it. Here’s the key:


How Blogger Themes Work

  1. Default themes (like Contempo Light) are “master copies” in Blogger’s system.

  2. When you apply a theme to your blog, Blogger creates a copy of the theme HTML and CSS for your blog.

  3. From that point on:

    • You control the HTML/CSS/JS in your blog’s Theme Editor.

    • Blogger will not push updates to that copy automatically.

    • This prevents your customizations from being overwritten.


Implications

  • Any manual edits (like your dark mode CSS, gadgets, or HTML tweaks) are safe from being overwritten by Blogger.

  • However, if Google ever releases new features in the theme itself, your blog won’t automatically inherit those changes — you’d have to manually integrate them if desired.

  • This is why dark-mode fixes that depend on .splash-wrapper or .sidebar-back are tied to the current structure of the Contempo theme. If Blogger updates the theme copy (rare, usually only for new blogs), these fixes might need adjustment.


Conclusion:

  • You can safely tweak your current blog theme.

  • Keep a backup of your Theme HTML just in case you ever want to migrate or troubleshoot.


...

Me: What I guess I wanted to know is whether there are dynamic server side components that the theme uses which Google may change over time. You see, the theme code is complex - thousands of lines - but so long as it is only using that theme code (HTML/CSS/JS) and does NOT invoke some Blogger hosted API kind of stuff for theme operation , we are safe with customized theme continuing to work. 

CG: Exactly — you’ve got it. ✅

Here’s a more precise way to think about it:


1️⃣ Static Theme Code

  • All the HTML, CSS, and JS you see in Theme → Edit HTML is part of your blog’s copy.

  • Once you customize it, it lives on your blog’s servers.

  • Any code you added or modified (like dark-mode rules, ripple fixes, or gadgets) will continue to work because it’s fully self-contained.


2️⃣ Dynamic/Server-side Components

Blogger does use some dynamic components, e.g.,:

  • Data-driven widgets like:

    • Post lists

    • Comments

    • Archive widgets

    • Page lists
      These rely on Blogger servers to provide content.

  • Built-in JS that sometimes fetches resources from Blogger URLs (/responsive/sprite_v1_6.css.svg, etc.) or updates menus dynamically.

    • These can change if Google updates how those resources are served.

Important: As long as your customizations don’t depend on changing Blogger APIs or dynamic JS behavior, they are safe.


3️⃣ What could break

  • If Blogger changes the structure of a dynamic element (like the ripple wrappers, menu buttons, or class names), your CSS rules tied to those classes (e.g., .hamburger-menu .splash-wrapper) might stop working.

  • Rarely, if a JS resource that your theme references externally is removed or changed, dynamic behaviors may be affected (like the menu sprite or ripple logic).


✅ Conclusion

  • Your static customizations are safe.

  • Any fixes that target specific HTML structures or classes may need adjustment if Blogger updates how those dynamic widgets are generated.

  • For maximum robustness:

    • Keep backups of your Theme HTML/CSS.

    • Use class-based selectors and dark-mode wrappers rather than deep structural selectors where possible.


If you want, I can outline a best-practice way to make your dark-mode CSS/JS less fragile so it survives small Blogger updates. This would make your fixes safer even if Google tweaks the dynamic parts.

Do you want me to do that?


Me: Dynamic widget generation is worrisome for this aspect. What if some new class is used instead of splash-wrapper? Essentially, Blogger server side injecting HTML/JS/CSS into the theme at runtime is the tricky thing. But perhaps as that could break lot of customizations which Blogger permits, Blogger may not be doing that.

CG: Exactly — you’re thinking along the right lines. 👍

Here’s the nuanced picture:


1️⃣ What Blogger does dynamically

Blogger does generate some HTML/JS at runtime for widgets and menus, but within limits:

  • Widgets like page lists, menus, and comments may be rendered dynamically using server-side templates.

  • Some JS enhancements (ripple effects, menu toggling, responsive behaviors) are injected client-side.

  • These often rely on specific class names (e.g., .splash-wrapper, .flat-icon-button) in the shipped theme JS.


2️⃣ Why your dark-mode fix can be fragile

  • Your fix depends on existing class names (.splash-wrapper, .sidebar-back) and the structure of the generated HTML.

  • If Google changes the class names or slightly modifies the DOM structure for these dynamic widgets, your CSS rules may stop working.

  • This is the main risk of targeting dynamic elements that are not fully under your control.


3️⃣ Why Blogger probably doesn’t change it often

  • Blogger is a mass-market platform; changing class names or structure for menus or ripple buttons would break thousands of customizations.

  • Google likely maintains backward compatibility for existing themes and blogs.

  • So the risk of sudden breakage is low, but it’s not zero.


4️⃣ How to make your customizations safer

  • Scope fixes via parent classes (e.g., body.darkmode-optin) to avoid affecting other elements.

  • Target broader patterns when possible:

    • Instead of .hamburger-menu .splash-wrapper, you could do .flat-icon-button .splash-wrapper inside dark mode — catches all ripple buttons.

  • Keep a backup of your Theme HTML/CSS/JS.

  • Test occasionally, especially after any Blogger UI updates.


Bottom line:

  • Your dark-mode customizations are generally safe.

  • The main fragility comes from dynamic HTML/JS generation with specific class names, but Google likely won’t change them lightly.

  • Using broader or more general CSS rules scoped under darkmode-optin can mitigate the risk further.


If you want, I can draft a robust dark-mode CSS/JS approach for Contempo Light that handles ripple buttons dynamically, so even if Blogger adds new ripple wrappers, your icons remain visible. This would make it far less brittle.

Do you want me to do that?

Me: I think we can have a key indicator here. If a class (like splash-wrapper or hamburger-menu) is present in the Blogger supplied theme code (unmodified Contempo Light) then using those classes in customized code would be safe. What would be unsafe is HTML/JS/CSS not present in theme code but which is injected dynamically by Blogger and so visible in Chrome DevTools. Such HTML/JS/CSS should be viewed as Blogger implementation details above and beyond the supplied default theme (like Contempo Light). What do u say?

CG: Exactly — that’s a very sound way to think about it. ✅

Here’s a clear breakdown:


1️⃣ Safe to target

  • Classes, IDs, HTML structure, and JS functions present in the unmodified theme (e.g., Contempo Light shipped by Blogger)

    • Examples: .hamburger-menu, .sidebar-back, .flat-icon-button, .page, .sidebar-container

  • These are part of the official theme code.

  • Using them in your custom CSS or JS is relatively safe, because Google won’t usually rename or remove them — doing so would break existing blogs.


2️⃣ Unsafe to target

  • Elements, classes, or inline styles that are injected dynamically at runtime by Blogger

    • Examples: <div class="splash-wrapper"><span class="splash">…</span></div> that appear when you click buttons

    • These are implementation details of Blogger’s JS, not part of the shipped theme HTML/CSS/JS

  • Using these in your customization is fragile, because Google could change:

    • Class names (splash-wrapper → something else)

    • DOM structure

    • JS logic

  • Any fix depending on these is technically unsupported, even if it works today.


✅ Practical guideline

  1. Inspect the unmodified Contempo Light theme in Theme → Edit HTML.

  2. Only rely on classes/IDs present there for long-term, stable CSS/JS customization.

  3. For dynamic elements (like ripple wrappers), treat them as implementation details and consider:

    • Making fixes broad and flexible (e.g., hide any .splash-wrapper inside .flat-icon-button in dark mode)

    • Accepting that minor breakage could happen if Google changes the JS behavior.


So your reasoning is correct:

If a class exists in the shipped theme code, using it is generally safe. Anything visible only after runtime injection by Blogger is fragile and can change without notice.

This distinction is a good key indicator for maintenance and future-proofing.

If you want, I can draft a dark-mode approach for Contempo Light that respects this principle — using only safe theme classes where possible and still handling the ripple/button issue. It would be robust and maintainable.

Do you want me to do that?

Me: splash-wrapper class is part of theme code.

But div elements using that class are not part of theme code and seem to be dynamically generated.

CG: Exactly — that distinction is spot on. ✅

  • The splash-wrapper class itself is defined in the Contempo Light theme CSS/JS.

    • That means the class selector is safe to use in your custom CSS.

    • Example: body.darkmode-optin .splash-wrapper { … } is stable.

  • The actual <div class="splash-wrapper"><span class="splash">…</span></div> elements are dynamically generated by Blogger’s JS at runtime when you click buttons.

    • These elements aren’t present in the shipped theme HTML.

    • They could be recreated differently if Google changes the menu/ripple implementation.

Implications for customization:

  • You can safely write CSS targeting .splash-wrapper — because the class exists in the theme and will always exist in some context.

  • However, you can’t rely on the exact structure of the dynamically generated <div> for JS fixes, because Blogger can modify how/when it’s inserted.

  • Using display: none or other CSS rules on .splash-wrapper works today, but it’s technically dependent on Blogger’s runtime behavior. It’s practically safe but slightly fragile.


✅ Summary:

  • Safe: Class selectors, IDs, and structure defined in shipped theme code.

  • Fragile: Dynamically created elements using those classes at runtime.

This explains why your dark-mode fix works but why you have to observe the ripple div behavior — it’s injected dynamically but uses a class from the theme.

You could make it slightly more robust by scoping CSS to body.darkmode-optin .flat-icon-button .splash-wrapper so any dynamically added ripple in dark mode is automatically handled.

Do you want me to write that robust CSS snippet for all ripple buttons?

[Then I got into a more general discussion about extensions vs customized theme; lack of mechanism for user to switch themes due to which if a blog breaks due to theme customization and that is not fixed, the blog may be become unusable; difference between personal blogs without maintenance person(s) to regularly observe and fix issues with theme customization, and organization or team blogs which have regular maintenace and so can fix issues with theme customization (including going to a stable backup theme temporarily/long-term) ... This part is (to be) covered in another post of mine: Exploratory chat with ChatGPT on Blogger as Free/Low-cost Static CMS possibility; Blogger LMS Education Templates.]

=====================================

=====================================================
04:23, 25 October 2025

Created https://contempo-ld.blogspot.com/ for test and demo purposes.

Commit: First version of customization done and tested with https://contempo-ld.blogspot.com/


In modal dialog UI, made the radio buttons checkboxes and improved the labels.

Commit: Improved modal dialog UI

==============

Me: In Contempo Light Theme's Layout,in its Sidebar (Top) widget (if widget's the term for it), if I have only a Pages gadget with one Page (Appearance Mode) and hide the About profile gadget, an unseemly unnecessary horizontal scrollbar appears below Appearance Mode page when the blog is shown on PC desktop as full width window (I am saying unnecessary as content easily fits in horizontal width of sidebar). In Chrome DevTools, I see that the CSS of the Sidebar (Top) widget can be easily changed to fix it. For example:
.sidebar-container .sidebar_top
{
    overflow: auto;
}
can be changed to 
.sidebar-container .sidebar_top
 {
    overflow-x: hidden;
    overflow-y: auto;
}
----------
That fixes the issue (no unnecessary horizontal scrollbar appears).
But now I am modifying Blogger Contempo Light Theme code (as against simply adding some code). I am hesitant to do that.
Any ideas?
...

Me: It seems to be a design flaw in the theme. Perhaps they expect users to always show the profile gadget in the Sidebar (Top). When that is shown, this horizontal scrollbar problem goes away. For full width on desktop PC (> 1440 px, I think is the spec.), the Pages gadget is shown on the left and Profile gadget is shown to its right. Still there is no horizontal scrollbar issue at the bottom. 'Appearance Mode' is broken into 'Appearanc' in one line and 'e' in another.
--------------

Me: Given below is the entire Sidebar (Top) HTML taken from Chrome DevTools:
<div class="sidebar_top_wrapper">
<div class="sidebar_top section" id="sidebar_top" name="Sidebar (Top)"><div class="widget PageList" data-version="2" id="PageList2">
<div class="widget-content">
<ul>
<li>
<a href="javascript:openModal(false)">Appearance Mode</a>
</li>
</ul>
</div>
</div>
</div>
</div>
--------------------
Now for the CSS classes used above
How can I get sidebar_top_wrapper CSS class value from Chrome DevTools?
...

Me: U see, I want to debug the CSS issue in Contempo Layout Theme which results in excess width being provided to Page entry in Pages gadget within Sidebar (Top). Why is the width so big when the content is small? A flex box is used but I don't see flex-grow 1 (it is 0). I can't figure out why that is happening. So I was wondering I could get the CSS values easily for the classes involved in the HTML I shared with you of Sidebar (top) and then see if you could spot the issue.

The hack-fix for the issue is easy. Override the overflow-x using custom CSS. But I still want to know the root cause as I want to do minimal changes to original Contempo Layout Theme. Sometimes an innocent override can trip up something else.
...

CG: Perfect — here’s a ready-to-run snippet you can paste into the Chrome DevTools Console. It will log all relevant computed CSS values and box model info for the Sidebar (Top) container and the Pages gadget, including the key classes .sidebar_top_wrapper, .sidebar_top, and .section. This should help us pinpoint why the Pages gadget gets excess width.
(() => { // Select elements const wrapper = document.querySelector('.sidebar_top_wrapper'); const sidebarTop = document.querySelector('.sidebar_top'); const section = sidebarTop; // In Contempo, .sidebar_top has .section class const pagesWidget = document.querySelector('#PageList2'); const widgetContent = pagesWidget.querySelector('.widget-content'); const elements = { wrapper, sidebarTop, section, pagesWidget, widgetContent }; console.log("=== Computed Styles and Box Model Info ==="); Object.entries(elements).forEach(([name, el]) => { if (!el) { console.log(`${name}: element not found`); return; } const style = getComputedStyle(el); console.log(`\n${name}:`); console.log({ display: style.display, flexDirection: style.flexDirection, flexGrow: style.flexGrow, flexShrink: style.flexShrink, flexBasis: style.flexBasis, justifyContent: style.justifyContent, alignItems: style.alignItems, width: style.width, minWidth: style.minWidth, maxWidth: style.maxWidth, padding: style.padding, margin: style.margin, boxSizing: style.boxSizing, overflowX: style.overflowX, overflowY: style.overflowY }); const rect = el.getBoundingClientRect(); console.log("Box Model / Pixel sizes:", { offsetWidth: el.offsetWidth, clientWidth: el.clientWidth, scrollWidth: el.scrollWidth, boundingRectWidth: rect.width }); }); })();

What this does

  1. Selects the key elements:

    • .sidebar_top_wrapper → wrapper around top sidebar

    • .sidebar_top → flex container for widgets

    • .section → same as .sidebar_top in Contempo

    • #PageList2 → Pages gadget

    • .widget-content → content inside Pages gadget

  2. Logs computed styles relevant for flex layout and sizing:

    • display, flex-grow, flex-shrink, flex-basis

    • width, min-width, max-width

    • padding, margin, box-sizing, overflow

  3. Logs box model widths:

    • offsetWidth, clientWidth, scrollWidth, boundingRect.width


✅ How to use

  1. Open your blog page in Chrome.

  2. Right-click → InspectConsole tab.

  3. Paste the snippet → press Enter.

  4. Expand the logged objects to see all widths, paddings, flex properties.

Once you have this info, we can pinpoint why the Pages gadget width is bigger than expected, and whether a minimal tweak can fix it without overriding the theme unnecessarily.


...

Me: here's top level output (copy-paste) (the issue is the 284 width - that is far more than needed to fit 'Appearance Mode'):
=== Computed Styles and Box Model Info ===
VM7496:20 
wrapper:
VM7496:21 {display: 'block', flexDirection: 'row', flexGrow: '0', flexShrink: '1', flexBasis: 'auto', …}
VM7496:40 Box Model / Pixel sizes: {offsetWidth: 284, clientWidth: 284, scrollWidth: 284, boundingRectWidth: 284}
VM7496:20 
sidebarTop:
VM7496:21 {display: 'flex', flexDirection: 'row', flexGrow: '0', flexShrink: '1', flexBasis: 'auto', …}
VM7496:40 Box Model / Pixel sizes: {offsetWidth: 284, clientWidth: 284, scrollWidth: 316, boundingRectWidth: 284}
VM7496:20 
section:
VM7496:21 {display: 'flex', flexDirection: 'row', flexGrow: '0', flexShrink: '1', flexBasis: 'auto', …}
VM7496:40 Box Model / Pixel sizes: {offsetWidth: 284, clientWidth: 284, scrollWidth: 316, boundingRectWidth: 284}
VM7496:20 
pagesWidget:
VM7496:21 {display: 'block', flexDirection: 'row', flexGrow: '0', flexShrink: '0', flexBasis: 'auto', …}
VM7496:40 Box Model / Pixel sizes: {offsetWidth: 284, clientWidth: 284, scrollWidth: 284, boundingRectWidth: 284}
VM7496:20 
widgetContent:
VM7496:21 {display: 'block', flexDirection: 'row', flexGrow: '0', flexShrink: '1', flexBasis: 'auto', …}
VM7496:40 Box Model / Pixel sizes: {offsetWidth: 284, clientWidth: 284, scrollWidth: 284, boundingRectWidth: 284}
undefined
----

Me: It is margin of pagesWidget that causes the width to increase. But why is pagesWidget taking up 284 px width (excluding margin)?
pagesWidget:
VM7496:21 
{
    "display": "block",
    "flexDirection": "row",
    "flexGrow": "0",
    "flexShrink": "0",
    "flexBasis": "auto",
    "justifyContent": "normal",
    "alignItems": "normal",
    "width": "284px",
    "minWidth": "auto",
    "maxWidth": "none",
    "padding": "0px 0px 16px",
    "margin": "0px 16px",
    "boxSizing": "content-box",
    "overflowX": "visible",
    "overflowY": "visible"
}
...

Me: Rule for widget Pagelist from DevTools:
.sidebar-container .sidebar_top>:only-child {
    -webkit-box-flex: 0;
    -webkit-flex: 0 0 auto;
    -ms-flex: 0 0 auto;
    flex: 0 0 auto;
    -webkit-align-self: center;
    -ms-flex-item-align: center;
    align-self: center;
    width: 100%;
}
------------------- How can I make flex-shrink 1 here?
...

CG: ... .sidebar-container .sidebar_top > :only-child {
    width: auto;      /* let flex control the width */
    flex-shrink: 1;   /* allow shrinking */
}
✅ This ensures the Pages gadget shrinks to fit its content and doesn’t produce unnecessary extra width.
...
[I did not try out the above but in all probability it would work.]
...

In DevTools if I change the rule-entry to:
flex: 0 1 auto;
the horizontal scrollbar goes away.
If I change it back to:
flex: 0 0 auto;
the horizontal scrollbar gets shown again.
--------

From Blogger Contempo Light Theme HTML code:
.sidebar-container .sidebar_top>:only-child{
-webkit-box-flex:0;
-webkit-flex:0 0 auto;
-ms-flex:0 0 auto;
flex:0 0 auto;
-webkit-align-self:center;
-ms-flex-item-align:center;
align-self:center;
width:100%
}
-----
That's the only search result for 'only-child'

So this seems to be a CSS design bug/flaw in Blogger's theme code. It should be: flex:0 1 auto;
Am I right?

CG: Yes — you are correct. ✅
...

4️⃣ Conclusion

  • This is essentially a small CSS bug/flaw in the Contempo Light Theme.

  • Changing it to flex: 0 1 auto is the minimal correct fix.

  • Safe and backward-compatible: does not break flex behavior for multiple widgets.


...

Me: I don't want to change that Blogger code. Usually such code changes should be followed by rigorous testing which I think only the Blogger team/person that developed/maintains the theme should do/can do in a proper way.

I will document this as an issue. Now that I know the root cause being a small flaw in Blogger theme, I can consider, workarounds like putting the Pages gadget in Sidebar Bottom and see if that works out well. Worst case, I can do the override of overflow-x: hidden.
...

Me: I invested time in this as I wanted to develop the confidence of debugging such Blogger core Theme issues. If I propose a Blogger customized theme approach as a small software solution for some needs, I want to have some confidence that if the core theme code itself has issues, with AI help, I can dig into it,  isolate it thereby being sure that the issue is with the core theme and not customized theme code I added, and finally consider a workaround solution. ...
...

Me: ... U said:
Where to be cautious

Don’t spend weeks on a single minor visual issue unless it’s critical.

Focus on: can I reproduce the problem, identify the cause, propose a safe workaround or document it? That’s usually sufficient.

Your current effort is just a few hours of deep inspection — that’s reasonable.
------------------

Very good advice. I agree. Few hours is a good limit for these kind of things. You see horizontal scrollbar appearing when not needed may not impact functionality at all. But users may get put off seeing it and think that the customized solution is not good. if afer few hours, the root cause is identified, the customer can be told about it, and then the workaround applied. This way, customer does not get a concern that the customizaton was not professional.
...

Me: There is only one element with id as sidebar_top in the Theme HTML.
So I am using the following CSS rule added to Theme HTML which applies to light and dark mode:
      #sidebar_top
      {
          overflow-x: hidden !important;
      }        
----
Note that this is outside the block of:
@media (prefers-color-scheme: dark)
----

Tested the above. It is working as expected. No horizontal scrollbar issue in light/dark mode.

I think my above #sidebar_top is a better solution than:
.sidebar-container .sidebar_top {
    overflow-x: hidden; /* hide unnecessary horizontal scrollbar */
    overflow-y: auto;
}
----
The issue with above code is that sidebar_top class and sidebar-container class are referenced many times in the theme HTML.
What do u say?

CG: ✅ You’re absolutely right — your chosen solution using the specific ID selector is the better and safer approach here. ...

Commit: Fix for unnecessary horizontal scrollbar in Sidebar (Top) when only Pages gadget is contained in it
---------------

In following HTML:
<div class="search focused">
<button aria-label="Search" class="search-expand touch-icon-button">
<div class="flat-icon-button ripple"><div class="splash-wrapper"><span class="splash" style="height: 48px; width: 48px; left: -1px; top: 0px;"></span></div>
<svg class="svg-icon-24 search-expand-icon">
<use xlink:href="/responsive/sprite_v1_6.css.svg#ic_search_black_24dp" xmlns:xlink="http://www.w3.org/1999/xlink"></use>
</svg>
</div>
</button>
<div class="section" id="search_top" name="Search (Top)"><div class="widget BlogSearch" data-version="2" id="BlogSearch1">
<h3 class="title">
Search This Blog
</h3>
<div class="widget-content" role="search">
<form action="https://contempo-ld.blogspot.com/search" target="_top">
<div class="search-input">
<input aria-label="Search this blog" autocomplete="off" name="q" placeholder="Search this blog" value="">
</div>
<input class="search-action flat-button" type="submit" value="Search">
</form>
</div>
</div></div>
<div class="dim-overlay"></div></div>
-----
in dark mode, the search icon is not visible. The solution is to hide the splash-wrapper. Will the below CSS do it?

        body.darkmode-optin .search-expand .splash-wrapper {
          display: none !important;
        }

...
Me: That didn't work. Even deleting the splash_wrapper element in Chome DevTools does not show the search icon.

[Another time consuming trial and error activity. ...]

Me: The fill and color both are white. ... the unusual thing here is that the form component seems to cover the icon position (which is animated as if moving from right to left. Let me share the HTML:
<div class="search focused">
<button aria-label="Search" class="search-expand touch-icon-button">
<div class="flat-icon-button ripple"><div class="splash-wrapper"><span class="splash animate" style="height: 48px; width: 48px; left: 0px; top: -1px;"></span></div>
<svg class="svg-icon-24 search-expand-icon">
<use xlink:href="/responsive/sprite_v1_6.css.svg#ic_search_black_24dp" xmlns:xlink="http://www.w3.org/1999/xlink"></use>
</svg>
</div>
</button>
<div class="section" id="search_top" name="Search (Top)"><div class="widget BlogSearch" data-version="2" id="BlogSearch1">
<h3 class="title">
Search This Blog
</h3>
<div class="widget-content" role="search">
<form action="https://contempo-ld.blogspot.com/search" target="_top">
<div class="search-input">
<input aria-label="Search this blog" autocomplete="off" name="q" placeholder="Search this blog" value="">
</div>
<input class="search-action flat-button" type="submit" value="Search" disabled="">
</form>
</div>
</div></div>
<div class="dim-overlay"></div></div>
...

CG: Excellent — that extra detail is very helpful.

From your description and HTML, I can confirm that this is not a color issue but a layout / stacking (z-index or overflow) issue.


💡 What’s happening

In Contempo’s search feature:

  • When you click the magnifier icon (the <button class="search-expand touch-icon-button">),
    a CSS animation expands the form element (<form>…</form>) horizontally into view.

  • During that animation, the input form often overlaps the icon.

  • In your dark mode, the contrast makes the overlapping invisible (the background and icon blend).

So, even though the SVG icon itself is still there, it’s covered up by the form (or its wrapper).

...

Me: If I give display: none to:
div with search_top id
div with dim-overlay class
Then the search icon is shown.
...

Me: In Devtools:
The form has z-index 101
So I made z-index of icon to 200
And I simply deleted the dim-overlay div
The icon is still not shown.

CG: ... 
If the <form> itself (inside #search_top) has z-index: 101 and you gave the icon a higher one (z-index: 200) but it’s still invisible, that suggests the <svg> icon is being covered by the <form> because of DOM order or stacking context, not just raw z-index.
...

🧠 1. Why the z-index: 200 didn’t help

z-index only takes effect when the element is positioned (position: relative | absolute | fixed | sticky).
If the SVG or its wrapper isn’t positioned, the z-index value is ignored.

So even though you set:

svg.search-expand-icon { z-index: 200; }

— it won’t matter unless you also set:

svg.search-expand-icon { position: relative; z-index: 200; }
...
Me: As soon as I specify position: relative on svg element, the icon is shown.
...

Me: Your suggestion of:
.search-expand svg.search-expand-icon {
  position: relative;
  z-index: 200;
}
------
worked! Hmm. CSS is so hard to understand when confronted with a complex set up like a Blogger theme.
...

Me: I used the following code within media query for dark mode:
        body.darkmode-optin .search-expand svg.search-expand-icon {
          position: relative;
          z-index: 200;
        }      
-----
It is working.
...

CG: [Concise note on it] ...

Dark Mode Search Icon – Contempo Theme

Behavior:

  • In dark mode, the search icon <svg class="search-expand-icon"> is initially visible.

  • When the icon is clicked, it slides left as the search input box expands.

  • During this animation, the icon becomes invisible because it is covered by the expanding form and overlay layers.

Root Cause:

  • The SVG is not a positioned element, so z-index has no effect.

  • Overlapping containers (form, dim-overlay) create stacking contexts that cover the icon during the slide animation.

Fix Applied:

body.darkmode-optin .search-expand svg.search-expand-icon { position: relative; z-index: 200; }

Why it Works:

  • position: relative allows z-index to lift the SVG above the form/overlay.

  • z-index: 200 ensures the icon stays visible throughout the slide animation.

  • Scoped to body.darkmode-optin to affect only dark mode.

Result:

  • Icon remains visible when clicked and during the expansion animation.

  • Light mode behavior is unaffected.

  • No changes to core theme code.


...

Commit: Fix for search icon visibility while in search mode and in dark mode

Commit: Fixed icon button related small bugs

[Console command to quickly compare two non-binary files (like diff in Unix):] 
I had to use it this way:
ThemeCopies> cmd /c fc .\ContempoLightThemeCustom.xml .\ContempoLightThemeCustom-v20251025-2031.xml
Comparing files .\ContempoLightThemeCustom.xml and .\CONTEMPOLIGHTTHEMECUSTOM-V20251025-2031.XML
FC: no differences encountered

ThemeCopies> 
-----

Commit: Updated Readme

==============================

13:37, 26 October 2025

[To convert Blogger-escaped code (e.g. &#39;, &quot;) in Blogger Theme HTML editor back to normal readable text with spacing preserved:]

[CG suggestions:]

Option 2: Use a small decoding script

If you do this often, create a quick PowerShell or Node.js utility that converts HTML entities back to plain text.

Example PowerShell one-liner:

Get-Content 'blogger_snippet.html' -Raw | ForEach-Object { [System.Net.WebUtility]::HtmlDecode($_) } | Set-Content 'decoded_snippet.js' -Encoding UTF8

This uses .HtmlDecode() to restore ' and other entities automatically.


Option 3: Use an online or VSCode extension decoder

  • Online: https://www.urldecoder.org/html-decoder/
    → Paste and decode instantly.

  • VSCode extension:
    🔍 Search for “HTML Entities Encoder/Decoder” or “Encode Decode” extension (e.g. Encoder / Decoder by mitchdenny).
    Then select text → Right-click → “Decode HTML entities”.


Option 4: Avoid Blogger escaping when possible

If you’re only inserting JS code (not HTML markup), wrap your code inside:

<b:if cond='data:blog.pageType == "index"'> <script><![CDATA[ // your JS code here — Blogger won’t escape this ]]></script> </b:if>

→ The <![CDATA[ ... ]]> block prevents Blogger from converting ' into &#39;.


...

Me: I am trying out https://www.urldecoder.org/
One issue is that I (lose) spaces and tabs in the decoded output

[The VSCode extension option did a good job. ...]
VSCode extension: Encode Decode VSCode Extension by Mitch Denny, https://marketplace.visualstudio.com/items?itemName=mitchdenny.ecdc , is open-source.
1. Select code to be converted.
2. Open Command Palette
3. Specify Encode/Decode: Convert Selection
In dropdown: Choose HTML Entities to String
------

Commit: Updated code style to match Blogger Theme Editor style; Old files reorg

=======================
16:22, 26 October 2025

TwsitBlogg Light/Dark Mode JS CG chat

[As now I had got some understanding of how light/dark mode support in Blogger blogs can be implement through customization of themes, I revisited a stackoverflow post which had some code for another implementation but which I did not follow when I read it in the past: Add dark mode button to blogspot . CG helped me get some top-level understanding of it mainly by converting the jquery code to plain JS.]
...

Me: Thanks. The above code seems to be picked up from https://www.twistblogg.com/2020/04/add-night-mode-in-blogger-blog.html

I don't know jquery and so above code was hard to understand for me. Your conversion to plain JS has helped me get a top-level understanding of it.

I plan to try it out later some time. Thanks.

CG: You're very welcome 🙏 — and yes, you’re exactly right: the original Blogger night-mode gadget from TwistBlogg (2020) uses jQuery.

Your observation is spot-on — the jQuery version looks a bit cryptic if you’re not used to its shorthand syntax ($(document).ready(), $('.check').change(), etc.). The plain-JavaScript version I shared does the same job, but it’s simpler, more transparent, and works even if your template doesn’t include jQuery (many modern Blogger themes omit it).

I’m glad this translation helped you get a clearer idea of what’s happening underneath 👏

When you try it later, I can help you:

  • Insert it safely in Blogger’s Theme → Edit HTML (so Blogger doesn’t strip it).

  • Or turn it into a reusable HTML/JavaScript gadget you can drop anywhere via Layout.

Would you like me to show both options side-by-side when you’re ready to implement it?

---

================

One earlier reported issue with the current implementation I am using (different from immediately above messages of stackoverflow and twistblogg.com implmentation), is outstanding. I am giving below the messages part related to that issue.

From msgexch (messages exchange) on or around 24 October 2025 in CG chat titled, "Find element by id":

Me: ... But the loading icon of the browser tab continues spinning for quite long as compared to my other blogs. How do I use Chrome DevTools to profile this case and find out which code is taking so much time for the loading?

CG: ... 

🧩 1. Profiling which code slows down page load

Yes, Chrome DevTools can tell you exactly what’s taking long.

🧭 Steps

  1. Open your blog in Chrome.

  2. Press F12 → open DevTools.

  3. Go to the Performance tab.

  4. Click the record button (●), then reload your page.

  5. Let it record until your blog fully loads → click Stop (■).

  6. Chrome will show a timeline:

    • Look at the Main thread section.

    • Expand long yellow (Script) or purple (Rendering) bars.

    • Hover to see what JavaScript or CSS file/function took time.

    • Click the long bar → see call stack and source line.

Tip: If you see repeated reflows or style recalculations (purple/green bars), some script is touching DOM repeatedly too early or too often — typical cause for flicker or delay.


==========================

20:32, 27 October 2025
Done: Add few posts including short ones and links from one post to another on same blog.
Done: Add one page
Added it to Pages gadget.

With above additions, the blog current (imperfect) dark mode functionality seems to work. In particular, added page also shows correctly in dark mode.

Done: Gradient in posts list
Commit: Added dark mode for gradient in posts list

Done: Floating header panel
Commit: Added dark mode for floating header panel

=========================
13:54, 28 October 2025

chrome://flags/#enable-force-dark on Chrome on Win 11 PC shows:
Auto Dark Mode for Web Contents
related options like enabled/disabled

chrome://flags/#enable-force-dark on Chrome on Android mobile shows:
Darken websites checkbox in themes setting
related options like enabled/disabled

Advantage of above feature on Chrome on Android mobile is that I can switch that on/off using Chrome menu without having to relaunch Chrome. In contrast, as Win 11 desktop Chrome does not show such a checkbox, I can switch off the feature, AFAIK, only by disabling "Auto Dark Mode for Web Contents" which needs a relaunch of Chrome.

The latter (desktop PC) is a significant disadvantage as the forced dark mode is applied to all websites and is not suitable for some. So for sites where it is not suitable turning off the Auto Dark Mode requires visiting chrome://flags/#enable-force-dark, disabling the feature and relaunching Chrome. This is where an extension or even our experimental/exploratory light/dark mode support for Contempo Light theme is very useful (easy to switch as it does not involve relaunch).
----

From Google search AI for: chrome mobile provides darken websites checkbox but chrome on Windows11 does not

Chrome on Windows does not have a "Darken websites" checkbox in the settings menu because it handles dark mode for websites differently than Chrome for Android. On desktop, website dark mode is controlled through system settings or experimental flags rather than a dedicated checkbox. [1, 2, 3]  
How Chrome desktop handles dark mode
• System-wide dark mode: The primary method for enabling dark mode on websites in Windows is by changing your operating system's theme to "Dark." When Windows is set to dark mode, Chrome automatically signals to websites that they should display their dark-themed version if one is available. 
• "Force Dark Mode" flag: For websites that don't have a native dark theme, you can force them to display one using an experimental feature. 

1. Type  into your address bar and press Enter. 
2. Search for "Auto Dark Mode for Web Contents". 
3. Change the setting from "Default" to "Enabled" and relaunch Chrome. 

• Extensions: For more granular control over dark mode on a per-website basis, you can install a browser extension like "Dark Reader" from the Chrome Web Store. These extensions allow you to customize brightness, contrast, and toggle dark mode on or off for specific sites. [1, 4, 5, 6, 7]  

Why Android is different

Chrome for Android's "Darken websites" checkbox was an experimental feature designed to force websites into dark mode on a mobile device. It was particularly useful for users on older versions of Android that did not have a system-wide dark mode. However, as the Android operating system evolved to support dark mode system-wide, the experimental checkbox became less necessary. [1, 2, 8, 9]  
Ultimately, the functionality exists in both versions, but the implementation differs based on the unique design and features of their respective operating systems. 

AI responses may include mistakes.

[1] https://www.ionos.com/digitalguide/websites/web-development/google-chrome-dark-mode/
[2] https://developer.chrome.com/blog/auto-dark-theme
[3] https://testingbot.com/resources/articles/how-to-change-browser-settings
[4] https://www.youtube.com/watch?v=6gw3qAc7Ayk
[5] https://www.pcmag.com/how-to/how-to-enable-dark-mode-on-your-browser
[6] https://www.howtogeek.com/446198/how-to-force-dark-mode-on-every-website-in-google-chrome/
[7] https://helpdeskgeek.com/6-ways-to-enable-google-chromes-dark-mode-in-windows/
[8] https://www.reddit.com/r/chrome/comments/gt8i9t/cant_disable_dark_mode_for_web_contents_in_chrome/
[9] https://www.bluestacks.com/apps/tools/dark-mode-on-pc.html

==== end Google search AI response ======================

Commit: Improved dark mode for floating header

==============================

I spent some time trying out the code provided in the stack overlow and twistblogg.com posts/articles mentioned earlier. That effort has been summarized below by CG with some editing by me. The code was tried out on https://ravisiyerar.blogspot.com.

Attempt to Add Night Mode to the Contempo Light Theme Using Stack Overflow and TwistBlogg Posts/Articles

Related posts/articles:

I explored solutions mentioned on Stack Overflow and the TwistBlogg.com posts/articles mentioned above to add a night (dark) mode feature to the Blogger Contempo Light theme, .

The Stack Overflow post referred to a script and CSS sample originally published on TwistBlogg (April 2020). They claimed to enable “Night Mode / Dark Mode” for Blogger by toggling a CSS class (.Night) on the <body> element using JavaScript (with jQuery).

At first glance, this appeared to be a generic Blogger-compatible solution. The accompanying CSS listed a few rules like:

.Night #outer-wrapper, .Night #sidebar-wrapper { background: #323232; color: #fff !important; }

and ended with the note:

/* --- Add More Elements --- */

which implied that users could expand the styling as needed.

However, on closer inspection and practical testing, it became clear that the solution was not designed for Google’s official templates such as Contempo, Emporio, Notable, or Soho. The linked page in the TwistBlogg article (“Best Premium Blogger Templates”) lists only third-party, non-Google templates from various designers.

Because of that, the provided CSS selectors matched only some elements of the Contempo layout:

  • The Popular Posts widget turned dark correctly (#PopularPosts1 was covered).

  • But the main post list and featured post sections (#Blog1 and #FeaturedPost1) remained bright, since these IDs and classes were never included in the TwistBlogg CSS.

  • Neither is the post page itself shown properly in dark mode.

Thus, the dark-mode effect appeared only partially — limited to a few areas that happened to share similar IDs with those third-party templates.

In summary:

  • The TwistBlogg script correctly toggles a .Night class on the <body>.

  • The CSS provided, however, targets non-standard template structures.

  • As a result, the method does not provide a full dark mode for the Contempo Light theme without substantial theme-specific CSS customization.

This exploration shows that while the TwistBlogg/Stack Overflow approach works as a general concept, it requires careful adaptation to each specific Blogger theme — particularly Google’s official ones, whose HTML structures differ significantly from custom third-party templates.

Note: This approach has a transparent floating button implementation which is good.


--- end Summary ---

I have saved the related code in the folder twistblogtrial in the project repo.
Commit: Stack overflow & Twistblogg.com articles approach trial
---------------

(Later on) 28 October 2025

Me: In some previous chats with you, we developed a different approach to implement dark in Contempo Light Theme. It is largely working but not entirely complete. Now in this twistblogg.com approach, I very much liked the transparent floating icon-button they use. The transparency ensures that reading the content that may come below it in small width screens like mobile is not really a problem.
But in our earlier approach we have a non-transparent icon-button. Its key HTML and CSS code is given below:
...
How can we convert above non-transparent button to a transparent button like in the twistblogg.com approach?
...
Me: I would like to try this out offline in a test html instead of in the blogger html theme. can u provide me a suitable test html file.

[CG provided the standalone test file, whose current version is saved as standalone-trials\darkmode-test.html. This was very useful for easy trials including changing the styles in Chrome DevTools for this file and thereby finalizing the style I wanted. After this, I incorporated the style in Blogger Theme HTML and corresponding project HTML file.]

Me: These settings work well for me:
      background: rgba(0, 0, 0, 0.25);
      /* backdrop-filter: blur(4px); */

      color: rgba(1,1,1,.7);

whats ur view

CG: ...
Overall result:
Elegant, minimal, and unobtrusive — the button remains legible but doesn’t block underlying text or visuals, which is especially good on small mobile screens.
...

Commit: Made floating button transparent
------------

Me: Now the next aspect ... The twistblogg.com button is a nice outline button done with svg whereas my above implementation is an emoji button. The transparency setting helps make the emoji button quite acceptable. But outline like twistblogg.com would be better. what do u say?

CG: Yes — I completely agree. ✅

Your emoji button works fine and is quick to implement, but the outline SVG button style (like in TwistBlogg’s code) has clear advantages — especially for long-term polish and consistency across devices.

Here’s a breakdown:

Aspect Emoji Button Outline SVG Button
Visual polish Looks decent, but emoji rendering differs by OS/browser Crisp, uniform appearance everywhere
Transparency handling Works well, but emoji edges may not blend perfectly Outline SVG blends beautifully with transparent backgrounds
Responsiveness Scales OK, but can get pixelated or misaligned Scales perfectly at any size or resolution
Theme adaptability Limited control (emoji color depends on OS) Full CSS control (you can recolor stroke/fill on hover or dark mode)
Professional look Friendly and simple Sleek and modern — more like material/flat design

So yes — keeping your transparent background idea but replacing the emoji with a small inline SVG moon/sun outline icon will make it look much more refined and consistent.

If you’d like, I can give you a small self-contained HTML test file that:

  • keeps your current transparent style,

  • replaces the emoji with a simple outline SVG moon icon, and

  • includes a hover effect (slightly darker background + lighter stroke).

Would you like me to prepare that version next?

[CG provided the file. I made some changes. Current version of it is saved as standalone-trials\outlinebtn-test.html.] 

CG: That’s a very nice refinement 👏 — simple, balanced, and practical.

Here’s my quick review of your version:

Pros / Improvements you’ve made

  1. Removed blur (backdrop-filter) — good call. While visually appealing, it can cause performance issues or inconsistent results across browsers (especially on Blogger pages).

  2. Added dark-mode color adjustment for the button (color: rgba(255, 255, 255, 0.7)) — excellent; ensures contrast and readability in dark mode.

  3. Retained mild transparency (rgba(0, 0, 0, 0.25)) — keeps the content underneath readable and elegant.

  4. Button hover and transition feel subtle but polished.

  5. Extra paragraph text helps test positioning and readability — great for realistic preview.

Behavior

  • Works flawlessly offline.

  • Toggle logic is clean and self-contained (no external dependencies).

  • No visual flicker between states.

  • SVG outline remains visible in both modes due to the smart stroke="currentColor" usage.

Optional future enhancement
If later you’d like to make the icon visually switch (e.g., moon → sun), that can be done with a small JS tweak and second SVG path toggle. But your current setup is already elegant and perfectly suitable for Blogger integration.

So yes — your modified version is production-quality for testing and Blogger use.
-----

[I incorporated changes in project code and Blogger customized theme.]
Commit: Made floating button svg outline
---------------

Comments