আমি জানি এটি এই প্রশ্নের ত্রিশতম উত্তর, তবে আমি মনে করি এটি মূল্যবান, সুতরাং এখানে চলে যায় goes এটি নিম্নলিখিত বৈশিষ্ট্যগুলির সাথে একটি সিএসএস-কেবল সমাধান:
- শুরুতে কোনও বিলম্ব নেই, এবং রূপান্তরটি প্রথম দিকে থামবে না। উভয় দিকনির্দেশে (প্রসারণ এবং ধসে পড়া), আপনি যদি নিজের সিএসএসে 300 মাইলের একটি রূপান্তর সময় নির্দিষ্ট করে থাকেন, তবে স্থানান্তরটি 300 মিমি, সময়কাল গ্রহণ করে।
- এটি প্রকৃত উচ্চতাকে রূপান্তরিত করছে (বিপরীতে
transform: scaleY(0)
), তাই সংযোগযোগ্য উপাদানগুলির পরে সামগ্রী থাকলে সঠিক কাজটি করে।
- যদিও (অন্যান্য সমাধান মত) সেখানে আছে যাদু সংখ্যা (মত "দৈর্ঘ্য বেশী আপনার বাক্স কি কখনো হতে যাচ্ছে যে বাছাই"), তাই না মারাত্মক যদি আপ ভুল হচ্ছে আপনার ধৃষ্টতা প্রান্ত। সেক্ষেত্রে রূপান্তরটি আশ্চর্যজনক নাও লাগতে পারে, তবে সংক্রমণের আগে এবং পরে, এটি কোনও সমস্যা নয়: প্রসারিত (
height: auto
) অবস্থায়, পুরো সামগ্রীতে সর্বদা সঠিক উচ্চতা থাকে (উদাহরণস্বরূপ, যদি আপনি কোনওটিকে বেছে max-height
নেন তবে অনেক কম). এবং ধসে পড়া অবস্থায়, উচ্চতাটি শূন্যের মতো হওয়া উচিত।
ডেমো
এখানে তিনটি সঙ্কুচিত উপাদানগুলির সাথে একটি ডেমো রয়েছে যা বিভিন্ন উচ্চতা সমস্তই একই সিএসএস ব্যবহার করে। আপনি "স্নিপেট চালান" ক্লিক করার পরে "পুরো পৃষ্ঠাতে" ক্লিক করতে চাইতে পারেন। নোট করুন যে জাভাস্ক্রিপ্টটি কেবল collapsed
CSS ক্লাসকে টোগল করে , এতে কোনও পরিমাপ জড়িত থাকে না। (আপনি কোনও চেকবক্স ব্যবহার করে বা কোনও জাভাস্ক্রিপ্ট ছাড়াই এই সঠিক ডেমোটি করতে পারেন :target
)) এছাড়াও লক্ষ করুন যে সিএসএসের যে অংশটি রূপান্তরটির জন্য দায়ী তা বেশ সংক্ষিপ্ত এবং এইচটিএমএলকে কেবলমাত্র একটি অতিরিক্ত অতিরিক্ত মোড়কের উপাদান প্রয়োজন।
$(function () {
$(".toggler").click(function () {
$(this).next().toggleClass("collapsed");
$(this).toggleClass("toggled"); // this just rotates the expander arrow
});
});
.collapsible-wrapper {
display: flex;
overflow: hidden;
}
.collapsible-wrapper:after {
content: '';
height: 50px;
transition: height 0.3s linear, max-height 0s 0.3s linear;
max-height: 0px;
}
.collapsible {
transition: margin-bottom 0.3s cubic-bezier(0, 0, 0, 1);
margin-bottom: 0;
max-height: 1000000px;
}
.collapsible-wrapper.collapsed > .collapsible {
margin-bottom: -2000px;
transition: margin-bottom 0.3s cubic-bezier(1, 0, 1, 1),
visibility 0s 0.3s, max-height 0s 0.3s;
visibility: hidden;
max-height: 0;
}
.collapsible-wrapper.collapsed:after
{
height: 0;
transition: height 0.3s linear;
max-height: 50px;
}
/* END of the collapsible implementation; the stuff below
is just styling for this demo */
#container {
display: flex;
align-items: flex-start;
max-width: 1000px;
margin: 0 auto;
}
.menu {
border: 1px solid #ccc;
box-shadow: 0 1px 3px rgba(0,0,0,0.5);
margin: 20px;
}
.menu-item {
display: block;
background: linear-gradient(to bottom, #fff 0%,#eee 100%);
margin: 0;
padding: 1em;
line-height: 1.3;
}
.collapsible .menu-item {
border-left: 2px solid #888;
border-right: 2px solid #888;
background: linear-gradient(to bottom, #eee 0%,#ddd 100%);
}
.menu-item.toggler {
background: linear-gradient(to bottom, #aaa 0%,#888 100%);
color: white;
cursor: pointer;
}
.menu-item.toggler:before {
content: '';
display: block;
border-left: 8px solid white;
border-top: 8px solid transparent;
border-bottom: 8px solid transparent;
width: 0;
height: 0;
float: right;
transition: transform 0.3s ease-out;
}
.menu-item.toggler.toggled:before {
transform: rotate(90deg);
}
body { font-family: sans-serif; font-size: 14px; }
*, *:after {
box-sizing: border-box;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<div class="menu">
<div class="menu-item">Something involving a holodeck</div>
<div class="menu-item">Send an away team</div>
<div class="menu-item toggler">Advanced solutions</div>
<div class="collapsible-wrapper collapsed">
<div class="collapsible">
<div class="menu-item">Separate saucer</div>
<div class="menu-item">Send an away team that includes the captain (despite Riker's protest)</div>
<div class="menu-item">Ask Worf</div>
<div class="menu-item">Something involving Wesley, the 19th century, and a holodeck</div>
<div class="menu-item">Ask Q for help</div>
</div>
</div>
<div class="menu-item">Sweet-talk the alien aggressor</div>
<div class="menu-item">Re-route power from auxiliary systems</div>
</div>
<div class="menu">
<div class="menu-item">Something involving a holodeck</div>
<div class="menu-item">Send an away team</div>
<div class="menu-item toggler">Advanced solutions</div>
<div class="collapsible-wrapper collapsed">
<div class="collapsible">
<div class="menu-item">Separate saucer</div>
<div class="menu-item">Send an away team that includes the captain (despite Riker's protest)</div>
</div>
</div>
<div class="menu-item">Sweet-talk the alien aggressor</div>
<div class="menu-item">Re-route power from auxiliary systems</div>
</div>
<div class="menu">
<div class="menu-item">Something involving a holodeck</div>
<div class="menu-item">Send an away team</div>
<div class="menu-item toggler">Advanced solutions</div>
<div class="collapsible-wrapper collapsed">
<div class="collapsible">
<div class="menu-item">Separate saucer</div>
<div class="menu-item">Send an away team that includes the captain (despite Riker's protest)</div>
<div class="menu-item">Ask Worf</div>
<div class="menu-item">Something involving Wesley, the 19th century, and a holodeck</div>
<div class="menu-item">Ask Q for help</div>
<div class="menu-item">Separate saucer</div>
<div class="menu-item">Send an away team that includes the captain (despite Riker's protest)</div>
<div class="menu-item">Ask Worf</div>
<div class="menu-item">Something involving Wesley, the 19th century, and a holodeck</div>
<div class="menu-item">Ask Q for help</div>
</div>
</div>
<div class="menu-item">Sweet-talk the alien aggressor</div>
<div class="menu-item">Re-route power from auxiliary systems</div>
</div>
</div>
এটা কিভাবে কাজ করে?
বাস্তবে এটি ঘটানোর সাথে সাথে দুটি রূপান্তর জড়িত। এর মধ্যে একটি margin-bottom
0px (প্রসারিত অবস্থায়) থেকে -2000px
ধসে পড়া অবস্থায় ( এই উত্তরের সমান ) রূপান্তর করে । 2000 এখানে প্রথম যাদু নম্বর, এটি আপনার বাক্স এর চেয়ে বেশি হবে না এই ধারণার উপর ভিত্তি করে (2000 পিক্সেল যুক্তিসঙ্গত পছন্দ বলে মনে হচ্ছে)।
margin-bottom
একাই নিজে থেকে রূপান্তরটি ব্যবহার করার দুটি বিষয় রয়েছে:
- যদি আপনার কাছে আসলে এমন একটি বাক্স থাকে যা 2000 পিক্সেলের চেয়ে বেশি হয়, তবে এটি
margin-bottom: -2000px
সমস্ত কিছু আড়াল করবে না - ধসে পড়ে যাওয়া ক্ষেত্রে এমনকি দৃশ্যমান স্টাফ থাকবে। এটি একটি ছোট্ট ফিক্স যা আমরা পরে করব।
- যদি প্রকৃত বাক্সটি বলে, 1000 পিক্সেল উঁচু, এবং আপনার রূপান্তর 300 মিটার দীর্ঘ হয়, তবে দৃশ্যমান রূপান্তরটি প্রায় 150 মিটার পরে ইতিমধ্যে শেষ হয়ে গেছে (বা, বিপরীত দিকে, 150 মিটার দেরিতে শুরু হবে)।
এই দ্বিতীয় ইস্যুটি ঠিক করা যেখানে দ্বিতীয় ট্রানজিশনটি আসে এবং এই রূপান্তরটি আদর্শভাবে মোড়কের নূন্যতম উচ্চতাকে লক্ষ্য করে ("ধারণাগতভাবে" কারণ আমরা আসলে এর min-height
জন্য সম্পত্তি ব্যবহার করছি না ; তারপরে আরও)।
এখানে একটি অ্যানিমেশন যা দেখায় যে নীচের মার্জিন রূপান্তরকে ন্যূনতম উচ্চতা ট্রানজিশনের সাথে কীভাবে সংযুক্ত করা হয়, উভয় সমতুল্য সময়কালই আমাদের পূর্ণ উচ্চতা থেকে শূন্য উচ্চতায় একত্রিত রূপান্তর দেয় যা একই সময়কালে রয়েছে।
বাম বারটি দেখায় যে নেতিবাচক নীচের মার্জিনটি দৃশ্যমান উচ্চতা হ্রাস করে নীচে উপরের দিকে কীভাবে চাপ দেয়। মাঝের বারটি দেখায় যে ন্যূনতম উচ্চতা কীভাবে নিশ্চিত হয় যে সংঘর্ষের ক্ষেত্রে, সংক্রমণটি খুব শীঘ্রই শেষ হয় না এবং প্রসারণের ক্ষেত্রে, স্থানান্তর দেরিতে শুরু হয় না। ডান দণ্ডটি দেখায় যে কীভাবে দুটির সংমিশ্রণটি বক্সকে সঠিক উচ্চতায় পুরো উচ্চতা থেকে শূন্য উচ্চতায় স্থানান্তরিত করে।
আমার ডেমোর জন্য আমি উপরের সর্বনিম্ন উচ্চতার মান হিসাবে 50px এ স্থির হয়েছি। এটি দ্বিতীয় যাদু নম্বর, এবং এটি বাক্সের উচ্চতার চেয়ে কম হওয়া উচিত। 50px পাশাপাশি যুক্তিসঙ্গত বলে মনে হয়; এটি অসম্ভব বলে মনে হয় যে আপনি প্রায়শই এমন একটি উপাদানকে সংযোগযোগ্য করে তুলতে চান যা প্রথম স্থানের চেয়ে 50 পিক্সেল বেশি নয়।
অ্যানিমেশনটিতে আপনি দেখতে পাচ্ছেন, ফলস্বরূপ পরিবর্তনটি অবিচ্ছিন্ন, তবে এটি পৃথক নয় - এই মুহুর্তে যখন ন্যূনতম উচ্চতা নীচের মার্জিনের সাথে সামঞ্জস্য করা পূর্ণ উচ্চতার সমান হয় তখন গতিতে হঠাৎ পরিবর্তন ঘটে। এটি অ্যানিমেশনটিতে খুব লক্ষণীয় কারণ এটি উভয় ট্রানজিশনের জন্য লিনিয়ার টাইমিং ফাংশন ব্যবহার করে এবং পুরো রূপান্তরটি খুব ধীর গতির কারণে। প্রকৃত ক্ষেত্রে (শীর্ষে আমার ডেমো), রূপান্তরটি কেবল 300 মিমি নেয় এবং নীচের প্রান্তিক রূপান্তরটি লিনিয়ার নয়। আমি উভয় স্থানান্তরের জন্য বিভিন্ন সময়সীমার সাথে প্রচুর পরিমাণে খেলা করেছি এবং যেগুলি আমি শেষ করেছিলাম তারা মনে করেছিল যে তারা বিস্তৃত বিভিন্ন ক্ষেত্রে সবচেয়ে ভাল কাজ করেছে।
দুটি সমস্যার সমাধান করতে বাকি রয়েছে:
- উপরের দিকটি, যেখানে ২০০০ পিক্সেলের বেশি উচ্চতার বাক্সগুলি ধসে পড়া অবস্থায় পুরোপুরি গোপন নেই,
- এবং বিপরীত সমস্যা যেখানে অ গোপনীয় ক্ষেত্রে, 50 পিক্সেলের চেয়ে কম উচ্চতার বাক্সগুলি ট্রানজিশনটি চলমান না হওয়া সত্ত্বেও খুব বেশি হয়, কারণ সর্বনিম্ন উচ্চতা তাদের 50 পিক্সেলে রাখে।
আমরা প্রথমে সমস্যার সমাধান করে কনটেইনার উপাদানটিকে max-height: 0
ধসে পড়ার ক্ষেত্রে একটি 0s 0.3s
রূপান্তর দিয়ে the এর অর্থ এটি সত্যই কোনও রূপান্তর নয়, তবে max-height
বিলম্বের সাথে প্রয়োগ করা হয়; রূপান্তরটি শেষ হয়ে গেলেই এটি প্রয়োগ হয়। এটি সঠিকভাবে কাজ করার max-height
জন্য, আমাদের বিপরীত, নষ্ট না হওয়া, রাষ্ট্রের জন্য একটি সংখ্যাও বাছাই করতে হবে । তবে 2000px ক্ষেত্রে বিপরীতে, যেখানে সংখ্যার বেশি সংখ্যক বাছাই করা স্থানান্তরের মানকে প্রভাবিত করে, এক্ষেত্রে, এটি সত্যিই কিছু যায় আসে না। সুতরাং আমরা কেবল এমন একটি সংখ্যা বাছাই করতে পারি যা এত বেশি যে আমরা জানি যে কোনও উচ্চতা এর কাছাকাছি আসতে পারবে না। আমি এক মিলিয়ন পিক্সেল বাছাই করেছি। আপনি যদি মনে করেন আপনার মিলিয়ন পিক্সেলের বেশি উচ্চতার সামগ্রীর সমর্থন করতে পারে তবে 1) আমি দুঃখিত, এবং 2) কেবল কয়েক শূন্য যোগ করুন।
দ্বিতীয় সমস্যা হ'ল কারণ আমরা আসলে ব্যবহার করছি না min-height
ন্যূনতম উচ্চতার রূপান্তরের জন্য । পরিবর্তে, ::after
ধারকটিতে একটি সিউডো-উপাদান রয়েছে যা height
50px থেকে শূন্যে রূপান্তর করে। এটির মতো একই প্রভাব রয়েছে min-height
: এটি সিউডো-এলিমেন্টের বর্তমানে যে উচ্চতার নীচে কন্টেইনারটি সঙ্কুচিত হতে দেবে না। তবে যেহেতু আমরা ব্যবহার করছি height
, তা নয় min-height
, আমরা এখন max-height
সিউডো-এলিমেন্টের আসল উচ্চতা শূন্যে সেট করার জন্য সিউডো-এলিমেন্টের প্রকৃত উচ্চতা শূন্যে সেট করতে ব্যবহার করতে পারি , অন্তত রূপান্তরের বাইরে এমনকি ছোট উপাদানগুলিরও নিশ্চিত হয়ে থাকে সঠিক উচ্চতা কারণ min-height
হল শক্তিশালী চেয়ে max-height
, এই যদি আমরা ধারক এর ব্যবহৃত কাজ করবে না । ঠিক যেমনmin-height
পরিবর্তে সিউডো-উপাদান এরheight
max-height
পূর্ববর্তী অনুচ্ছেদে, max-height
এর উত্তরণের বিপরীত প্রান্তের জন্যও একটি মান প্রয়োজন। তবে এই ক্ষেত্রে আমরা কেবল 50px বাছাই করতে পারি।
ক্রোমে পরীক্ষিত (উইন, ম্যাক, অ্যান্ড্রয়েড, আইওএস), ফায়ারফক্স (উইন, ম্যাক, অ্যান্ড্রয়েড), এজ, আইই ১১ (আমার ডেমোতে একটি ফ্লেক্সবক্স লেআউট ইস্যু ছাড়া যে আমি ডিবাগিংয়ে বিরক্ত করি নি), এবং সাফারি (ম্যাক, আইওএস) )। ফ্লেক্সবক্সের কথা বলতে গেলে কোনও ফ্লেক্সবক্স ব্যবহার না করেই এই কাজটি করা সম্ভব হওয়া উচিত; আসলে আমি মনে করি আপনি প্রায় সবই আই 7 তে কাজ করতে পারবেন - আপনার সিএসএস রূপান্তর হবে না তা বাদ দিয়ে একে একে অর্থহীন অনুশীলন করে তোলা।
height:auto/max-height
সমাধানটি কেবল তখনই কাজ করবে যদি আপনিheight
সীমাবদ্ধ করতে চান এমন অঞ্চলটি আপনি বাড়িয়ে তোলেন। আপনি যদি একটি থাকে তাহলেmax-height
এর300px
, কিন্তু একটি কম্বো বাক্স ড্রপডাউন, যা আসতে পারেন50px
, তাহলেmax-height
আপনাকে সাহায্য করবে না,50px
উপাদান সংখ্যার উপর নির্ভর করে পরিবর্তনশীল, আপনি একটি অসম্ভব অবস্থা যেখানে আমি এটা ঠিক করতে পারবেন না পৌঁছা যাবে না কারণheight
নয় স্থির,height:auto
সমাধান ছিল, কিন্তু আমি এটি দিয়ে ট্রানজিশন ব্যবহার করতে পারি না।