Search code examples
javascripthtmljquerycsstiktok

Embedded TikTok posts / thumbnail styling issue


I am building an HTML/CSS/JS app that displays embedded TikTok posts. It's a pretty simple operation - I make an API call that returns a list of post id's, and then dynamically display the posts using the embed code provided by TikTok. I am NOT using the TikTok embed API here, I am just populating iframe elements in the DOM and updating their innerHTML with the embed code for each post ID returned by the API. The embed code is just the default that you can copy from any public post.

The issue I'm having is that the thumbnails are appearing very small, only showing half of the video image, and the user has to click on the thumbnail in order to then scroll and see the rest of the thumbnail + caption. I am not seeing anything hard-coded in the embed code that would affect the height this way, and I cannot seem to affect the height via CSS either.

Does anyone see a solution here? I have tried setting the height both in percentage and px via HTML, JS, and CSS...with literally no success in any instance.

Here is a working codepen and see below for code. Thanks in advance.

tikTokArr = [{
    post_id: "7351959206842436907"
  },

];

// Store container in variable
let tikTokContainer = document.getElementById("tik-tok-feed-container");

tikTokArr.forEach((post) => {
  const postId = post.post_id;

  const postContainer = document.createElement("div");
  tikTokContainer.append(postContainer);
  postContainer.classList.add("post");

  const postFrame = document.createElement("iframe");
  postContainer.append(postFrame);
  postFrame.classList.add("post--frame");
  postFrame.id = `tt-post__${postId}`;
  postFrame.src = `https://www.tiktok.com/embed/v2/${postId}?lang=en-US&amp`;
  postFrame.innerHTML = `<blockquote class="tiktok-embed" cite="https://www.tiktok.com/embed/v2/${postId}?lang=en-US&amp" data-video-id="${postId}" style="max-width: 605px; min-width: 325px;"><iframe
      name="__tt_embed__v6828268207359413509"
      sandbox="allow-popups allow-popups-to-escape-sandbox allow-scriptallow-top-navigation allow-same-origin"
      src="https://www.tiktok.com/embed/v2/${postId}?lang=en-US&amp;"
      style="width: 100%; height: 100%; min-height: 900px; display: block; visibility: "></iframe></blockquote>`

})
#tik-tok-feed-container {
  display: flex;
  flex-direction: row;
  row-gap: 1rem;
  column-gap: 3rem;
  padding: 1rem;
}
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

<div id="tik-tok-feed-container">

</div>


Solution

  • Since it's cross domain, you probably want to use the intrinsic ratio technique, which uses padding-bottom hack. For example, we can use padding-bottom: 100% like this:

    tikTokArr = [{
        post_id: "7351959206842436907"
      },
      {
        post_id: "7351959206842436907"
      },
    ];
    
    // Store container in variable
    let tikTokContainer = document.getElementById("tik-tok-feed-container");
    
    tikTokArr.forEach((post) => {
      const postId = post.post_id;
    
      const postContainer = document.createElement("div");
      tikTokContainer.append(postContainer);
      postContainer.classList.add("post");
    
      const postFrame = document.createElement("iframe");
    
      postContainer.append(postFrame);
      postFrame.classList.add("post--frame");
      postFrame.id = `tt-post__${postId}`;
    
      postFrame.src = `https://www.tiktok.com/embed/v2/${postId}?lang=en-US&amp`;
    });
    #tik-tok-feed-container {
      display: flex;
      flex-direction: row;
      row-gap: 1rem;
      column-gap: 3rem;
      padding: 1rem;
    }
    
    .post {
      position: relative;
      height: 0;
      padding-bottom: 100%;
      min-width: 325px;
      flex-basis: 100%;
    }
    
    .post--frame {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
    }
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    
    <div id="tik-tok-feed-container">
    
    </div>

    If you want a fixed size for each card, you can also play around with the padding-bottom: 100%; and flex-basis: 100%;, e.g. for a 605px x 900px card, you can change them to:

    padding-bottom: 900px;
    flex-basis: 605px;
    

    Like this:

    tikTokArr = [{
        post_id: "7351959206842436907"
      },
      {
        post_id: "7351959206842436907"
      },
    ];
    
    // Store container in variable
    let tikTokContainer = document.getElementById("tik-tok-feed-container");
    
    tikTokArr.forEach((post) => {
      const postId = post.post_id;
    
      const postContainer = document.createElement("div");
      tikTokContainer.append(postContainer);
      postContainer.classList.add("post");
    
      const postFrame = document.createElement("iframe");
    
      postContainer.append(postFrame);
      postFrame.classList.add("post--frame");
      postFrame.id = `tt-post__${postId}`;
    
      postFrame.src = `https://www.tiktok.com/embed/v2/${postId}?lang=en-US&amp`;
    });
    #tik-tok-feed-container {
      display: flex;
      flex-direction: row;
      row-gap: 1rem;
      column-gap: 3rem;
      padding: 1rem;
    }
    
    .post {
      position: relative;
      height: 0;
      padding-bottom: 900px;
      min-width: 325px;
      flex-basis: 605px;
    }
    
    .post--frame {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
    }
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    
    <div id="tik-tok-feed-container">
    
    </div>