Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough

Responsive iframe in Drupal 8 from Client Embed Code

Parent Feed: 

Nobody likes iframes. That's because you can't style their innards, and they aren't responsive... or are they?!?!

The first thing to know about here is the padding height hack. This allows you to set the height of an object relative to the width, because while height is always as a percentage of the container, padding height is as a percentage of width. So all you have to know is the ratio of height to width and you can make a thing that responsively scales.

My first attempt was to use javascript to get the viewport height from the iframe. Turns out, no, you can't do that. Even if you find some Stack Overflow that seems to say you can. We knew this already, didn't we?

What I did next was to make a field for the client to paste in the embed code. In iframe embed code there's almost always a width and a height. So, just scrape that from the HTML in a preprocess hook, and then set the padding accordingly in the twig file.

Here's my preprocess hook. You can learn more about HTML parsing found in this hook in my post here.

function mytheme_preprocess_field(&$variables, $hook) {
  if ($variables['field_name'] == 'field_myiframe_embed_code') {
    $embed = !empty($variables['items'][0]['content']['#context']['value']) ? $variables['items'][0]['content']['#context']['value'] : '';
    if (!empty($embed)) {
      foreach (Html::load($embed)->getElementsByTagName('iframe') as $iframe) {
        $variables['src'] = $iframe->getAttribute('src');  / Sets a variable `src` accessible in the twig template
        $width = $iframe->getAttribute('width');
        $height = $iframe->getAttribute('height');
        $variables['paddingTop'] =  $height / $width * 100; // Sets a variable `paddingTop` accessible in the twig template
      }
      if (empty($width) || empty($height) || empty($variables['src'])) {
        drupal_set_message('There\'s something wrong with your embed code. Please fix. Needs height, width, and src.', 'error');
      }
    }
    else {
      drupal_set_message('No value found for your embed code', 'error');
    }
  }
}

Here's my twig field template (field--field-myiframe-embed-code.html.twig):

<div class="myiframe__iframe-wrapper" style="padding-top: {{ paddingTop }}%;">
  <iframe src="http://glassdimly.com/blog/tech/drupal-8-responsive-iframes-css-drupal-planet/responsive-iframe-drupal-8-client-embed-code/{{ src }}" class="myiframe__iframe" />
</div>

And here's the CSS I used, more detail here.

.myiframe__iframe {
  position: absolute;
  top:0;
  left: 0;
  width: 100%;
  height: 100%;
  border: none;
}
 
.myiframe__iframe-wrapper {
  position: relative;
  height: 0;
  overflow: hidden;
}
Author: 
Original Post: 

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web