في CSS الخالص، هل من الممكن تعيين هامش يساوي ارتفاع العنصر الحالي؟

StackOverflow https://stackoverflow.com//questions/21004707

  •  20-12-2019
  •  | 
  •  

سؤال

لدي مجموعة عمودية من العناصر التي يمكن للمستخدم إلحاق عنصر بها عن طريق النقر فوق الزر، مثل هذا تقريبًا.

<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 أو ما شابه ذلك للتعبير عما أريد للمتصفح.

اقتراحات؟

يحرر

أنا أستخدم قالبًا مع ربط متكرر لإضافة العناصر إلى القائمة.يقوم JS فقط بدفع كائن آخر إلى مصفوفة يمكن ملاحظتها، ويتعامل إطار العمل مع إدراج 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 فقط (باستخدام ترميز مكرر ورسوم متحركة أخرى)

إحدى الحيل المستخدمة غالبًا مع عمليات اختراق CSS فقط، هي تكرار الترميز - في هذه الحالة، الرابط نفسه - ووضعه داخل الأغلفة الأصلية التي سيتم تشغيلها أو إيقاف تشغيلها بوسائل مختلفة.الجوانب السلبية لهذه الطريقة هي أنك تحصل على علامة قبيحة إلى حد ما، وفي هذه الحالة بالذات يظهر رقم نقطي بشكل متناقض (بسبب الاضطرار إلى نقل الرسوم المتحركة العتامة من li إلى textarea).

لكن فوائد هذه الطريقة هي أنه من خلال نقل الرابط داخل الملف li يمكنك استخدام -100% على المحور ص باستخدام طريقة ترجمة أو إزاحة أخرى.من الغريب أنني لا أستطيع معرفة ماذا translateY(-100%) يتم الحساب على أساس... لا يبدو أنه الارتفاع الأصلي، ربما هو الارتفاع نفسه.لهذا السبب قمت بتحديث الكمان للاستخدام bottom والموضع النسبي بدلاً من ذلك، على الرغم من حدوث خلل لفترة وجيزة في Firefox (في نظام التشغيل Mac).

يبدو أن الأمر كذلك translateY يقوم بحساب النسبة المئوية بناءً على ارتفاعه، لذلك من أجل التغلب على هذه المشكلة، كان علي الاستفادة من الموضع المطلق وإجبار طبقة الارتباط على افتراض نفس الأبعاد مثل li...مزعج، لأنه يتضمن فهرسة z لملفات textarea فوق الارتباط، وداخلية 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>

المغلق:

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;
  }
}


إصدار جافا سكريبت (ترجمات الكود المحفزة)

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

من الواضح أن ما يلي لا يأخذ في الاعتبار حقيقة أنك تستخدم محرك قالب لتشغيل معالجات DOM الخاصة بك، ولكن كل ما تحتاجه التعليمات البرمجية للعمل بشكل صحيح هو ارتفاع القائمة قبل وبعده (لحساب الفرق في الارتفاع)، وحدث يتم تشغيله عند النقطة التي تتم فيها إضافة عنصر القائمة الجديد.

للأسف، ليس من الممكن حتى الآن القيام بكل هذا باستخدام CSS خالصًا، على الأقل ليس بقدر ما رأيت، ربما مرة واحدة calc وصل مستواه...؟أو ربما إذا تم تقديم طريقة ما للإشارة إلى أبعاد العناصر الحالية، وليس فقط الأصل المُقابل لها.

وتجدر الإشارة إلى أنه لم يكن لدي برنامج Internet Explorer لاختبار ذلك، لكن جميع المتصفحات الحديثة الأخرى تبدو سعيدة.

وضع علامة على:

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

جافا سكريبت (مع مسج):

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);
  });
});

المغلق:

.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;
  }
}


نسخة إعادة التصميم

لقد واجهت مشكلة مماثلة عدة مرات، فقط لأجد أن إعادة التصميم تساعد في التخلص من المشكلة ويمكنها في كثير من الأحيان تحسين سهولة الاستخدام.في حالتك، قد يكون من الأفضل وضع "رابط الإضافة" أعلى القائمة (أو أعلى اليمين)، أو دمج الزر كرمز عائم في مكان ما...أينما وضعتها، فمن الأفضل أن تحاول الاحتفاظ بها في مكان ثابت، فقد تكون نقاط التفاعل المتحركة مزعجة للمستخدمين، خاصة إذا كانوا يرغبون في إضافة أكثر من عنصر واحد في تتابع سريع.

example of top right link

نصائح أخرى

أبسط حل يمكن أن أفكر فيه هو هذا.

عند إضافة عنصر li جديد، ما عليك سوى إلحاقه في الدوم.

liMarkup = '<li><textarea></textarea></li>'
$('ol').append(liMarkup);
$('ol').find('li').last().css('display','none');
$('ol').find('li').last().show('fast');

هذا من شأنه أن يعمل وفقا لمتطلباتك :) وآمل أن يساعد.

عمل jsfiddle

يحرر:من السهل والأفضل القيام بذلك في JS.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top