Anular el estilo del cuerpo para el contenido en un iframe

165

¿Cómo puedo controlar la imagen de fondo y el color de un elemento del cuerpo dentro de un iframe? Tenga en cuenta que el elemento del cuerpo incrustado tiene una clase y iframees de una página que forma parte de mi sitio.

La razón por la que necesito esto es que mi sitio tiene un fondo negro asignado al cuerpo, y luego un fondo blanco asignado a divs que contienen texto. Un editor WYSIWYG usa un elemento iframepara incrustar contenido al editar, pero no incluye el div, por lo que el texto es muy difícil de leer.

El cuerpo de iframecuando en el editor tiene una clase que no se usa en ningún otro lugar, así que supongo que esto se puso allí para que problemas como este puedan resolverse. Sin embargo, cuando aplico estilos class.body, no anulan los estilos aplicados al cuerpo. Lo extraño es que los estilos aparecen en Firebug, ¡así que no tengo idea de lo que está pasando!

Gracias

ACTUALIZACIÓN: he probado la solución de @ mikeq de agregar un estilo a la clase que es la clase del cuerpo. Esto no funciona cuando se agrega a la hoja de estilo de la página principal, pero funciona cuando se agrega con Firebug. Supongo que esto se debe a que Firebug se aplica a todos los elementos de la página, mientras que el CSS no se aplica dentro de los iframes. ¿Significa esto que agregar el CSS después de la carga de la ventana con JavaScript funcionaría?

jd6699
fuente
1
Posible duplicado de ¿Cómo aplicar CSS a iframe?
2540625
Si bien no es posible tocar nada en un iframe, cargar esa URL por Ajax en una <div>lata a veces puede ser una solución alternativa (si CORS-Header lo permite) ... (y "desinfectar" los datos cargados por regexp en el Sí, todo hacky ...)
Frank Nocke 05 de
Puede usar JavaScript si los dominios de la página coinciden, pero ¿por qué no simplemente poner un bloque de estilo en el HTML de su página interna para anular los colores que desea cambiar? ¡Simplemente agregue más selectores en su anulación o use importante! si todo lo demás falla, para anular cualquier estilo de color que desee solo en esa página ...
OG Sean

Respuestas:

111

Un iframe es un "agujero" en su página que muestra otra página web dentro de él. El contenido del iframe no tiene ninguna forma ni forma parte de su página principal.

Como han dicho otros, sus opciones son:

  • dar al archivo que se está cargando en el iframe el CSS necesario
  • si el archivo en el iframe es del mismo dominio que su padre, entonces puede acceder al DOM del documento en el iframe desde el padre.
DA.
fuente
251

Lo siguiente solo funciona si el contenido del iframe es del mismo dominio principal.

El siguiente script jquery funciona para mí. Probado en Chrome e IE8. El iframe interno hace referencia a una página que está en el mismo dominio que la página principal.

En este caso particular, estoy ocultando un elemento con una clase específica en el iframe interno.

Básicamente, simplemente agrega un elemento de 'estilo' a la 'cabeza' del iframe interno.

$('iframe').load( function() {
    $('iframe').contents().find("head")
      .append($("<style type='text/css'>  .my-class{display:none;}  </style>"));
});
SimpleSam5
fuente
44
@ SimpleSam5 ¿Puede proporcionar la alternativa de Javascript (sin usar Jquery)?
Kamalakannan J
1
@sincerekamal Aquí está el código sin la necesidad de jQuery: jsfiddle.net/9g9wkpon Solo necesita saber que las propiedades de CSS con guiones están escritas en camelCase en JavaScript, como en mi ejemplo. :)
Dennis98
2
jquery.js? ver = 1.12.4: 2 DOMException no capturado: no se pudo leer la propiedad 'contentDocument' de 'HTMLIFrameElement': bloqueó un marco con origen " xxxxxxxxx.com " para que no acceda a un marco de origen cruzado.
Alex Stanese
2
@AlexStanese como dice jeremy, esto solo funciona si la página del iframe proviene del mismo servidor que la página principal ... lo que generalmente significa que no necesita molestarse con javascript de todos modos ... simplemente agregue el CSS a la otra página en primer lugar.
DA.
@KamalakannanJ ni siquiera necesitas usar Javascript. Simplemente edite la página que está en el iFrame y coloque el CSS allí.
DA.
25

No puede cambiar el estilo de una página que se muestra en un iframe a menos que tenga acceso directo y, por lo tanto, sea propietario de los archivos html y / o css de origen.

Esto es para detener XSS (Cross Site Scripting)

Myles Gray
fuente
¿Qué quiere decir con "acceso directo"? La página en el iframe es de mi sitio, es todo un dominio.
jd6699
2
Bueno, entonces deberá cambiar el archivo fuente en su sitio (no puede modificar ningún contenido en un iframe), por lo que si el iframe apunta a mysite.com/test.html, deberá modificar test.html directamente. .
Myles Gray
1
¿No puedo? Bajo las condiciones, el OP dice que puedes. Por ejemplo, la URL de marco flotante interno es igual a su sitio principal por lo que debería ser capaz de acceder al DOM bien con cualquier sabor de javascript te gusta ...
OG Sean
@Myles Gray Wrong. Puede modificar el contenido de un iframe desde su página principal si está en el mismo dominio, tanto con JavaScript como con CSS.
Kevin M
8

Un iframetiene otro alcance, por lo que no puede acceder al estilo o cambiar su contenido con javascript.

Básicamente es "otra página".

Lo único que puede hacer es editar su propio CSS, porque con su CSS global no puede hacer nada.

Alessandro Vendruscolo
fuente
Sí puedes, con javascript. Tenga en cuenta que funciona mejor con la URL del iframe y la URL principal que comparte el mismo dominio. Pero, creo que tiene razón al señalar que esto solo se puede hacer con CSS en la página dentro del iframe.
OG Sean
8

Anular otro dominio iframe CSS

Al usar parte de la respuesta de SimpleSam5 , logré esto con algunos de los iframes de chat de Tawk (su interfaz de personalización está bien, pero necesitaba más personalizaciones).

En este iframe particular que aparece en dispositivos móviles, necesitaba ocultar el ícono predeterminado y colocar una de mis imágenes de fondo. Hice lo siguiente:

Tawk_API.onLoad = function() {
// without a specific API, you may try a similar load function
// perhaps with a setTimeout to ensure the iframe's content is fully loaded
  $('#mtawkchat-minified-iframe-element').
    contents().find("head").append(
     $("<style type='text/css'>"+
       "#tawkchat-status-text-container {"+
         "background: url(https://example.net/img/my_mobile_bg.png) no-repeat center center blue;"+
         "background-size: 100%;"+
       "} "+
       "#tawkchat-status-icon {display:none} </style>")
   );
};

No soy dueño de ningún dominio de Tawk y esto funcionó para mí, por lo tanto, puede hacerlo incluso si no es del mismo dominio principal (a pesar del comentario de Jeremy Becker sobre la respuesta de Sam).

CPHPython
fuente
18
Sospecho que esto solo funciona porque la gente de Tawk lo ha permitido explícitamente.
Abogados
@CPHPython Quizás puedas ayudarme. Mira esto: stackoverflow.com/questions/60923168/…
Success Man
7

Este código usa JavaScript vainilla. Crea un nuevo <style>elemento. Establece el contenido de texto de ese elemento como una cadena que contiene el nuevo CSS. Y agrega ese elemento directamente a la cabeza del documento del iframe.

var iframe = document.getElementById('the-iframe');
var style = document.createElement('style');
style.textContent =
  'body {' +
  '  background-color: some-color;' +
  '  background-image: some-image;' +
  '}' 
;
iframe.contentDocument.head.appendChild(style);
2540625
fuente
77
Blocked a frame with origin xxxxxxxxx from accessing a cross-origin frame.Me temo que no funcionará
Mike
1

Si tiene control de la página que aloja el iframe y la página del iframe, puede pasar un parámetro de consulta al iframe ...

Aquí hay un ejemplo para agregar una clase al iframe en función de si el sitio de alojamiento es móvil o no ...

Agregar iFrame:

var isMobile=$("mobile").length; //detect if page is mobile
var iFrameUrl ="https://myiframesite/?isMobile=" + isMobile; 

$(body).append("<div id='wrapper'><iframe src=''></iframe></div>");
$("#wrapper iframe").attr("src", iFrameUrl ); 

Dentro de iFrame:

//add mobile class if needed
var url = new URL(window.location.href);
var isMobile = url.searchParams.get("isMobile");
if(isMobile == "1") {
    $("body").addClass("mobile");
}
Ben
fuente
Quizás podrías ayudarme. Mira esto: stackoverflow.com/questions/60923168/…
Success Man
0

Tengo un blog y tuve muchos problemas para descubrir cómo cambiar el tamaño de mi esencia incrustada. El administrador de publicaciones solo le permite escribir texto, colocar imágenes e incrustar código HTML. El diseño del blog responde en sí mismo. Está construido con Wix. Sin embargo, el HTML incrustado no lo es. Leí mucho sobre cómo es imposible cambiar el tamaño de los componentes dentro del cuerpo de los iFrames generados. Entonces, aquí está mi sugerencia:

Si solo tiene un componente dentro de su iFrame, es decir, su esencia, solo puede cambiar su tamaño. Olvídate del iFrame.

Tuve problemas con viewport, diseños específicos para diferentes agentes de usuario y esto es lo que resolvió mi problema:

<script language="javascript" type="text/javascript" src="https://gist.github.com/roliveiravictor/447f994a82238247f83919e75e391c6f.js"></script>

<script language="javascript" type="text/javascript">

function windowSize() {
  let gist = document.querySelector('#gist92442763');

  let isMobile = {
    Android: function() {
        return /Android/i.test(navigator.userAgent)
    },
    BlackBerry: function() {
        return /BlackBerry/i.test(navigator.userAgent)
    },
    iOS: function() {
        return /iPhone|iPod/i.test(navigator.userAgent)
    },
    Opera: function() {
        return /Opera Mini/i.test(navigator.userAgent)
    },
    Windows: function() {
        return /IEMobile/i.test(navigator.userAgent) || /WPDesktop/i.test(navigator.userAgent)
    },
    any: function() {
        return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
    }
};

  if(isMobile.any()) {
    gist.style.width = "36%";
    gist.style.WebkitOverflowScrolling = "touch"
    gist.style.position = "absolute"
  } else {
    gist.style.width = "auto !important";
  }
}

windowSize();

window.addEventListener('onresize', function() {
    windowSize();
});

</script>

<style type="text/css">

.gist-data {
  max-height: 300px;
}

.gist-meta {
  display: none;
}

</style>

La lógica es establecer css gist (o su componente) en función del agente de usuario. Asegúrese de identificar primero su componente, antes de aplicar al selector de consultas. Siéntase libre de ver cómo funciona la capacidad de respuesta .

Victor R. Oliveira
fuente
-3

Tal vez ha cambiado ahora, pero he usado una hoja de estilo separada con este elemento:

.feedEkList iframe
{
max-width: 435px!important;
width: 435px!important;
height: 320px!important;
}

para diseñar con éxito iframes de YouTube incrustados ... vea las publicaciones de blog en esta página .

Tim Jackson
fuente
44
Si bien este enlace puede responder la pregunta, es mejor incluir las partes esenciales de la respuesta aquí y proporcionar el enlace como referencia. Las respuestas de solo enlace pueden volverse inválidas si la página vinculada cambia.
Shaiful Islam
44
Esto solo se aplica al elemento iFrame en sí mismo: la pregunta se refiere específicamente al contenido de iFrame, que actualmente no es posible cambiar a través de CSS solo.
pwdst
@ShaifulIslam, que es precisamente lo que ha sucedido. Rending Tims responde inútil.
Alex Foxleigh
-24

proporcione al cuerpo de su página de iframe una identificación (o clase si lo desea)

<html>
<head></head>
<body id="myId">
</body>
</html>

luego, también dentro de la página del iframe, asigne un fondo a eso en CSS

#myId {
    background-color: white;
}
mikeq
fuente
Esto es raro Su solución funciona para mí cuando la agrego a la página con firebug, pero no funciona si está en el archivo CSS normal de la página. ¿Podría ser parte de su comentario "suponiendo que la página dentro del iFrame sea suya para editar"? No entendí lo que querías decir con eso. Gracias
jd6699
Quiero decir con eso, ¿está la página que está cargando en el iFrame desde su sitio y está bajo su control? o es de un sitio externo que no puede editar la fuente para incluir esa identificación / clase.
mikeq
Es de mi sitio, pero como lo ha hecho el editor, no será fácil cambiar el marcado que se extrae.
jd6699
ps No quise decir agregar el id = "myId" a su página principal, sino a la página dentro del iFrame. De esa manera, puede orientar el cuerpo de la página iFrame con un estilo diferente al de su página principal. También está haciendo referencia al archivo CSS en sus páginas de iFrame, ¿verdad? Debe tratar la página cargada en el iFrame como una página completamente independiente. Si carga solo esa página en un navegador web, ¿tiene el estilo correcto?
mikeq
No estoy realmente seguro de dónde está la 'página', ya que no es toda la página que usa el editor. Gracias por su ayuda, creo que entiendo cómo funciona todo esto, no.
jd6699