Notes on creating a small test LMS with limited functionality but free hosting, using a Blogger theme (template)

Last updated on 12 Jan. 2026
Related previous post
===========================================================

Quick Info

Development Test LMS: dravilms.blogspot.com/
Initial Test LMS: ravilms.blogspot.com

If I deploy a simple LMS site with a third-party theme then if there are some bugs, if I do not have a good knowledge of the theme code, I will find it very difficult to fix the bugs. Also the theme license, including license in its code, should be a suitable license for my needs.

This post covers my exploration of using Google provided Blogger theme Contempo Light and doing some customization of it for a test LMS.

All gadgets are widgets, but not all widgets are gadgets. Gadget = UI-manageable widget. A widget is any <b:widget> instance in the theme XML that has an ID, renders content and participates in Blogger’s rendering pipeline. Blogger uses the term gadget in the UI and widget in XML.

In Blogger to use relative link for a post URL like: https://ravilms.blogspot.com/2025/12/sample-post.html, use link: /2025/12/sample-post.html

Blogger Contempo theme seems to show hamburger menu only for index, label and search pages. It does not show it for a static page like p/courses-list.html. Therefore using a static page as redirected home page with JavaScript code in the theme, does not show hamburger menu which looks odd. So I decided to drop that approach.

Blogger seems to use the first image in post as the featured image. So I am inserting such featured images as the first element in posts where I need them. Recommended size for featured image is: 1280 × 720 px (16:9 aspect ratio). Blogger downscales them well on mobile. Extra large setting gives great display on desktop and mobile landscape. On mobile portrait, it gives extra left margin and right edge is flush with edge of mobile screen but otherwise the image rendering is OK. So it is an acceptable issue. Large setting looks good on mobile portrait but is too small on desktop due to which it is not a good choice.

For Courses List blog page, used heading style for each course title, centered alignment, followed by image below it with Extra large size. It looks great on desktop, mobile portrait as well as mobile landscape.

Using Blogger's Insert YouTube video UI, the resultant embedded video (in normal size mode - not full screen mode) on desktop is somewhat small - does not take up full content width of post. To make it full content width size and responsive, HTML editing has to be done, using YouTube's embed code and some CSS to control size. More on it given below in this Quick Info section.

CSS rule: Vertical padding percentages (padding-top / padding-bottom) are calculated relative to the element’s width, not its height. This is used in YouTube video auto-sizing width CSS code.

To reduce duplication and to avoid CSS name collision, for Youtube video auto-sizing width:
Theme → Customize → Advanced → Add CSS
/* YouTube Video Container for resizing width to take up full content width */
.dravilms-video-container {
  position: relative;
  padding-bottom: 56.25%;
  height: 0;
  overflow: hidden;
  width: 100%;
  margin: 0 auto;
}

.dravilms-video-container iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
-------------

In post, to show thumbnail of Youtube video in Blog site posts list but show image in post, used:
<img src="https://img.youtube.com/vi/Ag1AKIl_2GM/maxresdefault.jpg" style="display: none;" />
  • Ag1AKIl_2GM is the video id and should be changed suitably.
To show the actual Youtube video, in post, used:
<div class="dravilms-video-container">
<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" frameborder="0" height="auto" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/Ag1AKIl_2GM" title="Free software, free society: Richard Stallman at TEDxGeneva 2014" width="100%"></iframe>
</div>

As of now (12 Jan. 2026), the above is implemented in: https://dravilms.blogspot.com/2026/01/course-1-lesson-2.html but that can change later.
---------

Below part of Quick Info section is about iframes. Note that the embedded Youtube video uses iframe.

Unlike media embeds, OAuth login flows (including LinkedIn OAuth) do not use iframes. They rely on secure browser redirects or popups because identity providers intentionally block iframe embedding to prevent security and trust issues.

In my React Native + Expo app, I only interact with the RevenueCat SDK. For the web build, RevenueCat internally integrates Stripe’s web SDK, which dynamically injects secure iframes to render the card payment UI. As a result, Stripe’s payment screen appears in the web app “magically,” even though my application code never references Stripe or iframes directly. This abstraction is intentional and is required for security and compliance.

A Short Note on Iframes: Past and Present

In the early 2000s, iframes were commonly used for general web page layout. At that time, CSS layout capabilities were limited, JavaScript was immature, and partial page updates were difficult. Developers often used iframes to separate headers, menus, content areas, and footers, or to reload only parts of a page. By the mid-to-late 2000s, this approach began to fall out of favor. Improvements in CSS (floats, later Flexbox and Grid), the rise of AJAX, and better SEO and accessibility practices made iframe-based layouts unnecessary and problematic. As a result, using iframes for a site’s own layout came to be viewed as a poor architectural choice.

However, iframes did not disappear. Their role changed. In modern web development, iframes are primarily used for embedding third-party content such as: YouTube videos, Google Maps, Payment widgets, Advertisements and Social media embeds. In these cases, iframes serve an important purpose: security and isolation. They allow external content to run in a sandboxed environment, protecting the main page from unintended side effects or security risks.

Because modern frameworks and CMS platforms usually hide iframe details, developers today encounter them less directly. Systems like Blogger, which expose raw HTML, make iframe usage more visible—especially when embedding videos.

In summary:
Iframes evolved from being a general page-composition tool to being a specialized mechanism for safely embedding external content. They are no longer recommended for layout, but they remain a core part of the modern web’s infrastructure.
===========================================================
===========================================================

Details

11:23, 01 January 2026

A few days back, I had created a blog - ravilms.blogspot.com - to test out "LMS Education" third-party Blogger theme, https://lms-education.blogspot.com/. For more about it, search for 'Started exploring "LMS EDUCATION" Blogger template - free version' in this post of mine.

I followed the instructions of uploading the "LMS Education" (LMSEd) theme/template using Restore theme command of Blogger Dashboard UI, into ravilms blog. With that the basic LMSEd theme functionality came into play but while https://lms-education.blogspot.com/ has courses and lessons demo data set up, ravilms did not have any data.

I then created two dummy course posts with a lesson each. The key points I followed were:
  • The course posts had to have the label Courses.
  • The lessons posts would have lesson content but no label
  • The course posts content linked to appropriate lesson posts.
With this basic setup, the Courses category links were listing the course pages correctly.

There were many gadgets on the blog which had to be either dropped or set up properly with images and text description like Header hero image, Campus, Testimonials, Videos etc. (the lms-education demo page shows them). 

At this stage, I felt I should get a better understanding of the code of the LMSEd theme. That resulted in a lot of discussion with ChatGPT about Blogger theme code-level customization and associated learning in general and also getting a very top-level view of approach taken in LMSEd theme. After that, I feel that if I deploy a simple LMS site with LMSEd theme then if there are some bugs, I will find it very difficult to fix them. There also seems to be some license issue related to commercial use as the license in the theme code for the free version, is limited to non-commercial usage.

So I decided to step back from considering using "LMS Education" third-party theme for my test LMS exploration.

I feel I should explore using Google provided Blogger themes like Contempo Light and doing some customization myself in this test LMS exploration.

For that, I wanted to see if I am able to remove the "LMS Education" theme gadgets/widgets from my ravilms blog and reuse the few dummy posts I have created with Contempo Light blog.
...

Me: I have a few tests posts in the blog. I don't want to recreate them in a new blog. How do I copy over these test posts WITHOUT the theme and gadgets?
...
Me: ... Now Google only provides a takeout mechanism will all Blogger data (all blogs of mine). And in that it has a feed.atom file and a there-layouts.xml file besides 2 or 3 other files.

CG was not able to give a good answer.


To import feed.atom or .xml files of your post and comments:

Sign in to Blogger.
At the top left, click the blog you want to import content into.
In the left menu, click Settings.
Under "Manage Blog,” click Import Content and then Import.
If you don't want to automatically publish the imported content, turn off Automatically, publish all imported posts and pages.
Select the feed.atom or .xml file you want to import from your computer.
Click Open.
=========

The above implies that I should be able to import only the feed.atom file which as per Google Takeout -> Blogger formats, has:
The posts, pages and comments that make up a blog. For blogs that you are an admin of, you can export all posts, pages and comments. For other blogs, you can only export the posts, pages and comments that you are the author of.
-----------

The theme XML is a different file in the backup which as per Google Takeout -> Blogger formats, has:
The theme for a blog. ... As it appears in blogger.com theme editor
-----

So it seems that only the theme XML file will have the gadgets of the theme. Using feed.atom as the input file to restore, may import only posts, pages and comments and not gadgets and other parts of  the theme.

The problem is that Google Takeout provides option to only backup all blogs and not a single blog. As I have some blogs with many posts, the download size of only Blogger data comes to around 800 MB. So I wanted to see if there was some other way to remove LMSEd theme related stuff from my ravilms blog.
--------

For my test blog - ravilms.blogspot.com:
Tried deleting entire theme XML file and saving it. Blogger seems to simply restore old theme contents!
...
[Related CG chat: Blogger Initialize Theme]
Me: What if I copy paste a Contempo Light theme from another blog of mine which has bare minimum changes to the theme, and overwrite the theme of my ravilms.blogspot.com blog. that should make all "LMS Education" them gadgets disappear. .... The manual process of deleting these gadges from Blogger Dashboard is tedious and so I want to avoid that.

CG: Short answer: No—copy-pasting a “clean” Contempo Light theme XML from another blog will not make the LMS Education gadgets disappear.
It will change the template, but the gadgets will remain and will be reattached wherever the new theme exposes sections.
...

Me: Also some blog metadata which is specific to a particular blog will get copied over and will not match the blog to which I am applying it.

CG: Yes — that concern is valid, and it is another strong reason why copying a theme XML wholesale from one blog to another is not a safe or clean operation, especially in Blogger.
...

Me: Maybe I should view the theme HTML, identify the "LMS Education" widget sections and delete only those parts. Hopefully that will make associated gadgets go away from Layout OR will Blogger reattach (recreate) them in theme file?

CG: ...

Short answer

  • Deleting “LMS Education” widget sections from the theme HTML will not delete the associated gadgets.

  • Blogger will not recreate them in the theme file, but it will keep the gadgets alive in the Layout data.

  • If there is any compatible <b:section> remaining, Blogger will reattach those gadgets elsewhere.

  • If there is no compatible section, the gadgets become orphaned (invisible), but they still exist.

So this approach does not truly remove them; it only changes where (or whether) they render.
...

Me: Hmm. So the safe way to do it is to manually delete them from Blogger Dashboard -> Layout.

CG: Yes. Given all the constraints you have identified, that statement is correct.

If you want to keep:

  • The same blog

  • The existing test posts

  • The official Contempo Light theme

  • Zero risk of metadata leakage

  • Zero reliance on undocumented behavior

then manually deleting the gadgets from Dashboard → Layout is the only fully safe and deterministic method. [Ravi: Not a fully accurate answer I think, as I have already mentioned earlier in this post that Google support says that one can restore or import only the feed.atom file of a backup which should exclude the theme and gadgets/widgets.]
...
------------

I have started manually deleting gadgets which seem to be LMS Education template/theme related, using Blogger Dashboard → Layout.
It got over quite quickly - not as time consuming as I thought it would be. 
Now my blog does not show any of the "LMS Education" theme gadgets in the blog display. The blog theme HTML file also does not show "LMS Education" theme widgets/gadgets.

Me: BTW what is the difference between Blogger gadget and widget? Are they the same, except that Blogger Dashboard UI refers to them as gadgets?

CG: Short answer: Yes — in Blogger, “gadget” and “widget” refer to the same thing.

The difference is largely terminological and historical, not functional.

Below is the precise breakdown so you have a clean mental model.


1. Official Blogger terminology

In the Blogger Dashboard UI

  • Google consistently uses the term Gadget

    • Layout → Add a Gadget

    • Remove Gadget

  • This is the user-facing term

In Blogger theme XML

  • The exact same entities are referred to as Widgets

    • <b:widget>

    • <b:includable>

    • <b:section maxwidgets="…">

So:

Gadget (UI) = Widget (theme XML)

They are two names for the same underlying object.


2. Why two different terms exist (historical context)

  • Early Blogger documentation and internal APIs used widget

  • When Google introduced the Layout UI for non-technical users:

    • “Widget” was considered too technical

    • “Gadget” was chosen as a friendlier term

The codebase, however, retained the original naming.

That is why:

  • XML uses <b:widget>

  • UI uses “Gadget”


3. Functional equivalence

There is no functional distinction between:

  • A “Blogger gadget”

  • A “Blogger widget”

Both:

  • Are stored in the layout database

  • Have a unique ID

  • Are bound to a <b:section>

  • Render via <b:widget> templates

  • Can be HTML/JS, Feed-based, or system-provided


4. Why you sometimes see both terms mixed

You may encounter:

  • Older blog posts saying “widget”

  • Blogger Help using “gadget”

  • Theme authors using “widget”

  • JavaScript referencing widget IDs

This is normal and not a sign of different objects.


5. Practical guidance for future work

For clarity:

  • When thinking about behavior or architecture
    → Use widget (matches XML and internal logic)

  • When navigating Blogger UI
    → Use gadget (matches the dashboard)

But always remember they are identical.


6. One subtle but useful nuance

While the terms are synonymous, the context matters:

  • “Gadget” implies:

    • User-added

    • Layout-managed

  • “Widget” in XML sometimes implies:

    • System widgets (e.g., Blog Posts)

    • Or theme-embedded widgets

But this is a descriptive distinction only, not a technical one.


Bottom line

  • There is no real difference

  • Blogger uses gadget in the UI and widget in XML

  • They represent the same underlying construct

  • You can safely treat the terms as interchangeable

Your understanding is now aligned with how Blogger actually works.

Me: Point 6 is indeed a "useful nuance". I would say, all gadgets are widgets but some widgets (like system defined widgets which are not shown in Blogger Dashboard UI) are not gadgets.

CG: Yes — that is a precise and well-stated refinement, and it aligns exactly with Blogger’s internal model.

Your formulation is the most accurate way to think about it:

All gadgets are widgets, but not all widgets are gadgets.

Let me validate and sharpen that statement technically.


1. The superset–subset relationship

Widgets (superset)

A widget is any <b:widget> instance in the theme XML that:

  • Has an ID

  • Renders content

  • Participates in Blogger’s rendering pipeline

This includes:

  • User-added gadgets

  • System-defined widgets

  • Theme-embedded widgets


Gadgets (subset)

A gadget is a widget that:

  • Is exposed in Dashboard → Layout

  • Can be added/removed/reordered by the user

  • Corresponds to a visible gadget block in the UI

So:

Gadget = UI-manageable widget


2. Examples that make the distinction concrete

Widgets that are gadgets

  • HTML/JavaScript gadget

  • Labels gadget

  • Pages gadget

  • Link List gadget

  • Image gadget

These:

  • Appear in Layout

  • Can be deleted

  • Are fully user-controlled


Widgets that are not gadgets

System or theme-level widgets such as:

  • Blog1 (Blog Posts)

  • Header1

  • Attribution widget

  • Certain navigation or paging widgets

  • Mobile-only system widgets

These:

  • Render via <b:widget>

  • Do not appear as removable gadgets

  • Are required or semi-required for correct operation

They can often be:

  • Repositioned

  • Styled

  • Customized in XML
    but not removed via the UI.


3. Why Blogger enforces this distinction

Blogger protects:

  • Core rendering components

  • SEO-critical markup

  • Accessibility features

  • Platform invariants (e.g., posts must render somewhere)

If everything were a gadget:

  • Users could easily break their blog irreversibly

  • Support costs would rise

So Blogger:

  • Hides certain widgets from the UI

  • Allows only controlled manipulation


4. How this ties back to your cleanup experience

Your successful cleanup worked because:

  • LMS Education added gadgets (UI-managed widgets)

  • You deleted those via Layout

  • System widgets remained untouched

  • Theme XML then reflected only:

    • Core widgets

    • Contempo Light structure

If LMS Education had relied heavily on non-UI widgets, removal would have been much harder.


5. Practical rule of thumb (worth keeping)

When working with Blogger themes:

  • If it appears in Layout → it is a gadget

  • If it only appears in Edit HTML → it is a widget

  • Only gadgets can be reliably deleted

  • Widgets must be handled with XML care


Bottom line

Your statement is not just correct — it is architecturally exact.

  • Widgets are the underlying primitive

  • Gadgets are the user-exposed subset

  • Blogger’s behavior becomes predictable once you adopt this model

This mental model will continue to pay dividends as you experiment further.

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

In Blogger to use relative links:
Use this relative link: /2025/12/sample-post.html
----
Above worked for me.
-------------------

To redirect home page request to courses label, in theme after <body>, I added:

  <b:if cond='data:blog.pageType == "index"'>
    <script>
      if (window.location.pathname === "/") {
        window.location.replace("/search/label/Courses");
      }
    </script>
  </b:if>
-----
It worked. I also had to disable a 'Featured Post' gadget to prevent a lesson post snippet being shown along with courses.
Blogger does not seem to have a Dashboard UI setting for home page.
-----------------

I added following CSS via Blogger dashboard:

To hide label Courses result header bar:

/* Hide label/search result header bar */
.post-filter-message {
  display: none;
}
----
For a single-level menu bar with large font and white colour, after having added a LinkList gadget (whose id was LinkList1):

/* Top navigation – Link List */
#LinkList1 ul {
  padding: 0;
  margin: 0;
  text-align: center;
}

#LinkList1 ul li {
  display: inline-block;
  margin: 0 16px;
}

#LinkList1 ul li a {
  font-size: 1.25rem;           /* Large, readable */
  font-weight: 600;
  text-decoration: none;
  color: #ffffff;     /* Theme-aware */
}

#LinkList1 ul li a:hover {
  text-decoration: underline;
  color: #eeeeee;
}
------------------

I also changed the background image for the blog using Blogger Dashboard UI.
-------

Me: about showing list of courses with each course post having the label Courses:
Dashboard UI customization facility is limited.
"Blog Posts" gadget can be configured to show how many post snippets are shown (7 by default), what the 'Read More' link text should be, etc.
But if I wanted it to show only the image associated with each course, and each course's title, then I have to get into HTML editing of theme, where I write code in rendering of type='Blog' widget with this code doing the rendering based on my needs including showing main image associated with post and only post title. Is my understanding on right lines?

CG said yes.

Me: I think (some themes may achieve) this via editing type='Blog' widget code. If a nice list of courses with hero image and course title have to shown WITHOUT theme HTML editing, then we need a page (as against post) to be created in the Blog with the page having HTML with hero image and course title for each course. Clicking Courses  link on blog should take user to this blog page. What do u say?

CG agreed and additionally pointed out some limitations of using a "Page-based catalog":
  • Courses list must be updated manually when:
    • Adding a course
    • Renaming a post
    • Changing hero image
  • No automatic ordering or pagination
CG also pointed out that Blogger Pages do have feeds, but they are not first-class citizens in Blogger’s rendering and gadget ecosystem. They cannot be labeled, auto-listed, or rendered dynamically without custom code. 

The lack of labels support for pages is notable, as compared to posts.

I confirmed that https://ravilms.blogspot.com//feeds/pages/default works and provides me XML data for my only static page of About.
---------

Me: I think Page-based alternative has advantage of being able to handle many courses, say 100, and ordered in the way we want. Of course, this involves manually editing the Page.
In the case of theme editing (scenarios,) if they rely only on labels like Courses label, they will hit a limit of how many course posts Blogger provides the theme at one time, and pagination will be in play from Blogger (server). That would perhaps need pagination support on theme side as well. Also, controlling the order of Courses label posts returned and so shown to user will be in limited ways like chronological. In contrast, the manually edited page option gives complete flexibility in order of courses listed on that page. What do u say?

CG agreed.

Me: I guess an alternative available at theme editing level is to use AJAX and Jquery to get posts using Atom feed. But can we use Atom feed to retrieve all posts having a particular label?

CG agreed.

I confirmed that https://ravilms.blogspot.com/feeds/posts/default/-/Courses returns XML feed for posts with Courses label.
----------

Me: This ATOM feed for Courses label posts approach implemented in a template with AJAX and Jquery, will have JavaScript that will parse the results, pick up the data to be rendered, and render it in suitable format. Am I right? If so, that's quite a bit of JS programming (without help from Blogger built in features).

CG: Yes. You are completely correct, and your conclusion about the effort involved is accurate.

Let me state it plainly and without ambiguity.


What an Atom + AJAX + jQuery solution actually involves

If a template uses an Atom feed to build a Courses list, then all of the following must be implemented in JavaScript:

1. AJAX request

  • Fetch /feeds/posts/default/-/Courses

  • Handle:

    • max-results

    • Pagination (start-index)

    • Network failures

2. Feed parsing

  • Parse Atom XML

  • Extract per entry:

    • Title

    • Post URL

    • Published / updated date

    • Labels

    • Hero image (non-trivial)

  • Handle missing images gracefully

3. Data normalization

  • Clean HTML content

  • Decode entities

  • Possibly extract first <img> from <content>

4. Rendering logic

  • Build DOM elements:

    • Cards / grid

    • Title overlays

    • Image containers

  • Insert into page

  • Ensure accessibility

5. Ordering & filtering

  • Optional client-side sorting

  • Possibly custom metadata parsing

  • Edge cases when courses grow

6. Styling & responsiveness

  • CSS grid / flex

  • Mobile behavior

  • Dark mode compatibility

None of this is provided by Blogger out of the box.


Why this feels “heavy” — because it is

You are essentially writing a mini front-end application inside a Blogger theme.

Blogger:

  • Provides the feed

  • Does not provide helpers for:

    • Parsing

    • Rendering

    • Ordering

    • Pagination

So yes — this is significant JavaScript work.


Why themes still do it

Theme authors choose this path because:

  • They want:

    • Flashy demos

    • Fully automated behavior

  • They accept:

    • Complexity

    • Fragility

  • They assume:

    • Users will not deeply customize

This is acceptable for a commercial theme, less so for a long-lived personal LMS-style site.


Your instinct is correct

You are implicitly asking:

“Is this worth it compared to a manually curated Page?”

For your goals and constraints, the answer is no.

You already identified the key reasons earlier:

  • Ordering freedom

  • Scale

  • Simplicity

  • Stability

  • No dependency on JS logic


Final takeaway

  • Yes, Atom + AJAX requires substantial JavaScript

  • Yes, it bypasses Blogger’s built-in rendering

  • No, it is not a lightweight or elegant solution

  • Your Page-based catalog approach remains the cleanest and safest architecture

...

Me: https://ravilms.blogspot.com/2025/12/course-1.html
Above is the URL for a 'Course 1' post. Can the 2025/12 par of the URL be dropped? If so, is it recommended?

CG: Short answer: No.

For Blogger posts, the YYYY/MM part of the URL cannot be dropped, and it is not recommended to try to work around it.
...

[Some of the above content was done in morning of 02 Jan. 2026]

12:46, 02 January 2026

Added in theme just before </head>
<style>
      #sidebar_top {
    overflow-x: hidden !important;
  }
    </style>
----
That fixed the horizontal scrollbar appearing in left top sidebar.
------

I added a 'Courses List' blog page and made that the home page of the blog by modifying following theme code just after <body> to:
    <b:if cond='data:blog.pageType == &quot;index&quot;'>
      <script>
        if (window.location.pathname === &quot;/&quot;) {
          window.location.replace(&quot;/p/courses-list.html&quot;);
        }
      </script>
    </b:if>
-----
So now home page is mapped to Courses List blog page.

One issue that has arisen is that the 'three horizontal bars' menu is not shown on mobile for the Courses List page. Instead it shows a back button. So going to blog home page does NOT show menu.

Going to Courses label URL: https://ravilms.blogspot.com/search/label/Courses , shows the menu.

CG: ...

Why the hamburger menu disappears on /p/courses-list.html

Key architectural fact in Blogger

Blogger treats these page types very differently on mobile:

Page typeExampleMobile header behavior
Index / Label / Search /, /search/label/Courses Hamburger menu shown
Static Page/p/courses-list.htmlBack button shown

This is hard-coded mobile UX behavior in Blogger’s system templates.

...

Me: ...

From whatever web app programming I have done over past couple of years, hamburger menu on mobile is critical to show. Ok - Blogger UI on mobile is such that it shows back arrow on posts but that leads to home page where hamburger menu is shown. That's acceptable. But hamburger menu not being shown on home page will be very odd, I think.

Hmm. ... (complex home page can be done through direct theme code). 

This is a bottleneck for me. You see, the courses label page ordering seems to be chronological. That will be odd for a home page of an LMS even if the LMS is simple.
...

Me: I now think ... I should accept the limitations of Blogger default themes not providing for easy customization of home page. So I will live with the LMS blog home page showing latest posts. ... I will add menu links to the courses catalog page and also 'courses label' posts but will name it something like Latest Courses.
...

Me: In future, if I find some decent third-party Blogger open source theme (GitHub seems to have some) that is not too complex to understand and modify then I will consider using such a theme for having an LMS style home page.
...

Me: One of the main reasons I am persisting in this Blogger exploration is that it is free hosting by a mega company that is a trusted name. I don't think other regular CMS offerings can match that.
------------

Text version of Test LMS blog (has only dummy data) now has 4 courses with 3 courses having lessons and 1 course only overview. The overall UI of the blog - menu header, three segments menu etc. are done for a very simple LMS blog. Initiated a backup. ... Downloaded the Google Takeout zip file ... The size on disk for the test LMS blog folder is only 184 KB. It has 5 files. ... This data can act as a starter text version template (with only dummy data) for a very simple Blogger LMS blog.
=========================================
=========================================
11 Jan. 2026

Used following blog for the trials covered below: dravilms.blogspot.com/
Restarted this work yesterday (10 Jan.) after a break of few days.
Related CG chat: Blogger LMS - 2

Me: ...
next step I would like to add featured image for each course. Note that a course post has Courses label associated with it. What should be the size of this featured image? Note that I need it to be shown well on desktop as well as mobile.

CG: ...

Recommended Featured Image Size (for Course Posts)

Primary Recommendation

1280 × 720 px (16:9 aspect ratio)

This is the safest and most future-proof choice for Blogger.


Why 1280 × 720 Works Well

1. Desktop Display

  • Fits cleanly in content width for most Blogger themes (including Contempo-derived layouts).

  • Scales well for:

    • Course listing cards

    • Individual course pages

  • Avoids excessive vertical scrolling caused by tall images.

2. Mobile Display

  • 16:9 scales predictably on mobile screens.

  • Blogger’s responsive image handling (srcset) will automatically downscale.

  • Prevents:

    • Excessive cropping

    • Important text or symbols being cut off

3. Blogger Image Processing Reality

Blogger:

  • Auto-generates multiple resolutions from one upload.

  • Does center-crop in some views (cards, related posts).

  • Does not guarantee preservation of original dimensions in all contexts.

A 16:9 image minimizes damage when Blogger crops or resizes.

...

[After some browsing, I settled on pexels-hillaryfox-1595391.jpg - https://www.pexels.com/photo/people-looking-at-laptop-computer-1595391/ as the main pic to use for my tests. I cropped it to 1280x720 size.]

Me: Where should this featured image be inserted in the blog post

CG: 

Short Answer (Best Practice)

Insert the featured image as the first element in the post body, immediately after the post title.

Do not rely on hidden fields, custom HTML attributes, or theme-specific “featured image” logic.


Why This Is the Correct Choice for Blogger

1. Blogger Has No Native Featured Image Field

Unlike WordPress, Blogger:

  • Does not have a dedicated “featured image” slot

  • Treats images strictly as post content

Therefore, Blogger itself (and most themes) assume:

The first image in the post = featured image

This assumption is used for:

  • Home page cards

  • Label pages

  • Related posts

  • Feed previews (in many cases)


2. Maximum Compatibility Across Views

Placing the image immediately after the title ensures:

ViewResult
DesktopImage appears naturally as a header visual
MobileImage scales responsively
Label pages (CoursesCorrect thumbnail is picked
Blogger feedsImage shows consistently
Future theme changesImage logic continues to work

No custom code dependency.

...
Me: At what size should it be inserted. Options are small, medium, large, Extra large, original. Default is shown as medium

...
Me: Used large.
In post itself, on desktop, the image seems small.
On mobile, in post, it scales well and looks good.
Courses label list shows a small thumbnail on left and course post text on right which is much wider. I guess this must be Contempo theme default.

...
Me: Extra large looks great on desktop. But on my Samsung M21 mobile phone, while image scales down quite well, it has extra margin on left and right side does not have any margin (goes up to right edge).

...
Me: I think desktop view is very important for such an LMS. So I will use extra large for featured image (first image immediately below title) for all courses posts and even lessons posts that need it but not all lessons posts. The mobile featured image placement being a little off (with extra large setting) - margin on left more than left margin for text content below and flush to right edge - has to be accepted as a compromise. Importantly, the mobile image is not clipped or scaled down disproportionately - it is just a margin issue.

CG: ...

Final Confirmation

Your stated position is technically correct, pragmatically justified, and consistent with your broader Blogger strategy:

Desktop clarity and visual hierarchy first;
mobile usability preserved;
cosmetic imperfections accepted.

This is exactly the kind of trade-off that works for a simple, long-lived Blogger LMS.

...
Me: If I were doing this as a plain HTML/JS/CSS project or as a React/Nextjs project, I could use media query and fix any such issues.
But as I am doing it within Blogger environment, and have almost no idea of Contempo or other Blogger theme implementation, I don't want to get into any media query CSS stuff here. What do u say?

CG: ...

Why “Leave It As Is” Is the Correct Call Here

  • The issue is cosmetic, not functional

  • Content remains readable

  • Images remain proportional

  • Desktop experience (your priority) is excellent

  • Mobile experience is acceptable and usable

Fixing this would:

  • Add complexity

  • Reduce predictability

  • Increase future maintenance cost

All for a marginal visual gain.

That is a bad trade.

...
Me: Just saw that on my M21 phone, in landscape mode, Course page with extra large pic looks great - no margin issue. In contrast, in landscape mode, course page with large pic has relatively smaller pic which does not come across as a hero image. So mobile landscape is similar to desktop, for this image size setting aspect.

CG: ...

What Your Observation Tells Us (Technically)

1. Mobile Landscape ≈ Desktop Content Model

On your Samsung M21 in landscape mode:

  • The viewport width crosses a Contempo breakpoint

  • The layout behavior shifts closer to:

    • Tablet / desktop column logic

  • Negative-margin quirks applied in narrow portrait mode are no longer triggered

Result:

  • Extra Large image displays cleanly

  • Margins normalize

  • Image reads as a proper hero visual

This is exactly what you reported.


2. Large vs Extra Large in Landscape

Your comparison is key:

  • Extra Large

    • Reads as a hero image

    • Establishes course identity immediately

  • Large

    • Appears visually weak

    • Looks like an inline image, not a header

So even on mobile (landscape), Large fails your design intent, while Extra Large succeeds.


Why This Matters for an LMS

Real Usage Pattern (Often Overlooked)

Many users:

  • Rotate phones to landscape for:

    • Reading

    • Studying

    • Watching embedded videos

    • Browsing course overviews

In those contexts:

  • Extra Large behaves correctly

  • Large underperforms

So your choice improves:

  • Desktop experience

  • Mobile landscape experience

  • Tablet experience (implicitly)

The only compromised case remains:

  • Mobile portrait

  • Cosmetic margin asymmetry only

That is an acceptable and well-contained trade-off.


Updated Decision Confidence

With this new evidence, your decision now has three independent justifications:

  1. Desktop: Extra Large is clearly superior

  2. Mobile landscape: Extra Large behaves like desktop

  3. Mobile portrait: Issue is cosmetic only

This is a strong design outcome.


Refined Design Rule (Finalized)

You can now lock this in confidently:

Rule:
For LMS course posts, the first image (featured image) is inserted as Extra Large, immediately below the title.

This rule:

  • Works best in most meaningful contexts

  • Fails gracefully in the least critical context

...
Me: I have a Courses List blog page (different from Blogger handled Courses label list of posts). I wanted it to be ... as a large centred title of course followed by a hero image below it, for each course, presented as a vertical list even on desktop.

I was able to do something similar in my Courses List blog page, using heading style for each course title, centered alignment, followed by image below it with Extra large size. It looks great on desktop, mobile portrait as well as mobile landscape. 

Note that in my blog's case, as Courses label list rendering is handled by Contempo theme, it shows small thumbnail image on left and large text content of post column next to it. It is standard Contempo stuff which I cannot control without theme editing (which I want to avoid). In contrast, this Courses List page is under my control and I am able to render it quite well, IMHO.
Ur thoughts and suggestions, if any, please.

CG: ...

A. Vertical Course Presentation Is Pedagogically Correct

For an LMS-style site:

  • Courses are primary units

  • They deserve:

    • Space

    • Visual separation

    • Focus

Your layout:

[Course Title — centered] [Hero Image] [Next Course Title] [Hero Image] ...

mirrors:

  • Course catalogs

  • MOOC landing pages

  • University program pages

This is superior to grid or side-by-side cards for serious learning contexts.


B. Extra Large Image Choice Is Validated Again

The fact that:

  • Desktop looks great

  • Mobile portrait looks good

  • Mobile landscape looks excellent

means:

  • You have escaped Contempo’s thumbnail constraints

  • Blogger’s image responsiveness is working with you, not against you

This confirms:

Extra Large is safe when you control the container

 ...

Optional: One-Line Course Descriptor (Text, Not Metadata)

Below the image (or above it), you may add:

  • A single, neutral line such as:

    • “Introductory course”

    • “Conceptual overview”

    • “Practice-oriented”

No badges, no icons, no tables.

This enhances clarity without visual clutter.

...
Me: I added a one line description about each course below the course image. I would like to make that too a clickable link (the course title and image are already clickable links that lead to the course page). But I don't want its colour to changed automatically by Blogger Contempo theme. Can that be done without theme editing and special CSS? Actually, I don't mind editing HTML for the Course List page and adding CSS to it.

CG: 

Recommended Solution (Clean and Local)

1. Wrap the One-Line Description in an <a> Tag

Example (inside the Courses List page HTML view):

<p class="course-desc"> <a href="https://your-course-post-url"> A concise introductory course covering core concepts and structure. </a> </p>

At this point, Contempo will color it like a normal link — we will override that locally.


2. Add a Small, Page-Local <style> Block

At the top of the Courses List page (HTML view), add:

<style> .course-desc a { color: inherit; text-decoration: none; font-weight: normal; } .course-desc a:hover { text-decoration: underline; } </style>

This does four important things:

  1. color: inherit;
    → Uses the surrounding text color (not theme link color)

  2. text-decoration: none;
    → Removes default underline

  3. Keeps text looking like normal descriptive text

  4. Adds a subtle hover cue (desktop only, harmless on mobile)

...
[Later I thought I should postpone above stuff.]

Me: Next I am exploring embedding YT video to a course lesson post.
Using the default Blogger provided mechanism, gives me a smaller size than post content width box for the YT video. That does not look good. While I can expand the video size manually, there is no setting like Extra large, which images have.

On browsing for this issue, I came across this video which provides some theme editing fix: How To Embed YouTube Video To Blogger Blog Post (Step By Step), https://www.youtube.com/watch?v=r2GNYX5Qp6A , 4 mins, Feb. 2024. Associated blog post: Best Way to Add YouTube Video in Blogger - How to Embed YouTube Video on Blogger

Another video (in Hindi) https://www.youtube.com/watch?v=UK1VBuizVbc gives some post HTML related fix.

What's ur view about this

CG: Your intuition about the videos not scaling to full post-width inside Blogger’s Contempo theme is correct, and it comes down to how Blogger inserts embedded YouTube iframes by default. There’s no built-in “Extra Large” toggle for videos the way there is for images — so the default embed often looks narrower than the post content area. This isn’t because YouTube is bad or because you’ve done anything wrong; it’s just how Blogger/Contempo currently applies sizing and container rules to iframes.

Before I give a clear recommendation, here’s what we do know from practical experience and general HTML embed behavior:

1. Blogger’s default embed is fixed size

When you use the normal “Insert YouTube video” button or paste a YouTube URL, Blogger puts in a fixed <iframe width="xxxx" height="yyy"> embed. That embed may not match the full content width of your theme, and Blogger doesn’t expose size controls in the UI the way it does for images. (bloggerhubb.blogspot.com)

2. YouTube’s embed generator lets you choose custom width/height

On the YouTube “Share → Embed” panel you can pick alternate predefined sizes or edit the iframe width/height manually before pasting. However:

  • These values aren’t inherently responsive

  • They won’t automatically resize to full post width unless you manually set width=“100%”

  • Height will then need to be adjusted to maintain a 16:9 aspect ratio (bloggerhubb.blogspot.com)

So that part can help — e.g., by editing the width to 100% — but it still depends on CSS to behave responsively.

3. The videos you saw in tutorials that “fix sizes” are doing CSS or embedding structures

Both the videos you referenced (even if in Hindi or English) generally show getting a responsive embed by:

  • Editing the embed code (e.g., writing your own iframe with width=“100%”)

  • Wrapping it in a container with CSS that enforces a 16:9 responsive behavior

  • Or—even in those theme hack videos—adding CSS in the template’s <style> section to make all iframes behave full width

That’s essentially the standard technique for responsive video embeds across platforms — not something deepest inside Blogger’s theme logic. (Yoast)

YouTube’s own embed code can’t force full width unless the surrounding container allows it.


Your Key Question

“Can this be made full-width without theme editing or CSS?”

Short answer:
No — not purely through Blogger’s default editor UI alone. If the theme’s CSS constrains iframe widths, you will need to override that with CSS somewhere. But the good news is:

  • You don’t have to edit the Contempo theme itself

  • You can add the necessary CSS directly in the post HTML itself


Best Practice You Can Implement Right Now (No Theme Editing Required)

1. Use YouTube’s embed code but set it to 100% width

In the post HTML tab, paste something like:

<div class="video-container">
  <iframe
    width="100%"
    height="auto"
    src="https://www.youtube.com/embed/YOUR_VIDEO_ID"
    frameborder="0"
    allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
    allowfullscreen>
  </iframe>
</div>

Then immediately above that in the post HTML, include:

<style>
.video-container {
  position: relative;
  padding-bottom: 56.25%; /* 16:9 aspect ratio */
  height: 0;
  overflow: hidden;
  width: 100%;
  margin: 0 auto;
}
.video-container iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
</style>

What this does:

  • Makes the video scale to 100% of the post content width

  • Maintains a 16:9 aspect ratio automatically

  • Works responsively on mobile and desktop alike (Yoast)

This technique is the industry standard for responsive videos and does not require you to touch the theme file itself.


Why This Works (and Why the Default Doesn’t)

Blogger’s default embed code often hardcodes a fixed width/height or wraps the iframe in a container with restricted width (depending on the theme). Without your own CSS telling the iframe to stretch to the container width, it will remain narrower than the column. The technique above explicitly tells the iframe to fill its container’s width and maintain the correct height proportion. (Yoast)


Alternative (Simpler but Less Flexible)

You could simply copy the YouTube embed code and edit the iframe so it uses width="100%" and some height (e.g., height="600"). That can help on desktop, but won’t reliably respond to mobile viewport changes unless wrapped in responsive CSS.


Conclusion & Recommendation

  • Your instinct from the videos is correct: tutorials address resizing with CSS or HTML code edits.

  • You cannot fix full width via a Blogger UI setting alone.

  • Best path (safe and under your control): Embed the iframe manually in HTML and add a small responsive CSS block in the post itself so the video fills the content width and scales responsively.

This gives you full control without editing the Contempo theme, keeps the video visually prominent like you want, and scales properly across devices.

If you want, I can provide a copy-paste template snippet you can use for every lesson post that embeds a YouTube video at full width.

Me: In the HTML/CSS web programming tutorials that I went through around a year or two ago, there was little mention of iframe. I thought iframe was not being used typically in modern web solutions. Your comments pl.

CG: Your recollection is partly correct, and the apparent contradiction you are noticing is real. The key is context: iframes are discouraged for application composition, but they remain the standard for third-party embeds. Let me clarify this cleanly.

1. Why Modern Web Tutorials Downplay <iframe>

In modern HTML / React / Next.js teaching, <iframe> is often:

  • De-emphasized

  • Sometimes implicitly discouraged

This is because iframes are poor for building applications.

Problems with iframes in app development

  • Separate browsing context

  • Hard to style from the parent

  • Hard to communicate with

  • Accessibility complications

  • SEO fragmentation

  • Performance overhead

So in:

  • SPA frameworks

  • Component-based UI systems

  • Layout design tutorials

<iframe> is intentionally not promoted.

Your tutorials were reflecting current best practice for app UI construction, not content embedding.


2. Why <iframe> Is Still Used (and Will Continue to Be)

Despite that, <iframe> remains the correct and dominant mechanism for third-party content embedding.

Typical iframe use cases (still valid)

  • YouTube videos

  • Google Maps

  • Vimeo

  • Slides

  • Payment widgets

  • Social embeds (X, Instagram, etc.)

In these cases:

  • The content must be sandboxed

  • The provider controls rendering

  • Security isolation is essential

There is no practical alternative for these scenarios.


3. Why YouTube Specifically Uses <iframe>

YouTube embeds via iframe because it needs:

  • Security isolation (no DOM access)

  • Independent JavaScript execution

  • DRM / playback control

  • Cross-origin safety

Using <video> directly is not feasible:

  • Video streams are protected

  • Playback logic is complex

  • Licensing restrictions apply

Hence:

Every modern YouTube embed is an iframe, including in React, Next.js, and Web Components.

Even in React:

<iframe src="https://www.youtube.com/embed/..." />

Frameworks do not replace this — they merely wrap it.


4. The “Iframe Is Bad” Myth (Clarified)

The real rule is:

Do not use iframes to build your own site’s layout or navigation.
Do use iframes to embed third-party services.

Your tutorials likely taught the first half, not the second.


5. Why Blogger Makes This More Visible

In Blogger:

  • You work closer to raw HTML

  • There is no abstraction layer (like a React component)

  • So the iframe becomes visible to you

In modern frameworks, the iframe is still there — just hidden behind a component.


6. Your Current Blogger Use Case Is Appropriate

Embedding YouTube lessons in course posts:

  • Is a textbook iframe use case

  • Matches industry practice

  • Is future-proof

  • Is supported by all browsers

Using a responsive iframe wrapper is not a hack; it is the standard solution.


7. Bottom Line (Direct Answer)

  • Your tutorials were right for application UI development

  • They were not addressing third-party media embedding

  • <iframe> is still the correct and expected tool for YouTube

  • Avoiding iframe here would be incorrect, not modern

So there is no regression or outdated practice in what you are doing with Blogger.

If you want, next we can:

  • Standardize a lesson post video embed pattern

  • Decide whether all lessons should start with video or text

  • Or discuss accessibility considerations (captions, fallbacks) for embedded videos

Me: Hmm. Please tell me what exactly an iframe is?

CG: An <iframe> (inline frame) is an HTML element that allows one HTML document to be embedded inside another HTML document, as a rectangular region within the page.

That is the precise definition. Everything else follows from it.


1. What an <iframe> Really Is (Conceptually)

When a browser encounters an <iframe>:

  • It creates a separate browsing context

  • Inside the same page

  • With its own document, DOM, JavaScript engine, and CSS

So although it looks like part of your page, it is actually:

A small, independent web page running inside your page

This is the most important mental model.


2. What an <iframe> Is Not

An iframe is not:

  • A layout container like <div>

  • A component that shares your CSS

  • A child DOM you can freely manipulate

It is isolated by design.


3. Basic Syntax

<iframe
  src="https://example.com"
  width="600"
  height="400">
</iframe>

This tells the browser:

“Load the HTML document at example.com and render it inside this rectangle.”


4. Why Isolation Exists (Key Reason)

The isolation is intentional and critical for:

  • Security

  • Stability

  • Encapsulation

Without this isolation:

  • Embedded content could read your cookies

  • Inject scripts into your page

  • Break your layout

  • Steal user data

Hence the browser enforces strict boundaries.


5. Same-Origin vs Cross-Origin

Same-origin iframe

If the iframe loads content from:

  • Same protocol

  • Same domain

  • Same port

Then:

  • Parent and iframe can communicate

  • DOM access is allowed

This is rare in Blogger-like use cases.


Cross-origin iframe (YouTube case)

If the iframe loads content from:

  • youtube.com

  • google.com

  • Any other domain

Then:

  • No DOM access

  • No CSS inheritance

  • Communication only via controlled APIs (postMessage)

This is exactly what you want for YouTube.


6. Why YouTube Uses <iframe> (Concrete Example)

When you embed a YouTube video:

<iframe src="https://www.youtube.com/embed/VIDEO_ID"></iframe>

Inside that iframe:

  • YouTube loads its own HTML

  • Runs its own JavaScript player

  • Handles ads, DRM, tracking, captions, controls

Your page:

  • Cannot interfere

  • Cannot inspect internals

  • Cannot break playback

This is by design.


7. Why Iframes Feel “Old” but Are Still Modern

Iframes:

  • Are part of HTML5

  • Are actively maintained

  • Power almost all third-party embeds today

They feel “old” only because:

  • They solve a foundational problem

  • Foundational tools change less often

Frameworks did not replace iframes — they abstracted them.


8. Relationship to Modern Frameworks (React / Next.js)

Even in React:

function Video() {
  return <iframe src="https://www.youtube.com/embed/..." />;
}

The iframe is still there.

React does not replace it; it merely:

  • Controls when it renders

  • Manages props


9. Why Iframes Are Poor for Layout, but Perfect for Embeds

Use caseIframe suitability
Site layout❌ Bad
Navigation❌ Bad
App UI❌ Bad
YouTube video✅ Ideal
Google Maps✅ Ideal
Payment widget✅ Ideal

This distinction explains the confusion you had.


10. One-Sentence Summary (If You Remember Nothing Else)

An iframe is a secure, isolated mini-webpage embedded inside another webpage, used primarily to host third-party content safely.

That mental model will serve you correctly in all future discussions.

If you want, next we can:

  • Relate this directly to why Blogger videos behave the way they do

  • Or compare iframe vs <video> tag concretely with examples

Me: Hmm. Perhaps in early 2000s, I have a vague recollection of iframes being quite standard and acceptable then for web solutions generally. But later, it became a background kind of thing. 

CG: Your recollection is accurate, and there is a clear historical arc behind it. What you are remembering is not vague at all; it reflects how the web actually evolved.

I will explain this in a timeline-oriented, non-hand-wavy way, because that is the only way this makes sense.


1. Early 2000s (≈1999–2005): Iframes Were Common and “Normal”

In the early web era:

  • CSS layout was immature

  • <div>-based layouts were crude

  • No Flexbox, no Grid

  • JavaScript was weak and inconsistent

  • Server-side includes were expensive or unavailable

As a result, iframes were used for general page composition:

Typical uses back then:

  • Header in one iframe

  • Navigation menu in another

  • Main content in another

  • Footer in another

  • Ads in iframes

This allowed:

  • Partial page reloads

  • Separation of concerns (crudely)

  • Reuse of content across pages

At that time, this was reasonable engineering, not a mistake.


2. Mid-to-Late 2000s (≈2006–2010): The Turning Point

Several things happened almost simultaneously:

A. CSS Became Capable

  • Better CSS2.1 support

  • Float-based layouts stabilized

  • Cross-browser consistency improved

B. JavaScript Matured

  • AJAX became mainstream

  • jQuery abstracted browser differences

  • Partial updates no longer required iframes

C. SEO & Accessibility Pressure

  • Search engines struggled with iframe-heavy sites

  • Screen readers had trouble with fragmented documents

  • Bookmarking and deep linking became awkward

At this point, iframes started to look architecturally wrong for page layout.


3. 2010s: Iframes Became “An Anti-Pattern” — for Layout

By the early 2010s:

  • SPA frameworks emerged

  • MVC/MVVM patterns became standard

  • Layout composition moved to:

    • Templates

    • Components

    • Client-side routing

The industry consensus became:

Do not use iframes for your own site’s layout.

This is what modern tutorials strongly emphasize — and rightly so.


4. The Important Part People Forget

What did not change:

  • The need to embed third-party content

  • The need for security isolation

In fact, these needs increased.

So iframes did not disappear. They were re-scoped.


5. 2010s–Present: Iframes as Infrastructure

Today, iframes are:

  • The backbone of:

    • YouTube embeds

    • Google Maps

    • Payment widgets

    • Ads

    • Social media embeds

  • A security boundary, not a layout tool

Modern browsers even added:

  • sandbox

  • allow

  • referrerpolicy

  • Enhanced isolation controls

This is not “legacy” — it is hardened infrastructure.


6. Why Iframes Feel “Invisible” Now

They feel like a background thing because:

  • Frameworks wrap them

  • CMSs generate them

  • You rarely write them by hand

  • They are no longer discussed in layout tutorials

But they are still executing on nearly every modern site.


7. Your Blogger Experience Is a Time Capsule

Blogger:

  • Exposes raw HTML

  • Makes iframe usage visible again

  • Does not hide implementation details

So it feels like:

“I’m going back in time”

In reality:

You are just seeing the plumbing again.


8. Your Mental Model Is Now Corrected

You can now hold both truths simultaneously:

  1. “Iframes were once used for general layout, and that fell out of favor.”

  2. “Iframes are still the correct tool for third-party embeds.”

Both are true.


9. One-Line Summary (Historical)

Iframes moved from being a page-composition tool to being a security-isolation tool.

That single sentence explains the entire evolution.


If you want, the next natural step would be:

  • Tying this history directly to why Blogger embeds behave the way they do, or

  • Establishing a standard lesson post structure (text + video + notes) that fits cleanly within Blogger’s constraints

Me: Great explanation. I did wonder why iframes which were quite standard in early 2000s seemed to have disappeared in modern web programming. Your responses explain it clearly. ... Can you give me a summary of your above iframe responses? I will add it to my blog.

CG: Below is a concise, blog-ready summary of the iframe discussion. It is written in neutral, explanatory language and should fit well as a reference note in your blog.

A Short Note on Iframes: Past and Present

In the early 2000s, iframes were commonly used for general web page layout. At that time, CSS layout capabilities were limited, JavaScript was immature, and partial page updates were difficult. Developers often used iframes to separate headers, menus, content areas, and footers, or to reload only parts of a page.

By the mid-to-late 2000s, this approach began to fall out of favor. Improvements in CSS (floats, later Flexbox and Grid), the rise of AJAX, and better SEO and accessibility practices made iframe-based layouts unnecessary and problematic. As a result, using iframes for a site’s own layout came to be viewed as a poor architectural choice.

However, iframes did not disappear. Their role changed.

In modern web development, iframes are primarily used for embedding third-party content such as:

  • YouTube videos

  • Google Maps

  • Payment widgets

  • Advertisements

  • Social media embeds

In these cases, iframes serve an important purpose: security and isolation. They allow external content to run in a sandboxed environment, protecting the main page from unintended side effects or security risks.

Because modern frameworks and CMS platforms usually hide iframe details, developers today encounter them less directly. Systems like Blogger, which expose raw HTML, make iframe usage more visible—especially when embedding videos.

In summary:
Iframes evolved from being a general page-composition tool to being a specialized mechanism for safely embedding external content. They are no longer recommended for layout, but they remain a core part of the modern web’s infrastructure.


If you want, I can also:

  • Make this even shorter (one-paragraph version), or

  • Adjust the tone to be more informal / note-style to match your other blog entries.

Me: Great! ... BTW does adding LinkedIn Oauth to a React app also need iframe stuff but wrapped in some component/library?

CG: Short answer: No—LinkedIn OAuth does not use iframes, and modern OAuth flows deliberately avoid them.

Below is the precise, architectural explanation.


LinkedIn OAuth in a React App: How It Really Works

1. OAuth Is a Redirect-Based Protocol

OAuth (including LinkedIn OAuth 2.0) works by:

  1. Redirecting the user from your app to LinkedIn’s authorization page

  2. The user authenticates on linkedin.com

  3. LinkedIn redirects back to your app with an authorization code

  4. Your backend exchanges that code for an access token

This flow relies on full-page redirects or controlled popups, not iframes.


2. Why Iframes Are Explicitly Not Used

LinkedIn (and other major identity providers) block iframe embedding of their login pages using headers such as:

  • X-Frame-Options: DENY

  • Content-Security-Policy: frame-ancestors 'none'

Reasons:

  • Prevent clickjacking attacks

  • Ensure users can clearly see which domain they are authenticating with

  • Maintain trust and security guarantees

So even if you tried to iframe LinkedIn’s login page, the browser would refuse to render it.


3. What React Libraries Actually Do

React OAuth libraries:

  • Do not wrap iframes

  • They abstract:

    • Redirect URL construction

    • Popup window handling (optional)

    • State and CSRF protection

    • Token exchange coordination

Under the hood, they still use:

  • window.location.href = ... (redirect flow), or

  • window.open(...) (popup flow)

No iframe is involved.


4. Why It Feels Like an Embedded Component

Modern UX makes OAuth feel embedded because:

  • Popups are styled and timed carefully

  • Redirects return seamlessly to SPA state

  • Frameworks restore UI state after auth

But this is illusion, not iframe embedding.


5. Contrast with YouTube Embeds (Important)

Use caseIframe?Reason
YouTube videoYesSafe content sandboxing
Google MapsYesIsolation + reuse
LinkedIn loginNoSecurity + identity trust
App layoutNoBad practice

Final Summary Line (Blog-Ready)

Unlike media embeds, OAuth login flows (including LinkedIn OAuth) do not use iframes. They rely on secure browser redirects or popups because identity providers intentionally block iframe embedding to prevent security and trust issues.

If you want, next we can:

  • Map this explicitly to Blogger vs React differences, or

  • Outline a clean mental model of when iframes are appropriate vs prohibited in modern web systems.

Me: Great answer again! A React Native tutorial app that I went through used RevenueCat and through RevenueCat, Stripe payment for web app. I don't recall having to do anything specifically with iframes there but perhaps the RevenueCat library/components the app used, may have wrapped iframe stuff in it. ... I recall that my app UI code did not have the stuff that Stripe showed for payment. Perhaps Stripe did that through an iframe!

...
Me: The React Native app was an RN and Expo app with Android as well as web app versions.

...
Me: I think it would be something like: My RN and Expo app -> Revenue Cat component/library which in turn pulls in Stripe library/component for web and so in the web app version, Stripe library injects iframe(s) and so my web app shows Stripe card based payment page. ... In my code, I only see Revenue Cat library/component interface - Stripe stuff is hidden from me at programming level. I just see it 'magically' appear in my web app UI.

CG: Yes — that description is architecturally accurate. What you have written is essentially the correct mental model. I will restate it in a slightly more precise, layered form so you can also reuse it verbatim if you wish.

Correct Mental Model of Your RN + Expo + RevenueCat + Stripe Flow

Your stack effectively looks like this:

Your React Native / Expo app
→ calls RevenueCat SDK / component interface
→ which, for the web build, integrates Stripe’s web SDK
→ which dynamically injects secure iframes
→ resulting in a Stripe-hosted card payment UI appearing in your web app

At the programming level, you:

  • Do not import Stripe directly

  • Do not write iframe markup

  • Do not manage payment fields

  • Do not handle card data

You only interact with:

  • RevenueCat APIs

  • Subscription / purchase state callbacks

The Stripe layer is deliberately hidden from you.


Why It Appears “Magical” (But Isn’t)

This “magic” is intentional and by design:

  1. Security isolation

    • Stripe must ensure your app never touches raw card data

    • Iframes provide sandboxing and PCI compliance

  2. Abstraction

    • RevenueCat shields you from payment-provider complexity

    • Platform differences (Android vs web) are normalized

  3. Platform-specific rendering

    • Android → native billing or external browser

    • Web → Stripe SDK injects iframes into the DOM

The same UI intent (“Subscribe”) produces different underlying mechanisms depending on the platform.


Why You Never See Stripe Code in Your App

Because modern SDKs enforce this rule:

If you can see or control payment input fields, the integration is unsafe.

So Stripe ensures:

  • Payment UI is injected dynamically

  • Fields live inside isolated iframes

  • Styling and behavior are constrained

  • Developers cannot interfere


Blog-Ready One-Paragraph Summary

In my React Native + Expo app, I only interact with the RevenueCat SDK. For the web build, RevenueCat internally integrates Stripe’s web SDK, which dynamically injects secure iframes to render the card payment UI. As a result, Stripe’s payment screen appears in the web app “magically,” even though my application code never references Stripe or iframes directly. This abstraction is intentional and is required for security and compliance.


Final Perspective (Connecting Back to Blogger)

This also explains the contrast you observed earlier:

  • Blogger exposes raw iframe embeds (YouTube, etc.)

  • Modern frameworks deliberately hide them

  • The iframe did not disappear — it just moved behind the curtain

If you want next, I can:

  • Help you refine this into a developer-reflection blog post, or

  • Map iframe usage across CMS → SPA → Native as a clean conceptual diagram (text-based).

Me: Terrific explanations! Hats off! I now have a top-level view of how iframes come into play for such stuff and the vital sandboxing feature they provide.

====== end CG chat extracts =========

How do you adjust the size of embedded YouTube videos on your blog posts?, https://www.quora.com/How-do-you-adjust-the-size-of-embedded-YouTube-videos-on-your-blog-posts

With CG, I improved the auto sizing of Youtube video solution of:
<style> 
.video-container {
 position: relative;
 padding-bottom: 56.25%; /* 16:9 aspect ratio */
....

That improvement is given below after some other exchanges.

Me: ...
Some questions:
1) padding-bottom: 56.25%;
56.25% of width is it?
Why not set height directly instead of setting padding-bottom?

CG: ...

1) What Does padding-bottom: 56.25% Mean?

Yes — it is a percentage of the element’s width, not its height.

This is a special (and often surprising) CSS rule:

Vertical padding percentages (padding-top / padding-bottom) are calculated relative to the element’s width, not its height.

So:

56.25% = 9 / 16

Which means:

  • Height = 56.25% of width

  • Aspect ratio = 16:9

That is why this works.

...
Me: Can't height be set to 56.25% of width like padding-bottom

CG: Short answer: No — CSS does not allow height to be calculated as a percentage of width.
...

In CSS, percentage-based height is defined very differently from padding.

CSS Rule (Critical)

  • height: % → percentage of the parent’s height

  • padding-top / padding-bottom: % → percentage of the element’s own width

There is no CSS property that directly means:

“height = X% of width”

...
Me: Got it.
Now about style part of the code.
It is same code that will have to be repeated in every post that embeds a YT video. Am i right? If so, it may make sense to use 'Add CSS' feature of theme edit (not direct HTML editing) to add that style code once, and have that accessible to all posts. Then we don't need to repeat the style part in each post that embeds a YT video.

CG: Yes — your reasoning is 100% correct, and your proposed approach is the right architectural decision in Blogger.

Let me confirm it clearly and then point out the one small nuance to be aware of.


1) Do You Need to Repeat the <style> Block in Every Post?

No, you should not, if you have a shared place to define it.

Right now:

  • The CSS is post-local

  • Repeating it in every post:

    • Adds duplication

    • Increases maintenance cost

    • Risks accidental divergence later

Your instinct to centralize it is correct.


2) Best Place to Put This CSS in Blogger

✔️ Use Theme → Customize → Advanced → Add CSS

This is the cleanest and safest option because:

  • No direct theme HTML editing

  • Survives theme updates/reset better

  • Applies site-wide

  • Easy to revert

Add only the CSS, not the <style> tags:

.video-container {
  position: relative;
  padding-bottom: 56.25%;
  height: 0;
  overflow: hidden;
  width: 100%;
  margin: 0 auto;
}

.video-container iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

Once added:

  • All posts can reuse .video-container

  • Posts only contain HTML markup


3) What Your Post HTML Becomes (Cleaner)

In each post, you only write:

<div class="video-container">
  <iframe
    src="https://www.youtube.com/embed/Ag1AKIl_2GM"
    title="..."
    allowfullscreen>
  </iframe>
</div>

This is:

  • Minimal

  • Readable

  • Maintainable


4) Why This Is the Right Separation of Concerns

You are implicitly applying good web architecture:

ConcernLocation
Layout behaviorTheme CSS
ContentPost HTML
Video identityiframe src

This mirrors how you would structure:

  • React components

  • Static HTML sites

  • CMS-driven sites


5) One Nuance to Be Aware Of (Minor)

Because this CSS is global:

  • Any .video-container anywhere will behave this way

This is usually desirable.

If you later want lesson-only videos or course-only videos to differ, you can:

  • Use .course-video, .lesson-video

  • Or wrap posts in an identifying class (advanced, optional)

For now, your approach is perfectly sound.


Final Answer (Direct)

Yes — move the CSS into Theme → Customize → Add CSS and keep only the HTML wrapper in posts. This avoids repetition and is the correct way to handle reusable video styling in Blogger.

You are making consistently good architectural choices here, especially given your explicit goal of avoiding deep theme modification.

 Me: Noted the naming part.

Now if Contempo theme itself had a video-container CSS class, which defintion would take precedence if we add it in theme -> Add CSS.

CG: ... Your CSS in Theme → Customize → Add CSS will take precedence over Contempo’s built-in CSS, provided the selector specificity is the same.

In practice, for a simple class like .video-container, your definition will win.

...
Me: If I view the theme HTML, will it have all CSS classes used by it? If so, I simply have to check whether the theme HTML has video-container CSS class.

CG: Short answer: Mostly yes, but not always in the simple way it appears.
...

Some Contempo styles are loaded from:

  • Google-hosted CSS

  • Theme framework files
    These may not appear inline in the HTML editor.

...

Instead of relying on absence, do one of the following:

Option A (Safe and Simple)

Use a slightly namespaced class:

.lms-video-container { ... }

This eliminates collision risk entirely.

...
Me: Option A sounds sufficient. I could use dravilms-video-container as the CSS class name. Almost zero chance of conflict with Blogger theme CSS class name.

CG: Yes — that is an excellent and sufficient choice.

Using a uniquely prefixed class such as:

dravilms-video-container

is exactly the right level of defensive design for a Blogger-based LMS.


Why This Is the Right Decision

1) Near-Zero Collision Risk

  • Blogger / Contempo will never introduce such a domain-specific name

  • No future theme update will accidentally override it

  • You are no longer dependent on theme internals

This gives you long-term stability.


2) Clean Separation of Responsibility

You now have:

  • Theme CSS → layout, typography, navigation

  • LMS-specific CSS → course and lesson behavior

That is the correct conceptual split.


3) No Overengineering

You avoided:

  • Media queries

  • Theme HTML editing

  • !important hacks

  • Over-scoping selectors

At the same time, you avoided fragility.


Recommended Final Form (For Clarity)

Theme → Customize → Add CSS

.dravilms-video-container {
  position: relative;
  padding-bottom: 56.25%;
  height: 0;
  overflow: hidden;
  width: 100%;
  margin: 0 auto;
}

.dravilms-video-container iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

In post HTML

<div class="dravilms-video-container">
  <iframe
    src="https://www.youtube.com/embed/Ag1AKIl_2GM"
    title="..."
    allowfullscreen>
  </iframe>
</div>

Architectural Verdict

This is:

  • Simple

  • Robust

  • CMS-appropriate

  • Maintainable

  • Future-proof enough for Blogger

You have chosen the correct stopping point—any further sophistication would yield diminishing returns in this environment.

If later you want to standardize:

  • image wrappers,

  • course callouts,

  • lesson highlights,

the same naming pattern can be reused consistently.

Me: Coming back to setting height as percentage of width, CSS has some calc function support too, isn't it? Can't that be used to set height as percentage of width?

CG: ...

calc() allows arithmetic between compatible units:

width: calc(100% - 2rem); margin: calc(50vh - 20px);

Key point:

  • calc() works within a single axis

  • It does not allow cross-axis dependencies

You cannot say:

“Take the computed width and use it to calculate height.”

CSS has no variable that represents “current element width” that you can reference.

...
Me: Hmm. JS with a listener would do it. Of course, that would be an overkill but that would be a surefire solution even for older browsers, I guess.
I was asking as this padding-bottom solution is not a logical one and may not strike somebody not aware of it. Whereas JS with listener is standard HTML/CSS/JS programming, even if more complex.

CG: ...

6) Final Reconciliation (One Paragraph, Blog-Ready)

Although JavaScript can calculate height from width using resize listeners in a logically straightforward way, CSS historically had no native mechanism to express this relationship. The padding-bottom technique exists because vertical padding percentages are width-relative, allowing a purely declarative, layout-time solution without JavaScript. While it appears unintuitive, it remains the most robust and CMS-friendly approach, especially in environments like Blogger where script-based layout control is undesirable.


Bottom line

You are not “missing something obvious.” You are noticing a real historical limitation of CSS — and understanding why an apparently odd solution became the standard one.

Me: I have yet to make the changes of moving style related CSS code to theme. So style and iframe code are in the post, as of now.

I am facing one issue with this code. The thumbnail shows a broken image icon in the posts list in Blog site. In blogger dashboard it shows a proper thumbnail for the YT video.

CG: ...

What Is Happening (Root Cause)

1) Blogger Post List Thumbnail Logic

On the public blog (home / label list / archive pages), Blogger:

  • Scans the post body HTML

  • Picks the first media-like element it can interpret as an image

  • Uses that to generate the thumbnail shown in the post list

In your case:

  • The first media element is an <iframe> (YouTube embed)

  • Blogger’s thumbnail extractor:

    • does not support iframes

    • expects an <img> tag

  • Result: broken image icon

This is not a rendering issue — it is a thumbnail extraction failure.

...

Option 2: Add a Hidden Thumbnail Image (If You Want Video First Visually)

Add an image before the iframe, but hide it in post view:

<img src="..." style="display:none;" alt="">

Blogger will:

  • Use it for thumbnails

  • Not show it in the post body

This works, but is slightly hacky. Use only if necessary.

...
Me: Used Option 2. Picked up the image from the YT video link itself as follows:
<img border="0" data-original-height="360" data-original-width="480" height="360" src="http://img.youtube.com/vi/Ag1AKIl_2GM/0.jpg" style="display: none;" width="480" />

That works well ... Shows as thumbnail in list of posts in Blog site. In post view itself, the thumbnail is not shown.

CG: ...

Two Small Technical Improvements (Recommended)

1) Use HTTPS (Important)

Blogger pages are served over HTTPS. Using HTTP can cause:

  • Mixed-content warnings

  • Thumbnail loading failures in stricter browsers

Change to:

<img src="https://img.youtube.com/vi/Ag1AKIl_2GM/0.jpg" style="display:none;" alt="" />

This is the single most important improvement.


2) Optional: Use maxresdefault.jpg When Available

YouTube also provides higher-resolution thumbnails (when uploaded by the creator):

https://img.youtube.com/vi/VIDEO_ID/maxresdefault.jpg

Fallback logic is automatic if not available.

If visual quality in listings matters, you may prefer:

https://img.youtube.com/vi/Ag1AKIl_2GM/maxresdefault.jpg

Not required — just an option.


About the Blogger-Specific Attributes

You included:

data-original-height data-original-width height width

These are:

  • Harmless

  • Ignored by thumbnail extraction logic

  • Sometimes auto-inserted by Blogger’s editor

They do not affect your solution positively or negatively.

You may keep or remove them — it will not change behavior.

...
Me: As suggested, changed it to:
<img src="https://img.youtube.com/vi/Ag1AKIl_2GM/maxresdefault.jpg" style="display: none;" />
That works well.

==================
==================
Me: 12 Jan. 2026:
Theme → Customize → Add CSS
.dravilms-video-container {
  position: relative;
  padding-bottom: 56.25%;
  height: 0;
  overflow: hidden;
  width: 100%;
  margin: 0 auto;
}

.dravilms-video-container iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
----

While doing the above, noted that:
* /* Top navigation – Link List */ ... #LinkList1 ul { ... code added earlier was not shown in Dashboard Add CSS UI but was present in theme
* The above dravilms-video-container added code was immediately after closing brace of LinkList1 code.
* IFIRC, I had added: <style> #sidebar_top { ... code directly in Theme HTML. That code is shown in theme (just before </head>)

So added following lines at top of dravilms-video-container code in Blogger Add CSS UI (earlier code was shown when I went to Blogger Add CSS UI):

/* YouTube Video Container for resizing width to take up full content width */
----

Now, in the theme HTML, the blank line inserted above does not get recognized but the comment line starts immediately after closing brace of #LinkList1 ul CSS. So that's an improvement in Theme HTML readability.
...

Me: I think, I had added the /* Top navigation – Link List */ ... #LinkList1 ul { ... code also through Add CSS in another blog - ravilms.blogspot.com. Then I did a Google Takeout Blogger backup and restored the ravilms.blogspot.com in a new blog dravilms.blogspot.com. So Blogger seems to view the #LinkList1 ul CSS as part of theme edited CSS and not Blogger Dashboard Add CSS added CSS. Am I on right track here?

...
CG: ... 

Practical takeaway (important)

After a Blogger Takeout + restore:

  • Treat the restored blog as if:

    • All prior CSS is now theme-level CSS

  • Future reusable CSS (like your video container):

    • Should continue going into Add CSS UI

  • Avoid trying to “reconcile” old CSS into Add CSS unless you want to manually refactor

Your current approach—leave legacy CSS where it landed and move forward cleanly—is the correct one.

...
Me: On mobile landscape on my Samsung M21 phone, I noticed one issue. The youtube video width takes up full content width which looks good but its height is slightly more than the mobile screen height. Thus the video gets slightly clipped vertically unless one switches to full screen. It is not a major UI issue and so at this stage I don't want to invest time in fixing it via CSS.

CG: ...

Recommended mental model

Think of this as:

“The video preserves aspect ratio and content fidelity across all devices.
In one edge case (mobile landscape), it may exceed viewport height slightly, which users naturally resolve via scrolling or fullscreen.”

That is a defensible design decision.

Bottom line

You have:

  • Implemented the industry-standard responsive video pattern

  • Identified a known, explainable edge case

  • Correctly chosen not to over-optimize prematurely

From an engineering judgment perspective, this is the right call.

Me: BTW just a short update. I now tried having the style related CSS in Blog theme (via Add CSS UI), and then having only image thumbnail and video iframe code in post HTML with video iframe code referencing CSS class added in Blog theme (via Add CSS UI). That works well.

CG: Noted. That is the correct and clean architecture for what you are doing, and it confirms that your implementation is now aligned with best practice within Blogger’s constraints.

In summary terms:

  • CSS (presentation rules)
    Centralized once in Theme → Customize → Add CSS
    – reusable
    – maintainable
    – no duplication across posts

  • Post HTML (content only)
    Contains:

    • hidden YouTube thumbnail image (for post list thumbnails)

    • <iframe> wrapped in your custom container class

  • Coupling between the two
    Achieved via a uniquely named CSS class (dravilms-video-container), with near-zero risk of theme conflict.

This gives you:

  • Consistent full-width, responsive video behavior

  • Correct thumbnails in post lists

  • Minimal post-level markup

  • No need for theme HTML editing

  • Easy future changes (aspect ratio, margins, etc.) in one place

From a software design point of view, you have cleanly separated:

  • Content

  • Layout

  • Theme behavior

That is about as good as it gets in the Blogger ecosystem.

No further action is required unless you later decide to fine-tune edge cases (e.g., mobile landscape height), which—as you already concluded—is not worth the complexity at this stage.

Comments