草庐IT

html - 在纯 CSS 中,是否可以将边距设置为等于当前元素的高度?

coder 2023-08-02 原文

我有一个垂直的元素堆栈,用户可以通过单击一个按钮来附加一个元素,大致是这样的。

<ol>
  <li><textarea></textarea></li>
  <li><textarea></textarea></li>
</ol>
<a data-action="additem">Add another</a>

我正在尝试编写一个 CSS 动画,以便当新的 li插入后,“添加另一个”平稳地滑下到新的放置位置。 li 上的固定高度标签不是一个选项,我试图避免使用 max-height动画黑客,因为它可以有奇怪的布局效果。

我发现我可以制作动画 margin-bottom从某物到 0 并具有所需的效果,但我无法弄清楚如何在 CSS 中表达我想要应用此规则的元素的当前高度。百分比是相对于元素的宽度来衡量的,这不是我在这里需要的,而且我想不出使用 calc 的巧妙技巧。或者类似的东西来表达我想要的浏览器。

建议?

编辑

我正在使用带有重复绑定(bind)的模板将元素添加到列表中。 JS 只是将另一个对象插入一个 observable 数组,由框架处理实际的 DOM 插入。 li标签上有以下 CSS 以使其顺利进入:
animation: append forwards .5s;

append定义为:
@keyframes append {
    from {
        transform: translateX(10%);
        opacity: 0;
        margin-bottom: _____;
    }

    to {
        transform: none;
        opacity: 1;
        margin-bottom: 0;
    }
}

最佳答案

不是现在...

我多次遇到这个令人沮丧的问题,总是试图为非数字值设置动画,将当前元素的特定属性作为动画值访问,或者将未指定的值设置为指定的值。一般来说,我总是不得不退回到某种形式的不太完美 max-height动画(就像您已经提到的那样)或混合使用 CSS 和 JavaScript/jQuery。

对于您的问题,有几个选项,但没有一个是您所追求的。

仅 css 版本(使用重复标记和另一个动画)

  • http://jsfiddle.net/7m8F9/2/
  • http://jsfiddle.net/7m8F9/3/ <-- 改进版使用="">bottomposition:relative
  • http://jsfiddle.net/7m8F9/5/ <-- 更好的版本,回到="">translateY

  • 一个经常与 CSS-only hacks 一起使用的技巧是复制标记——在这种情况下,链接本身——并将其放置在父包装器中,这些包装器将通过不同的方式打开或关闭。这种方法的缺点是你得到了一个相当丑陋的标记,在这个特殊的例子中,一个子弹编号看起来很刺耳(因为必须将不透明度动画从 li 移动到 textarea )。

    然而,这种方法的好处是通过移动 li 内的链接。您可以使用 -100%在 y 轴上使用平移或其他偏移方法。奇怪的是,虽然我不知道是什么 translateY(-100%)计算基于......它似乎不是父高度,也许是它自己的高度。出于这个原因,我更新了 fiddle 以使用 bottom和相对定位,尽管在 Firefox 中(在 mac 上)这会短暂出现故障。

    似乎是translateY正在根据自己的高度计算百分比,因此为了解决这个问题,我不得不使用绝对位置并强制链接层采用与 li 相同的尺寸...烦人,因为它涉及对 textarea 进行 z 索引在链接上方,还有一个内部 span抵消链接文本,但至少它确实有效。

    下面的代码适用于最新的 Firefox,如果正确使用所有不同的浏览器前缀来定义动画关键帧,它也适用于其他现代浏览器,但是我现在没有时间将它们全部设置好。

    标记:
    <ol class="list">
      <li><textarea></textarea><a class="add" href="#"><span>Add another</span></a></li>
      <li><textarea></textarea><a class="add" href="#"><span>Add another</span></a></li>
    </ol>
    

    css:
    ol li {
      position: relative;
    }
    ol li .add {
      display: none;
    }
    ol li:last-child .add {
      position: absolute;
      left: 0;
      right: 0;
      bottom: 0;
      top: 0;
      width: 100%;
      height: 100%;
      display: block;
      animation-duration: 1s;
      animation-name: slide;
    }
    
    ol li:last-child .add span {
        position: absolute;
        bottom: -20px;
    }
    
    .list li textarea {
      position: relative;
      animation-duration: 1s;
      animation-name: append;
      z-index: 1;
    }
    
    @keyframes append {
      from {
        transform: translateX(10%);
        opacity: 0;
      }
      to {
        transform: none;
        opacity: 1;
      }
    }
    
    @keyframes slide {
      from {
        transform: translateY(-100%);
      }
      to {
        transform: none;
      }
    }
    

    javascript 版本(代码触发翻译)

    http://jsfiddle.net/7m8F9/1/

    以下显然没有考虑到您使用模板引擎来支持 DOM 操作的事实,但所有代码需要正常工作是列表的前后高度(计算高度差异),以及在添加新列表项时触发的事件。

    遗憾的是,目前还不可能在纯 CSS 中完成这一切,至少在我所见的范围内,可能只有一次 calc升级了……?或者,如果引入某种方式来引用当前元素尺寸,而不仅仅是它的偏移父级。

    It should be noted I didn't have Internet Explorer around to test this with, but all other modern browsers seem happy.



    标记:
    <ol class="list">
      <li><textarea></textarea></li>
      <li><textarea></textarea></li>
    </ol>
    <div class="add">
      <a href="#">Add another</a>
    </div>
    

    javascript(使用 jQuery):
    function prefix(){
      for ( var a = ['Webkit','Moz','O','ms'], i=0, l = a.length; i<l; i++ ) {
        if ( document.body.style[a[i]+'AnimationName'] !== undefined ) {
          return { js: a[i], css: '-' + a[i].toLowerCase() + '-' };
        }
      }
      return { css:'', js:'' };
    }
    
    $(function(){
      $('.add a').click(function(e){
        e.preventDefault();
        var pref = prefix(),
          link = $(this).parent(), 
          list = $('.list'),
          lihi = list.height(),
          liad = $('<li><textarea></textarea></li>').appendTo(list),
          lihd = lihi - list.height();
          link.css(pref.css + 'transform', 'translateY(' + lihd + 'px)');
        setTimeout(function(){link.addClass('translate-zero transition-all');},0);
        setTimeout(function(){
          link.css(pref.css + 'transform', '');
          link.removeClass('translate-zero transition-all');
        },500);
      });
    });
    

    css:
    .transition-all {
      -webkit-transition: all 0.5s;
      -moz-transition: all 0.5s;
      -ms-transition: all 0.5s;
      -o-transition: all 0.5s;
      transition: all 0.5s;
    }
    
    .translate-zero {
      -webkit-transform: translateY(0) !important;
      -moz-transform: translateY(0) !important;
      -ms-transform: translateY(0) !important;
      -o-transform: translateY(0) !important;
      transform: translateY(0) !important;
    }
    
    .list li {
      animation-duration: 1s;
      animation-name: append;
    }
    
    @keyframes append {
      from {
        transform: translateX(10%);
        opacity: 0;
      }
      to {
        transform: none;
        opacity: 1;
      }
    }
    

    重新设计版本

    很多次我都遇到过类似的问题,结果发现重新设计有助于解决这个问题,而且通常实际上可以提高可用性。在您的情况下,最好将“添加链接”放在列表上方(或右上 Angular ),或者将按钮作为 float 图标集成到某处……无论您把它放在哪里,最好尝试保留它在静态位置,移动交互点对用户来说可能很烦人,尤其是当他们希望快速连续添加多个元素时。

    关于html - 在纯 CSS 中,是否可以将边距设置为等于当前元素的高度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21004707/

    有关html - 在纯 CSS 中,是否可以将边距设置为等于当前元素的高度?的更多相关文章

    1. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

      我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

    2. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

      类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

    3. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

      给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

    4. ruby-openid:执行发现时未设置@socket - 2

      我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

    5. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

      我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

    6. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

      使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

    7. ruby - capybara field.has_css?匹配器 - 2

      我在MiniTest::Spec和Capybara中使用以下规范:find_field('Email').must_have_css('[autofocus]')检查名为“电子邮件”的字段是否具有autofocus属性。doc说如下:has_css?(path,options={})ChecksifagivenCSSselectorisonthepageorcurrentnode.据我了解,字段“Email”是一个节点,因此调用must_have_css绝对有效!我做错了什么? 最佳答案 通过JonasNicklas得到了答案:No

    8. ruby - 我可以使用 Ruby 从 CSV 中删除列吗? - 2

      查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html

    9. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

      我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

    10. ruby - 检查数组是否在增加 - 2

      这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife

    随机推荐