Safari 忽略 CSS :not() 规则

Safari ignore CSS :not() rule

我遇到了 Safari 13.0.5 (14608.5.12)

的问题

尝试修改一些 WordPress Divi builder plugin 样式时,我遇到了一个意想不到的问题,即无法应用否定规则,该规则会阻止插件在必要时在特定位置设置样式。

修改文件:

src/wordpress/wp-content/plugins/divi-builder/includes/builder/styles/frontend-builder-plugin-style.min.css

所以我是这样来的:

#et-boc .et-l .hentry,
#et-boc .et-l a,
#et-boc .et-l a:active,
#et-boc .et-l blockquote,
#et-boc .et-l div:not(.woocommerce-message,.star-rating),
#et-boc .et-l em,
#et-boc .et-l form,
#et-boc .et-l h1,
#et-boc .et-l h2,
#et-boc .et-l h3,
#et-boc .et-l h4,
#et-boc .et-l h5,
#et-boc .et-l h6,
#et-boc .et-l hr,
#et-boc .et-l iframe,
#et-boc .et-l img,
#et-boc .et-l input,
#et-boc .et-l label,
#et-boc .et-l li,
#et-boc .et-l object,
#et-boc .et-l ol,
#et-boc .et-l p,
#et-boc .et-l span,
#et-boc .et-l strong,
#et-boc .et-l textarea,
#et-boc .et-l ul,
#et-boc .et-l video {background: 0 0;
    border: none;
    -moz-border-radius: 0;
    -webkit-border-radius: 0;
    border-radius: 0;
    -webkit-box-shadow: none;
    -moz-box-shadow: none;
    box-shadow: none;
    color: inherit;
    letter-spacing: normal;
    margin: 0;
    outline: 0;
    padding: 0;
    text-align: inherit;
    text-shadow: inherit;
    -moz-transition: none;
    -o-transition: none;
    -webkit-transition: none;
    transition: none;
    vertical-align: baseline;
}

为此:

#et-boc .et-l *:not(.no-divi-styles) .hentry,
#et-boc .et-l *:not(.no-divi-styles) a,
#et-boc .et-l *:not(.no-divi-styles) a:active,
#et-boc .et-l *:not(.no-divi-styles) blockquote,
#et-boc .et-l *:not(.no-divi-styles) div:not(.woocommerce-message,.star-rating),
#et-boc .et-l *:not(.no-divi-styles) em,
#et-boc .et-l *:not(.no-divi-styles) form,
#et-boc .et-l *:not(.no-divi-styles) h1,
#et-boc .et-l *:not(.no-divi-styles) h2,
#et-boc .et-l *:not(.no-divi-styles) h3,
#et-boc .et-l *:not(.no-divi-styles) h4,
#et-boc .et-l *:not(.no-divi-styles) h5,
#et-boc .et-l *:not(.no-divi-styles) h6,
#et-boc .et-l *:not(.no-divi-styles) hr,
#et-boc .et-l *:not(.no-divi-styles) iframe,
#et-boc .et-l *:not(.no-divi-styles) img,
#et-boc .et-l *:not(.no-divi-styles) input,
#et-boc .et-l *:not(.no-divi-styles) label,
#et-boc .et-l *:not(.no-divi-styles) li,
#et-boc .et-l *:not(.no-divi-styles) object,
#et-boc .et-l *:not(.no-divi-styles) ol,
#et-boc .et-l *:not(.no-divi-styles) p,
#et-boc .et-l *:not(.no-divi-styles) span,
#et-boc .et-l *:not(.no-divi-styles) strong,
#et-boc .et-l *:not(.no-divi-styles) textarea,
#et-boc .et-l *:not(.no-divi-styles) ul,
#et-boc .et-l *:not(.no-divi-styles) video {background: 0 0;
    border: none;
    -moz-border-radius: 0;
    -webkit-border-radius: 0;
    border-radius: 0;
    -webkit-box-shadow: none;
    -moz-box-shadow: none;
    box-shadow: none;
    color: inherit;
    letter-spacing: normal;
    margin: 0;
    outline: 0;
    padding: 0;
    text-align: inherit;
    text-shadow: inherit;
    -moz-transition: none;
    -o-transition: none;
    -webkit-transition: none;
    transition: none;
    vertical-align: baseline;
}

此解决方案适用于 Chrome、Firefox 等! ...除了 Safari =/

这个浏览器有什么问题?

您还不能在所有浏览器中使用 :not() 中的选择器列表,这就是为什么您在 Safari 中看不到此功能的原因 — 整个选择器列表都被删除了。参见 MDN's reference

您需要将其分成两个 :not()

...
#et-boc .et-l *:not(.no-divi-styles) div:not(.woocommerce-message):not(.star-rating),
...

无论如何,最好避免在样式中使用如此复杂的代码,并且不要被浏览器错误绊倒。我没有设法找出为什么 Safari 会以这种方式运行,但是,关于 DIVI plug-in,这样的解决方案会使代码更加复杂。我相信在未来的版本中会修复该错误。

但是我找到了另一个简单的解决方案:由于 DIVI plugin 对放置在其中的任何代码都非常激进,因此一个简单的解决方法是将应用程序和代码的必要部分放入流中将您需要的代码与第三方干扰完全隔离开来的 iframe。

例如你可以这样做:

interest.pug

extends index
block content
    .interest
        .container.container--content.interest__container
            script.
                function interestIframeOnLoad () {
                    var interestIframe = document.getElementById('interest__iframe')
                    interestIframe.contentWindow.postMessage({
                        selector: '#interest',
                        //...your_app_init_options_here
                    }, '*')
                }

            iframe(
                src='./interest__iframe.pug'
                class='interest__iframe'
                id='interest__iframe'
                frameborder='0'
                onload='javascript: interestIframeOnLoad()'
            )

interest__iframe.pug

doctype html
html(lang='en')
    head
        meta(charset='UTF-8')
        meta(name='viewport', content='width=device-width, initial-scale=1.0')
        title Interest inner app
        script(src='../../assets/js/interest.js')

    body
        #interest
        script.
            let appWasLaunched = false;
            const iframe = window.top.document.getElementById('interest__iframe');

            function launchApp(options) {
                window.app.interest(options);
            }

            window.addEventListener('message', e => {
                if (!appWasLaunched) {
                    appWasLaunched = true;
                    var data = e.data;
                    launchApp(data);
                }
            }, false);

interest.js

import Vue from 'vue'
import App from './App.vue'

export default function interest (options) {
    new Vue({
        data: options,
        render: (h) => h(App)
    }).$mount(options.selector);
}

window.app = window.app || {};
window.app.interest = interest;

上面的代码使用了 parsel bundler 因此,你可以在 iframe src 属性中使用 .pag 扩展,你甚至可以使用 .scssES6 在 iframe 中,在我的情况下,这基本上解决了 DIVI plugin 的问题。希望我的回答对大家有用