CSS :focus-within selector for an element with an iframe child
Asked Answered
T

2

12

I have a scenario like this:

.container {
  background: yellow;
  padding: 40px;
}

.container:focus-within {
  background: red;
}

iframe {
  background: white;
}
<div class="container">
  <input type="text" placeholder="Input 1">
  <iframe srcdoc="<input type='text' placeholder='Input 2'>"></iframe>
</div>

As you can see, when I click on input 1 to type, the container turns red because of the :focus-within selector. But when I focus input 2 (inside the iframe), it doesn't.

Is it possible to use a CSS selector on .container for if something inside the iframe is focused? I have control over the CSS inside the iframe as well.

Traject answered 23/9, 2018 at 5:43 Comment(0)
E
2

not by css but with jQuery, you can add class to container when input 2 focused, and remove class when it loses focus.

<style>
 .container:focus-within, .container.in_iframe {
            background: red;
        }
</style>

<script>
    $('document').ready(function () {
        $('#iframe').on('load', function () {
            var iframe = $('#iframe').contents();
            iframe.find("input").on('focus', function () {
                $('.container').addClass('in_iframe');
            });
            iframe.find("input").on('focusout', function () {
                $('.container').removeClass('in_iframe');
            });
        });
    });
</script>

full code: https://codepen.io/peker-ercan/pen/PdgEOy

Eudo answered 23/9, 2018 at 8:53 Comment(2)
3 years later... is this now possible with pure CSS on the container?Earthshine
@Earthshine For security reasons, no.Knitting
K
0

CSS is scoped to the one document - an iframe is a separate document.
Any CSS that applies to your page that contains that iframe can't apply to elements within the iframe.

Failed attempt with :has() selector as another example:

.container {
  background: yellow;
  padding: 40px;
}

.container:has(:focus) {
  background: red;
}

iframe {
  background: white;
}
<div class="container">
  <input type="text" placeholder="Input 1">
  <iframe srcdoc="<input type='text' placeholder='Input 2'>"></iframe>
</div>

You will need JavaScript, here is an example that should work with an iframe of the same origin:

document.querySelectorAll('.container').forEach((container) => {
  container.querySelectorAll('iframe').forEach((iframe) => {
    iframeRef(iframe).addEventListener('focus', () => {
      container.classList.add('container-iframe-focused-within')
    })
    iframeRef(iframe).addEventListener('focusout', () => {
      container.classList.remove('container-frame-focused-within')
    })
  })
})

function iframeRef(frameRef) {
  return frameRef.contentWindow ?
    frameRef.contentWindow.document :
    frameRef.contentDocument
}
.container {
  background: yellow;
  padding: 40px;
}

.container:focus-within,
.container-iframe-focused-within {
  background: red;
}

iframe {
  background: white;
}
<div class="container">
  <input type="text" placeholder="Input 1">
  <iframe srcdoc="<input type='text' placeholder='Input 2'>"></iframe>
</div>
Knitting answered 16/2, 2023 at 21:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.