RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1553479
Accepted
Alexandr_TT
Alexandr_TT
Asked:2023-11-28 02:09:55 +0000 UTC2023-11-28 02:09:55 +0000 UTC 2023-11-28 02:09:55 +0000 UTC

为什么将 CSS 过滤器应用于父元素会破坏子元素的定位?

  • 772

因此,我有一个标题屏幕“动画”,其中标题标题位于全屏页面的中心,当我向下滚动时,它会变小并停留在页面顶部。这是一个具有预期行为的工作示例,我从中删除了所有不必要的代码以保持最少:

$(window).scroll( () => {
    "use strict";
    let windowH = $(window).height();
    let windowS = $(window).scrollTop();
    let header  = $("#header").height(); 
    
    if (windowS < windowH-header) {
        $("#title").css("transform", "scale("+(2-(windowS/($(document).outerHeight()-windowH))*2.7)+")");
        $("#header").css("transform", "translateY(0)");
        $("#inside, #content").css({
            "position": "static",
            "margin-top": 0
        });
    } else {
        $("#inside").css({
            "position": "fixed",
            "margin-top": -windowH+header
        });
        $("#content").css("margin-top", windowH);
    }
  
    $("#header").css("position", windowS > (windowH-header)/2 ? "fixed" :"static");
});
.fixed {
    position: fixed!important;
}
.wrapper {
    width: 100%;
    text-align: center;
}
.wrapper:before {
    display: table;
    content: " ";
}
.wrapper:after {
    clear: both;
}
#inside {
    width: 100%;
    height: 100vh;
    background-color: lightcoral;
    display: flex;
    align-items: center;
    justify-content: center;
}
#header {
    height: 90px;
    top: 0;
    position: sticky;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.5s;
}
#title {
    width: 100%;
    color: #fff;
    transform: scale(2);
}
#content {
    height: 1000px;
    background-color: lightblue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>  
    <div class="wrapper">
        <div id="inside">
            <div id="header">
                <h1 id="title">Title</h1>
            </div>
        </div>
    <div id="content"></div>
</body>

接下来是相同的片段,但添加了一个:我应用了一个过滤器,在我看来,这纯粹是装饰性的:filter: Brightness(1.3);。

正如您在下面看到的,当您滚动“动画”一半时,标题就会消失。当您检查该元素时,它仍然保留其所有属性,但不知何故它不在那里。同样的事情发生在 Firefox 和 Chrome 中,我不知道为什么。
如果有人能发布一个应用了过滤器的工作片段并解释为什么它之前不起作用,我将非常感激。

$(window).scroll( () => {
    "use strict";
    let windowH = $(window).height();
    let windowS = $(window).scrollTop();
    let header  = $("#header").height(); 
    
    if (windowS < windowH-header) {
        $("#title").css("transform", "scale("+(2-(windowS/($(document).outerHeight()-windowH))*2.7)+")");
        $("#header").css("transform", "translateY(0)");
        $("#inside, #content").css({
            "position": "static",
            "margin-top": 0
        });
    } else {
        $("#inside").css({
            "position": "fixed",
            "margin-top": -windowH+header
        });
        $("#content").css("margin-top", windowH);
    }
  
    $("#header").css("position", windowS > (windowH-header)/2 ? "fixed" :"static");
});
.fixed {
    position: fixed!important;
}
.wrapper {
    width: 100%;
    text-align: center;
}
.wrapper:before {
    display: table;
    content: " ";
}
.wrapper:after {
    clear: both;
}
#inside {
    width: 100%;
    height: 100vh;
    background-color: lightcoral;
    filter: brightness(1.3);        /*<<<<<<<<<<<<<<<<*/
    display: flex;
    align-items: center;
    justify-content: center;
}
#header {
    height: 90px;
    top: 0;
    position: sticky;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.5s;
}
#title {
    width: 100%;
    color: #fff;
    transform: scale(2);
}
#content {
    height: 1000px;
    background-color: lightblue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>  
    <div class="wrapper">
        <div id="inside">
            <div id="header">
                <h1 id="title">Title</h1>
            </div>
        </div>
    <div id="content"></div>
</body>

问题的免费翻译为什么将 CSS 过滤器应用于父元素会破坏子元素的定位?来自成员 @leonheess。

javascript
  • 3 3 个回答
  • 90 Views

3 个回答

  • Voted
  1. Best Answer
    puffleeck
    2023-11-28T10:04:03Z2023-11-28T10:04:03Z

    $(window).scroll( () => {
        "use strict";
        let windowH = $(window).height();
        let windowS = $(window).scrollTop();
        let header  = $("#header").height(); 
        
        if (windowS < windowH-header) {
            $("#title").css("transform", "scale("+(2-(windowS/($(document).outerHeight()-windowH))*2.7)+")");
            $("#header").css("transform", "translateY(0)");
            $("#inside, #content").css({
                "position": "static",
                "margin-top": 0
            });
        } else {
            $("#inside").css({
                "position": "fixed",
                "margin-top": -windowH+header
            });
            $("#content").css("margin-top", windowH);
        }
      
        $("#header").css("position", windowS > (windowH-header)/2 ? "fixed" :"static");
    });
    .fixed {
        position: fixed!important;
    }
    .wrapper {
        width: 100%;
        text-align: center;
    }
    .wrapper:before {
        display: table;
        content: " ";
    }
    .wrapper:after {
        clear: both;
    }
    #inside {
        width: 100%;
        height: 100vh;
        background-color: lightcoral;
        filter: brightness(1.3);        /*<<<<<<<<<<<<<<<<*/
        display: flex;
        align-items: center;
        justify-content: center;
    }
    #header {
        height: 90px;
        top: 250px;   /* !!!!!!!!!!!!!!
        по всплывашке на потолке в консоли, можно было
        догадаться, что оно уехало куда то вверх. FF 91.6
        а вот почему уехало... это уже хороший вопрос)))
        fixed fixed'у родитель, контейнер и запасной потолок :3
        похоже top: 0 то на край окна, то на край родителя
        тригерится, начхав на то, что тот fixed в обоих случаях.
        учитывая что он должен цепляться за окно только
        если родитель static... выходит вопрос не в том почему
        исчезал с фильтром, вопрос в том, почему не исчезал
        без него :3 */
        position: sticky;
        display: flex;
        align-items: center;
        justify-content: center;
        transition: all 0.5s;
    }
    #title {
        width: 100%;
        color: #fff;
        transform: scale(2);
    }
    #content {
        height: 1000px;
        background-color: lightblue;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <body>  
        <div class="wrapper">
            <div id="inside">
                <div id="header">
                    <h1 id="title">Title</h1>
                </div>
            </div>
        <div id="content"></div>
    </body>

    • 5
  2. HTO HOT
    2023-11-28T20:11:21Z2023-11-28T20:11:21Z

    不幸的是,我无法回答为什么它会这样工作的问题(也许这是一个错误,或者是修复某些错误的功能)。我试图弄清楚,显然, 的块充当filter了一种relative块,包括带有 的子块position:fixed。尽管该块本身filter具有position:static.

    const wrap = document.querySelector('.wrap');
    const someBlock = document.querySelector('.some-block');
    const toggleF = document.querySelector('button');
    const radioElems = document.querySelectorAll('input[name="position"]');
    radioElems.forEach(elem => {
        elem.addEventListener('change', (e) => {
            if (e.target.checked) {
                someBlock.style.position = e.target.value;
                if (e.target.value === 'static') {
                    someBlock.style.transform = 'translate(0,0)'
                } else {
                    someBlock.style.transform = 'translate(-50%,-50%)'
                }
            }
    
        })
    })
    toggleF.addEventListener('click', () => {
        wrap.classList.toggle('filter')
    })
    html,
    body {
        margin: 0;
        padding: 0;
    }
    
    .filter {
        filter: brightness(1.3);
    }
    
    .wrap {
        height: 100px;
        background-color: brown;
        width: 100%;
        position: static;
    }
    
    .some-block {
        color: blue;
        font-weight: 700;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        font-size: 20px;
        border: 2px black solid;
    }
    
    .long-block {
    
        height: 200vh;
        background-color: aqua;
    }
    <div class="wrap">
            <div class="some-block">Block</div>
        </div>
        <div class="long-block">
            <button>Toggle Filter</button>
            <div>
                <p>Свойство position для "some-block"</p>
                <div>
                    <label>absolute <input checked type="radio" value="absolute" name="position" id="absolute"></label>
                </div>
                <div>
                    <label>static <input type="radio" value="static" name="position" id="static"></label>
                </div>
                <div>
                    <label>fixed <input type="radio" value="fixed" name="position" id="fixed"></label>
                </div>
    
    
            </div>
    
        </div>

    我尝试修复此代码,但行为不同filter

    $(window).scroll( () => {
        "use strict";
        let windowH = $(window).height();
        let windowS = $(window).scrollTop();
        let header  = $("#header").height(); 
        
        if (windowS < windowH-header) {
            $("#title").css("transform", "scale("+(2-(windowS/($(document).outerHeight()-windowH))*2.7)+")");
            $("#header").css("transform", "translateY(0)");
            $("#inside, #content").css({
                "position": "static",
                "margin-top": 0
            });
        } else {
            $("#inside").css({
                "position": "fixed",
                "margin-top": -windowH+header
            });
            $("#content").css("margin-top", windowH);
        }
        //// Здесь просто удалил position fixed для header
    });
    .fixed {
        position: fixed!important;
    }
    .wrapper {
        width: 100%;
        text-align: center;
    }
    .wrapper:before {
        display: table;
        content: " ";
    }
    .wrapper:after {
        clear: both;
    }
    #inside {
        width: 100%;
        height: 100vh;
        background-color: lightcoral;
        filter: brightness(1.3);        /*<<<<<<<<<<<<<<<<*/
        display: flex;
        align-items: center;
        justify-content: center;
    }
    #header {
        height: 90px;
        top: 0;
        position: sticky;
        display: flex;
        align-items: center;
        justify-content: center;
        transition: all 0.5s;
    }
    #title {
        width: 100%;
        color: #fff;
        transform: scale(2);
    }
    #content {
        height: 1000px;
        background-color: lightblue;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <body>  
        <div class="wrapper">
            <div id="inside">
                <div id="header">
                    <h1 id="title">Title</h1>
                </div>
            </div>
        <div id="content"></div>
    </body>

    PS 经过一番谷歌搜索后,我发现了更多以相同方式工作的属性。例如,transform:translate(0,0)它还将更改子绝对或固定元素的行为。

    • 2
  3. Alexandr_TT
    2023-11-30T15:30:45Z2023-11-30T15:30:45Z

    如果您查看规范,您可以阅读:

    Значение свойства фильтра, отличное от none, приводит к созданию содержащего блока для потомков с абсолютным и фиксированным расположением, если только элемент, к которому оно применяется, не является корневым элементом документа в текущем контексте просмотра. Список функций применяется в указанном порядке.

    Это означает, что ваш элемент position:fixed будет позиционироваться относительно фильтруемого контейнера, а не относительно области просмотра. Другими словами, он все еще fixed, но внутри нового содержащего блока (фильтрованного контейнера).
    Вот упрощенная версия, иллюстрирующая проблему:

    .container {
      display: inline-block;
      width: 200px;
      height: 200vh;
      border: 1px solid;
    }
    
    .container>div {
      position: fixed;
      width: 100px;
      height: 100px;
      background: red;
      color: #fff;
    }
    <div class="container">
      <div>I am fixed on scroll</div>
    </div>
    
    <div class="container" style="filter:grayscale(1);">
      <div>I move with the scroll</div>
    </div>

    Чтобы решить эту проблему, попробуйте переместить фильтр в фиксированный элемент, а не в его контейнер:

    .container {
      display: inline-block;
      width: 200px;
      height: 200vh;
      border: 1px solid;
    }
    
    .container>div {
      position: fixed;
      width: 100px;
      height: 100px;
      background: red;
      color: #fff;
      filter: grayscale(1);
    }
    <div class="container">
      <div>I am fixed on scroll</div>
    </div>

    Вот неполный1 список свойств, который приводит к созданию содержащего блока для абсолютных и фиксированных потомков:

    • filter
    • transform ref
    • backdrop-filter ref
    • perspective ref
    • contain ref
    • container ref
    • transform-style ref
    • content-visibility ref
    • will-change при использовании с одним из вышеуказанных значений

    Если какое-либо не начальное значение свойства приведет к тому, что элемент сгенерирует содержащий блок для абсолютно позиционированных элементов, указание этого свойства в will-change должно привести к тому, что элемент сгенерирует содержащий блок для абсолютно позиционированных элементов. ref


    1: Я постараюсь поддерживать этот список в актуальном состоянии..

    PS

    Перевод наиболее значимых комментариев:

    @MiXT4PE это определено в спецификации, так что так и должно быть. Вы, вероятно, можете спросить, почему они определяют это именно так ... Я почти уверен, что за этим выбором стоит причина (вероятно, сложная). – @Temani Afif

    @ygoe во-первых, это не bug, это задумано, как и многие функции, которые нам не нравятся, но с которыми мы должны работать (очистить плавающее пространство, схлопывать поля и т. д.), поэтому вам следует адаптировать свой код, чтобы преодолеть это. Универсального решения не существует, но в зависимости от вашего случая наверняка найдется решение. Вы можете задать вопрос, добавив свой конкретный код, чтобы посмотреть, сможем ли мы изменить вашу логику, чтобы удовлетворить ваши требования и решить проблему. – @Temani Afif

    Свободный перевод ответа от участника @Temani Afif.

    • 1

相关问题

  • 第二个 Instagram 按钮的 CSS 属性

  • 由于模糊,内容不可见

  • 弹出队列。消息显示不正确

  • 是否可以在 for 循环中插入提示?

  • 如何将 JSON 请求中的信息输出到数据表 Vuetify vue.js?

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5