【问题标题】:Any way to display some heavily-styled HTML in isolation from the rest of site's styles?有什么方法可以将一些样式繁重的 HTML 与网站的其他样式隔离开来?
【发布时间】:2010-10-29 23:33:08
【问题描述】:

我正在尝试找出一种在我客户的网站上显示电子邮件通讯存档的方法。问题是时事通讯充满了无数的内联样式,这非常适合在 Outlook 或任何地方看到它们,但它们在其他样式精美的网站中看起来并不太热。

我的目标是让我的客户能够复制生成的时事通讯的整个源代码(她的列表管理公司* 允许她访问)并将其粘贴到 CMS(drupal,如果它有所作为)。

*持续联系?邮件黑猩猩?我忘了。其中之一。

然后我想在她的网站上显示它,在网站其余部分的基本结构(标题、导航等)内。如果这是 1997 年,我会说“iframe!”并完成它,但是 A)这似乎是一个蹩脚的解决方案,并且 B)代码本身实际上并不存在于页面上,我认为这是 iframe 所必需的。

我可以在这个 HTML 块周围放置某种标签以将其与网站的其他样式隔离开来吗?还是有其他方法可以完全解决这个问题?

谢谢!

【问题讨论】:

  • 你能举一个这个疯狂的 HTML 的例子吗?
  • 在 1997 年,iFrames 只在 Internet Explorer 中,IE 的份额不到 20%。 :-)
  • 使用 DOM 解析器并删除所有 style 元素,因此适用标准样式表。您还可以根据需要添加类/ID,以使其与您现有的样式相得益彰。没有任何真正的方法可以忽略它们,并且您不能从外部样式表覆盖内联样式。此外,如果您在前端代码中执行此操作,它仍然会出现混乱,直到解析器触发,因此最好在服务器端执行,或者如果您坚持在客户端执行,则在将文本放入 dom 之前格式化文本(但是你失去了让搜索引擎抓取它的好处)。

标签: html css email


【解决方案1】:

我自己没有使用过但希望在类似情况下利用的另一个选项是使用Shadow DOM,它是Web Components 规范的一部分。我主要担心的是,我们仍然有一些用户在使用 IE 11,虽然似乎支持 polyfills,但根据我 read elsewhere 的内容,看起来覆盖所有浏览器并不是真正直接的。

有关如何使用 Shadow DOM 实现此效果的一些详细信息可以在 herehere 找到。我还创建了a small gist,我创建它是为了展示我在了解Shadow DOM 如何工作时一直在制定的基本想法,随着我了解更多,我将对其进行更新。您可以在下面看到该要点内容的快照。

<!doctype html>
<html>

<head>
    <style>
        .row {
            display: flex;
        }

        .column {
            flex: 50%;
            padding: 10px;
            height: 300px;
        }

        * {
            color: Red;
        }
    </style>
</head>

<body>
    <div class="row">
        <div class="column" style="background-color:#aaa;">
            <h2>Column 1</h2>
            <div id="content1">
                SOME CONTENT FROM CMS
            </div>
        </div>
        <div class="column" style="background-color:#bbb;">
            <h2>Column 2</h2>
            <div id="content2">
                SOME MORE CONTENT FROM CMS
            </div>
        </div>
    </div>

    <script>
        document
            .getElementById("content1")
            .attachShadow({ mode: 'open' })
            .innerHTML = `
                <style>
                    *{all:initial} 
                    style{display: none}
                    div{display: block}
                </style>
                <h3>This text is not red</h3>
                <div>slot content: <slot></slot></div>`;

        document
            .getElementById("content2")
            .attachShadow({ mode: 'open' })
            .innerHTML = `
                <style>
                    *{all:initial} 
                    style{display: none}
                    div{display: block}
                </style>
                <h3>This text is not red</h3>
                <div>slot content: <slot></slot></div>`;
    </script>
</body>

</html>

【讨论】:

【解决方案2】:

9 年后,仍然没有更好的解决方案。

如果你没有外部源(你不能手动将html添加到框架中)你需要使用js插入杂乱的html/css(在我的例子中我用它来查看电子邮件)

<iframe class="my-frame" width="100%" height="100%" src="about:blank"></iframe>

和js:

const frame = document.querySelector('.my-frame');

frame.contentWindow.document.open('text/html', 'replace');
frame.contentWindow.document.write(hereGoesYourMessyHtmlCss);
frame.contentWindow.document.close();

【讨论】:

    【解决方案3】:

    在我看来,剪切和粘贴原始 HTML 会带来太多的安全问题。永远不要相信用户的输入。即使内容完全是良性的,下周时事通讯的设计者也可能会决定更改其格式或加入一些 javascript,您将对任何可能出现的问题负责。

    因此,我将实现一个解析器,它会删除除内容部分之外的任何内容,只保留 b、a、h*、blockquote 和类似的简单元素,例如论坛帖子中允许的元素,以及它们的样式。之后,您可以将其显示为 CMS 中的普通帖子。我看不出有什么不同的理由。

    至于如何将其与您的其他 CSS 隔离开来,如果您注意您的 CMS 的所有 CSS 规则都适用于具有特定类的元素,您实际上并不需要这样做。或者,对您的帖子进行 CSS 重置:

    .post p {
         margin: 0;
         ... 
    .post /* all the standard CSS reset rules preceded with .post */
    

    然后

    <div class="post"> content parsed from your CMS </div>
    

    【讨论】:

    • 您可能会遇到特异性问题。覆盖所有的 CSS 不是解决方案。特别是在未知(动态)css插入的情况下。
    【解决方案4】:

    IFrame 是我能找到的唯一方法。唯一的替代方法是覆盖新闻通讯显示区域的父页面 CSS 中的所有样式。

    如您所述,使用 iframe 可能需要您将简报托管在一个独立文件中。我知道的唯一替代方法是您可以使用 JavaScript 动态创建和/或填充 iframe。

    如果您使用此方法,您可以将时事通讯显示在具有特定类的 div 中,然后使用 JavaScript 将 div 移动到 iframe 中。最大的缺点是,对于没有启用 JavaScript 的用户来说,这不会发生。

    【讨论】:

      【解决方案5】:

      您不能使用模态框有什么原因吗?这将允许您强制一个新请求并通过不应用您的通用样式表来使页面呈现您想要的方式,同时让您的用户保持在所需的页面上。当然,它不会显示内联元素,但它在功能上几乎是等效的。

      【讨论】:

      • 在这种情况下,客户特别希望内容以内联方式显示——我们正在替换一个必须点击才能显示最新时事通讯的页面。跨度>
      • 在这种情况下,它是 iFrames 或 bust。
      猜你喜欢
      • 1970-01-01
      • 2012-07-13
      • 1970-01-01
      • 2023-01-26
      • 1970-01-01
      • 1970-01-01
      • 2019-07-03
      • 1970-01-01
      相关资源
      最近更新 更多