Wednesday, September 2, 2026

Nostalgic television

This fully functional little television gadget is my most recent pride and joy. You can flip through different “channels”, play and pause videos, and even turn it on and off! Each channel can contain a YouTube video of your choice, or you can have the version where you upload your own videos. I love it, I love it, I love it! But enough about me. You’re here for the tutorial, so let’s get right into it.

1️⃣ First, go to Blogger → Layout → Add a Gadget → HTML/JavaScript and paste the HTML + CSS code below into the gadget:

<div class="television-gadget">

  <div class="television-gadget-screen">

    <div class="television-gadget-player"></div>

    <div class="television-gadget-pause-overlay">

      <div class="television-gadget-channel-info">
        <span class="television-gadget-channel">CH 01</span>
        <span class="television-gadget-network">CHANNEL ONE</span>
      </div>

    </div>

    <button
      class="television-gadget-screen-button"
      type="button"
      aria-label="Play or pause video">
    </button>

    <button
      class="television-gadget-screen-prev"
      type="button"
      aria-label="Previous channel">‹</button>

    <button
      class="television-gadget-screen-next"
      type="button"
      aria-label="Next channel">›</button>

  </div>

  <img
    class="television-gadget-frame"
    src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEii5qwFfhC8Oo6mX-UYsPimPG2XBcxJw4qf5SVDSK07wQjBEbwZpt0AlP-F15AGuI4VPUpE1dWvfKEAFiWsWeAhVgFUu2TwW5SsHjoEEfP1juVrP1CVC0CCiAv_oVkHKoP8KCGQBUlrBKgP28cfotuZV0JGL_VLbXZKIt_7e5Chch4-FYV7_ZcAmYpMV8o/s1600/cinderella%20television.png"
    alt="Television">


  <button
    class="television-gadget-power-button"
    type="button"
    aria-label="Turn television on or off">
  </button>

  <button
    class="television-gadget-heart-button"
    type="button"
    aria-label="Play or pause video">
  </button>

</div>


<style>

/* ================================= */
/*        TELEVISION GADGET          */
/* ================================= */

.television-gadget {
  position: relative;
  width: 300px;
  max-width: 100%;
  aspect-ratio: 1 / 1;
  margin: 0 auto;
  left: 0;
}


/* ================================= */
/*             SCREEN                */
/* ================================= */

.television-gadget-screen {
  position: absolute;
  left: 24.6%;
  top: 30.6%;
  width: 50.6%;
  height: 38.4%;
  overflow: hidden;
  background: #000;
  border-radius: 7% 7% 9% 9% / 8% 8% 10% 10%;
  z-index: 1;
}


/* ================================= */
/*         YOUTUBE PLAYER            */
/* ================================= */

.television-gadget-player {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  background: #000;
}


.television-gadget-player,
.television-gadget-screen > iframe,
.television-gadget-screen iframe[id^="television-gadget-player-"] {
  position: absolute !important;
  left: 0 !important;
  top: 0 !important;
  width: 100% !important;
  height: 100% !important;
  margin: 0 !important;
  padding: 0 !important;
  border: 0 !important;
  display: block !important;
  background: #000;
  pointer-events: none;
}


/* ================================= */
/*         CRT PAUSE OVERLAY         */
/* ================================= */

.television-gadget-pause-overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    radial-gradient(
      ellipse at center,
      rgba(255,255,255,0) 48%,
      rgba(0,0,0,0.18) 75%,
      rgba(0,0,0,0.38) 100%
    );

}


.television-gadget-pause-overlay::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    repeating-linear-gradient(
      to bottom,
      rgba(255,255,255,0.025) 0px,
      rgba(255,255,255,0.025) 1px,
      rgba(0,0,0,0.08) 2px,
      rgba(0,0,0,0.08) 3px
    );
  pointer-events: none;
}


.television-gadget-pause-overlay::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    rgba(255,255,255,0.025);
  pointer-events: none;
}


.television-gadget-pause-overlay.is-hidden {
  display: none;
}



/* ================================= */
/*          CHANNEL TEXT             */
/* ================================= */

.television-gadget-channel-info {
  position: absolute;
  top: 10%;
  left: 8%;
  z-index: 2;
  color: white;
  font-family: Arial, sans-serif;
  text-shadow:
    0 1px 2px rgba(0,0,0,0.9);
}


.television-gadget-channel {
  display: block;
  font-size: 11px;
  font-weight: bold;
  line-height: 1.1;
}


.television-gadget-network {
  display: block;
  margin-top: 2px;
  font-size: 8px;
  font-weight: bold;
  line-height: 1.1;
}


/* ================================= */
/*       SCREEN PLAY BUTTON          */
/* ================================= */

.television-gadget-screen-button {
  position: absolute;
  inset: 0;
  z-index: 2;
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
  border: 0;
  outline: 0;
  background: transparent;
  cursor: pointer;
}


/* ================================= */
/*          CHANNEL ARROWS           */
/* ================================= */

.television-gadget-screen-prev,
.television-gadget-screen-next {
  position: absolute;
  top: 50%;
  z-index: 4;
  width: 20px;
  height: 32px;
  padding: 0;
  margin: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: white;
  font-family: Arial, sans-serif;
  font-size: 30px;
  line-height: 32px;
  text-align: center;
  cursor: pointer;
  opacity: 0;
  transform: translateY(-50%);
  transition: opacity 0.15s ease;
}


.television-gadget-screen-prev {
  left: 4%;
}


.television-gadget-screen-next {
  right: 4%;
}


.television-gadget-screen-prev::before,
.television-gadget-screen-next::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background:
    rgba(0,0,0,0.32);
  border-radius: 3px;
  transform: translateY(3px);
  z-index: -1;
}


.television-gadget-screen:hover
.television-gadget-screen-prev,

.television-gadget-screen:hover
.television-gadget-screen-next {
  opacity: 0.8;
}


.television-gadget-screen-prev:hover,
.television-gadget-screen-next:hover {
  opacity: 1 !important;
}


/* ================================= */
/*             TV FRAME              */
/* ================================= */

.television-gadget-frame {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  margin: 0 !important;
  padding: 0 !important;
  border: 0 !important;
  outline: 0 !important;
  box-shadow: none !important;
  pointer-events: none;
  z-index: 3;
}


/* ================================= */
/*          POWER BUTTON             */
/* ================================= */

.television-gadget-power-button {
  position: absolute;
  left: 24%;
  top: 70.2%;
  width: 10%;
  height: 10%;
  z-index: 5;
  margin: 0;
  padding: 0;
  border: 0;
  outline: 0;
  background: transparent;
  cursor: pointer;
}


/* ================================= */
/*           HEART BUTTON            */
/* ================================= */

.television-gadget-heart-button {
  position: absolute;
  left: 46%;
  top: 70.8%;
  width: 8%;
  height: 8%;
  z-index: 5;
  margin: 0;
  padding: 0;
  border: 0;
  outline: 0;
  background: transparent;
  cursor: pointer;
}


/* ================================= */
/*              TV OFF               */
/* ================================= */

.television-gadget-screen.is-off {
  background: #000;
}


.television-gadget-screen.is-off
.television-gadget-player,

.television-gadget-screen.is-off
.television-gadget-pause-overlay {
  display: none;
}


.television-gadget-screen.is-off
.television-gadget-screen-prev,

.television-gadget-screen.is-off
.television-gadget-screen-next {
  display: none;
}


/* ================================= */
/*          TOUCH DEVICES            */
/* ================================= */

@media (hover: none) {

  .television-gadget-screen-prev,
  .television-gadget-screen-next {
    opacity: 0.8;
  }

}

</style>
2️⃣ Now go to Blogger → Theme → Edit HTML. (Before editing your theme, it’s always a good idea to download a backup copy! You know, just in case anything goes wrong while you’re tinkering with it.) Okay, now press Ctrl + F and search for </body>. Directly above that line, it’s where you’re going to paste this JavaScript code:
<script>
//<![CDATA[

/* ================================ */
/*  ✿ EDIT YOUR CHANNELS HERE ✿  */
/* ================================ */

var televisionGadgetChannels = [

  {
    label: 'CH 01',
    network: 'CHANNEL ONE',
    youtubeUrl: 'PASTE FULL YOUTUBE LINK HERE'
  },

  {
    label: 'CH 02',
    network: 'CHANNEL TWO',
    youtubeUrl: 'PASTE FULL YOUTUBE LINK HERE'
  },

  {
    label: 'CH 03',
    network: 'CHANNEL THREE',
    youtubeUrl: 'PASTE FULL YOUTUBE LINK HERE'
  }

];


(function () {

  /* ================================= */
  /*        YOUTUBE URL PARSER         */
  /* ================================= */

  function getYouTubeId(url) {

    if (!url) {
      return '';
    }


    url =
      String(url).trim();


    if (
      /^[A-Za-z0-9_-]{11}$/.test(url)
    ) {

      return url;

    }


    var match;


    match =
      url.match(
        /[?&]v=([A-Za-z0-9_-]{11})/
      );

    if (match) {
      return match[1];
    }


    match =
      url.match(
        /youtu\.be\/([A-Za-z0-9_-]{11})/
      );

    if (match) {
      return match[1];
    }


    match =
      url.match(
        /youtube\.com\/shorts\/([A-Za-z0-9_-]{11})/
      );

    if (match) {
      return match[1];
    }


    match =
      url.match(
        /youtube\.com\/embed\/([A-Za-z0-9_-]{11})/
      );

    if (match) {
      return match[1];
    }


    match =
      url.match(
        /youtube\.com\/live\/([A-Za-z0-9_-]{11})/
      );

    if (match) {
      return match[1];
    }


    return '';

  }


  /* ================================= */
  /*          YOUTUBE API              */
  /* ================================= */

  var previousYouTubeReady =
    window.onYouTubeIframeAPIReady;


  var televisionGadgetAPIReady =
    false;


  var televisionGadgetWaiting =
    [];


  window.onYouTubeIframeAPIReady =
    function () {

      televisionGadgetAPIReady =
        true;


      if (
        typeof previousYouTubeReady ===
        'function'
      ) {

        previousYouTubeReady();

      }


      televisionGadgetWaiting.forEach(
        function (startWidget) {

          startWidget();

        }
      );


      televisionGadgetWaiting = [];

    };


  function loadYouTubeAPI() {

    if (
      window.YT &&
      window.YT.Player
    ) {

      televisionGadgetAPIReady =
        true;

      return;

    }


    var existing =
      document.querySelector(
        'script[src="https://www.youtube.com/iframe_api"]'
      );


    if (existing) {
      return;
    }


    var script =
      document.createElement('script');


    script.src =
      'https://www.youtube.com/iframe_api';


    var firstScript =
      document.getElementsByTagName(
        'script'
      )[0];


    if (firstScript) {

      firstScript.parentNode.insertBefore(
        script,
        firstScript
      );

    } else {

      document.head.appendChild(
        script
      );

    }

  }


  /* ================================= */
  /*         START TV GADGETS          */
  /* ================================= */

  function initializeTelevisionGadgets() {

    var widgets =
      document.querySelectorAll(
        '.television-gadget'
      );


    widgets.forEach(
      function (widget, widgetIndex) {

        var screen =
          widget.querySelector(
            '.television-gadget-screen'
          );

        var playerContainer =
          widget.querySelector(
            '.television-gadget-player'
          );

        var pauseOverlay =
          widget.querySelector(
            '.television-gadget-pause-overlay'
          );

        var channelLabel =
          widget.querySelector(
            '.television-gadget-channel'
          );

        var networkLabel =
          widget.querySelector(
            '.television-gadget-network'
          );

        var screenButton =
          widget.querySelector(
            '.television-gadget-screen-button'
          );

        var previousButton =
          widget.querySelector(
            '.television-gadget-screen-prev'
          );

        var nextButton =
          widget.querySelector(
            '.television-gadget-screen-next'
          );

        var powerButton =
          widget.querySelector(
            '.television-gadget-power-button'
          );

        var heartButton =
          widget.querySelector(
            '.television-gadget-heart-button'
          );


        if (
          !screen ||
          !playerContainer
        ) {

          return;

        }


        var currentChannel = 0;

        var player = null;

        var isPoweredOn = true;

        var shouldPlayAfterLoad = false;


        /* ============================= */
        /*        PLAYER ELEMENT         */
        /* ============================= */

        var playerId =
          'television-gadget-player-' +
          widgetIndex +
          '-' +
          Math.floor(
            Math.random() * 1000000
          );


        playerContainer.id =
          playerId;


        /* ============================= */
        /*       CHANNEL INFORMATION     */
        /* ============================= */

        function updateChannelInfo() {

          var channel =
            televisionGadgetChannels[
              currentChannel
            ];


          if (channelLabel) {

            channelLabel.textContent =
              channel.label;

          }


          if (networkLabel) {

            networkLabel.textContent =
              channel.network;

          }

        }


        /* ============================= */
        /*        PAUSE OVERLAY          */
        /* ============================= */

        function showPauseOverlay() {

          if (!isPoweredOn) {
            return;
          }


          if (pauseOverlay) {

            pauseOverlay.classList.remove(
              'is-hidden'
            );

          }

        }


        function hidePauseOverlay() {

          if (pauseOverlay) {

            pauseOverlay.classList.add(
              'is-hidden'
            );

          }

        }


        /* ============================= */
        /*         LOAD CHANNEL          */
        /* ============================= */

        function loadChannel(
          index,
          playAfterLoad
        ) {

          if (
            !player ||
            !isPoweredOn
          ) {

            return;

          }


          currentChannel =
            index;


          shouldPlayAfterLoad =
            playAfterLoad;


          updateChannelInfo();


          var channel =
            televisionGadgetChannels[
              currentChannel
            ];


          var videoId =
            getYouTubeId(
              channel.youtubeUrl
            );


          if (!videoId) {

            player.stopVideo();

            showPauseOverlay();

            return;

          }


          /*
            Every channel begins at 0:00.
          */

          player.cueVideoById({
            videoId: videoId,
            startSeconds: 0
          });

        }


        /* ============================= */
        /*          PLAY / PAUSE         */
        /* ============================= */

        function toggleVideo() {

          if (
            !player ||
            !isPoweredOn
          ) {

            return;

          }


          var state =
            player.getPlayerState();


          if (
            state ===
            YT.PlayerState.PLAYING
          ) {

            player.pauseVideo();

            return;

          }


          hidePauseOverlay();


          /*
            If the visitor previously
            paused the video, YouTube
            continues from that position.
          */

          player.playVideo();

        }


        /* ============================= */
        /*        CHANGE CHANNEL         */
        /* ============================= */

        function switchChannel(
          newChannel
        ) {

          if (
            !player ||
            !isPoweredOn
          ) {

            return;

          }


          var wasPlaying =
            (
              player.getPlayerState() ===
              YT.PlayerState.PLAYING
            );


          loadChannel(
            newChannel,
            wasPlaying
          );

        }


        function previousChannel() {

          var newChannel =
            currentChannel - 1;


          if (newChannel < 0) {

            newChannel =
              televisionGadgetChannels.length -
              1;

          }


          switchChannel(
            newChannel
          );

        }


        function nextChannel() {

          var newChannel =
            currentChannel + 1;


          if (
            newChannel >=
            televisionGadgetChannels.length
          ) {

            newChannel = 0;

          }


          switchChannel(
            newChannel
          );

        }


        /* ============================= */
        /*             POWER             */
        /* ============================= */

        function powerOff() {

          if (!player) {
            return;
          }


          isPoweredOn =
            false;


          player.pauseVideo();


          hidePauseOverlay();


          screen.classList.add(
            'is-off'
          );

        }


        function powerOn() {

          if (!player) {
            return;
          }


          isPoweredOn =
            true;


          screen.classList.remove(
            'is-off'
          );


          /*
            Powering the television back
            on shows the current paused
            frame. It does not seek.
          */

          showPauseOverlay();

        }


        function togglePower() {

          if (isPoweredOn) {

            powerOff();

          } else {

            powerOn();

          }

        }


        /* ============================= */
        /*          TV BUTTONS           */
        /* ============================= */

        if (screenButton) {

          screenButton.addEventListener(
            'click',
            toggleVideo
          );

        }


        if (heartButton) {

          heartButton.addEventListener(
            'click',
            toggleVideo
          );

        }


        if (powerButton) {

          powerButton.addEventListener(
            'click',
            togglePower
          );

        }


        if (previousButton) {

          previousButton.addEventListener(
            'click',
            previousChannel
          );

        }


        if (nextButton) {

          nextButton.addEventListener(
            'click',
            nextChannel
          );

        }


        /* ============================= */
        /*       DISABLE CAPTIONS        */
        /* ============================= */

        function disableCaptions() {

          if (!player) {
            return;
          }


          try {

            player.unloadModule(
              'captions'
            );

          } catch (e) {}


          try {

            player.unloadModule(
              'cc'
            );

          } catch (e) {}

        }


        /* ============================= */
        /*        CREATE YT PLAYER       */
        /* ============================= */

        function createPlayer() {

          var firstChannel =
            televisionGadgetChannels[0];


          var firstVideoId =
            getYouTubeId(
              firstChannel.youtubeUrl
            );


          player =
            new YT.Player(
              playerId,
              {

                width: '100%',
                height: '100%',

                videoId:
                  firstVideoId,

                playerVars: {

                  controls: 0,
                  disablekb: 1,
                  fs: 0,
                  modestbranding: 1,
                  playsinline: 1,
                  rel: 0,
                  cc_load_policy: 0

                },

                events: {

                  onReady:
                    function () {

                      disableCaptions();

                      updateChannelInfo();

                      /*
                        Start paused at 0:00.
                      */

                      player.seekTo(
                        0,
                        true
                      );

                      player.pauseVideo();

                      showPauseOverlay();

                    },


                  onStateChange:
                    function (event) {

                      disableCaptions();

                      if (!isPoweredOn) {
                        return;
                      }


                      /* VIDEO PLAYING */

                      if (
                        event.data ===
                        YT.PlayerState.PLAYING
                      ) {

                        hidePauseOverlay();

                      }


                      /* VIDEO PAUSED */

                      if (
                        event.data ===
                        YT.PlayerState.PAUSED
                      ) {

                        showPauseOverlay();

                      }


                      /* VIDEO CUED */

                      if (
                        event.data ===
                        YT.PlayerState.CUED
                      ) {

                        /*
                          A newly selected
                          channel always begins
                          at 0:00.
                        */

                        player.seekTo(
                          0,
                          true
                        );


                        if (
                          shouldPlayAfterLoad
                        ) {

                          shouldPlayAfterLoad =
                            false;

                          hidePauseOverlay();

                          player.playVideo();

                        } else {

                          showPauseOverlay();

                        }

                      }


                      /* VIDEO ENDED */

                      if (
                        event.data ===
                        YT.PlayerState.ENDED
                      ) {

                        var newChannel =
                          currentChannel + 1;


                        if (
                          newChannel >=
                          televisionGadgetChannels.length
                        ) {

                          newChannel = 0;

                        }


                        loadChannel(
                          newChannel,
                          true
                        );

                      }

                    }

                }

              }
            );

        }


        /* ============================= */
        /*        WAIT FOR YOUTUBE       */
        /* ============================= */

        if (
          televisionGadgetAPIReady ||
          (
            window.YT &&
            window.YT.Player
          )
        ) {

          createPlayer();

        } else {

          televisionGadgetWaiting.push(
            createPlayer
          );

        }

      }
    );

  }


  /* ================================= */
  /*              START                */
  /* ================================= */

  function startTelevisionGadget() {

    loadYouTubeAPI();


    if (
      window.YT &&
      window.YT.Player
    ) {

      televisionGadgetAPIReady =
        true;

    }


    initializeTelevisionGadgets();

  }


  if (
    document.readyState ===
    'loading'
  ) {

    document.addEventListener(
      'DOMContentLoaded',
      startTelevisionGadget
    );

  } else {

    startTelevisionGadget();

  }

})();

//]]>
</script>
3️⃣ Then comes the fun part: creating your TV channels! Near the beginning of the JavaScript, you’ll find a big section marked /* ✿ EDIT YOUR CHANNELS HERE ✿ */ — where you can choose your channel label and network (for example, I have channels 01, 02 and 03, them being Disney Channel, MTV and Televisa) and you can paste your YouTube URL. It’ll look like this:
{
  label: 'CH #',
  network: 'MY CHANNEL',
  youtubeUrl: 'PASTE YOUTUBE LINK HERE'
}

And if you want to add more channels, all you have to do is copy the block above and add it inside the channel list. Just remember to put a comma between each block, and you should be good to go!

⚠️ IMPORTANT:

All the codes I just showed you are for the YouTube version of the gadget. If you want the version where, instead of a YouTube URL, you paste a link to your own video, then you should copy the following codes instead:



And in this case, you’ll have to store the video yourself, somewhere other than YouTube. I use Cloudinary, but you can use any file-hosting/storage service you want, as long as it gives you a direct URL to the video file itself, preferably an .mp4 file. A sharing link, preview-page link, or streaming-page link will not work! The URL needs to point directly to the video file. Other than that, the placing/editing is pretty much the same as in the YouTube version.

💖 Bonus: nostalgic television frames

The blue Cinderella-style TV is my favorite, but you can change the frame to anything you want! It’ll work as long as you keep the transparent screen opening in the same position (or you can change the positions directly in the code). This a bit tricky, so instead of having you do the work, I’ll put some options here that you can just copy and paste. Look for:

<img class="television-gadget-frame" src="AND PASTE YOUR TV PNG URL HERE" alt="Television">

In the original code, the blue TV png will already be there. You can replace it with any of these (and I’ll keep adding more, if I run into other cute television pngs on Pinterest — feel free to suggest something in the comments as well):

DISNEY PINK
BARBIE PINK
HELLO KITTY PINK
TINKER BELL PURPLE
CINDERELLA BLUE
HANNAH MONTANA PURPLE
ANTENNA BLACK
ANGELIC WHITE

2 comments:

  1. so cute!! I’ve been wanting something like this for sooo long but coding is so hard for me sometimes 😭 thank you queen <3

    ReplyDelete

The quick brown fox jumps over the lazy dog!?

Hi! My name is Anissa (not really) and I just turned 30 (well, almost). I feel just like the character from 13 Going On 30 (in that my body...

Pink iPod music player
Now Playing
Album cover
Loading...
0:00
0:00