در هنگام کار با متغیرهای CSS ممکن است با همان مشکلاتی مواجه شویم که هنگام کار با خصوصیات CSS مواجه می شویم، منظور من از مشکلات خطرهایی است که هنگام کار با متغیرهای CSS در کمین ما هستند و ممکن است در دام آن ها بیفتیم. در این جلسه می خواهیم برخی از خطاهای رایج در متغیرهای CSS را بررسی کنیم.
منظور من از دستورات دوگانه، دستورات CSS ای هستند که دو یا چند بار برای یک خصوصیت تعریف شده اند. به مثال زیر نگاه کنید:
/*define the variables*/ :root { --color: blue; } div { --color: green; } #alert { --color: red; } /*use the variable */ * { color: var(--color); }
در اینجا برای متغیر رنگ 3 مقدار مختلف تعریف شده است. این اتفاق برخی اوقات در CSS نیز رخ میدهد. مسئله این است که متغیرها نیز پیرو قوانین آبشاری CSS هستند بنابراین به نظر شما عناصر زیر چه رنگی میگیرند؟
<p>What's my color?</p> <div>and me?</div> <div id='alert'> What's my color too? <p>color?</p> </div>
پاراگراف اول (تگ p) آبی (blue) خواهد بود؛ طبق قوانین آبشاری CSS از آنجایی که هیچ مقدار color-- مشخصی برای عنصر p تعریف نشده است، مقدار مورد نظر را از root: به ارث می برد:
:root { --color: blue; }
اولین div نیز سبز (green) خواهد بود چرا که مستقیما مقدارش را تعیین کرده ایم:
div { --color: green; }
آن div ای که آیدی alert دارد نیز قرمز (red) خواهد بود:
#alert { --color: red; }
طبق قوانین آبشاری CSS آیدی (id) بالاترین اولویت را دارد و بنابراین متغیر تعریف شده در آن نیز فقط مختص به آن است و دیگر مقادیر را override میکند.
عنصر p داخل alert# نیز قرمز می شود. از آنجایی که برای این عنصر مقدار مستقیمی تعریف نشده است احتمالا فکر میکردید که رنگ این عنصر آبی شود (از root: ارث بری کند) اما اینطور نیست. طبق قوانین آبشاری CSS عناصر از پدر خود ارث بری دارند بنابراین p نیز از alert# ارث بری میکند.
cyclic dependency یا وابستگی های چرخهای (یعنی به شکل یک چرخ یا حلقه) به دو شکل عمده اتفاق می افتند:
1- زمانی که متغیر به خودش وابسته باشد؛ یعنی از ()var استفاده کنیم که به خودش اشاره می کند:
:root { --m: var(--m) } body { margin: var(--m) }
2- زمانی که یک یا دو متغیر به یکدیگر اشاره می کنند:
:root { --one: calc(var(--two) + 10px); --two: calc(var(--one) - 10px); }
شما باید همیشه از این دو حالت دوری کنید و گرنه در کدهایتان با خطا مواجه می شوید.
سوال: متغیرهای غیرمعتبر به چه چیزی تبدیل می شوند؟
پاسخ: همانطور که می دانید خطاهای مربوط به syntax (طرز نوشتار کدها) توسط مرورگر نادیده گرفته می شود اما متغیرها و ()var های غیرمعتبر به مقدار initial یا inherit برمیگردند.
این مثال را در نظر بگیرید:
:root { --color: 20px; } p { background-color: red; } p { background-color: var(--color); }
در چنین مثالی مقدار رنگ پس زمینه برابر با 20 پیکسل می شود که معنی ندارد و از آنجایی که background-color خصوصیت قابل وراثتی نیست مقدار آن به initial یا transparent برمیگردد.
اگر همین کد را به شکل background-color: 20px بنویسید (بدون متغیر و به شکل ساده) مقدار رنگ پس زمینه غیرمعتبر محسوب می شد اما از دستور قبلی برای آن استفاده شده و رنگ آن قرمز (red) میشد.
زمانی که مقدار یک خصوصیت CSS را به صورت زیر تعیین می کنید:
font-size: 20px
به آن single token می گوییم. در واقع 20px به عنوان یک واحد مستقل محسوب می شود بنابراین نمی توان آن را از هم جدا کرد. با این اوصاف هنگام کار با متغیرهای CSS مراقب باشید تا به تقلید از زبان های برنامه نویسی دیگر کد را به شکل زیر ننویسید:
:root { --size: 20 } div { font-size: var(--size)px/*WRONG*/ }
این کد کاملا غلط است چرا که نمی توان 20px را از هم جدا کرد. مرورگر این کد را به شکل px و 20 میبیند (یعنی بین px و 20 یک اسپیس قرار میگیرد). بنابراین در هنگام کار با single token ها باید کل آن را درون متغیر قرار دهید یا اینکه از تابع calc استفاده کنید:
calc(var(--size) * 1px(
در این دستور می توانید مقدار متغیر size را روی 20 خالی بگذارید.
در پروژه ی اول میخواهیم دو دکمه بسازیم که با hover شدن رنگشان تغییر کند.
اگر بخواهیم به روش عادی CSS عمل کنیم کدهایمان بدین شکل می شود:
یعنی:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> .btn { padding: 2rem 4rem; border: 2px solid black; background: transparent; font-size: 0.6em; border-radius: 2px; } /*on hover */ .btn:hover { cursor: pointer; background: black; color: white; } </style> </head> <body> <button class="btn">Hello</button><button class="btn red">Hello</button> </body> </html>
اگر همین کد را با متغیرها بنویسیم:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> .btn { padding: 2rem 4rem; border: 2px solid var(--color, black); background: transparent; font-size: 0.6em; border-radius: 2px; } /*on hover*/ .btn:hover { cursor: pointer; background: var(--color, black); color: white; } </style> </head> <body> <button class="btn">Hello</button><button class="btn red">Hello</button> </body> </html>
آیا میدانید syntax این مورد چیست؟
background: var(--color, black)
در این حالت پارامتر دوم (black) حالت پیش فرض است؛ یعنی رنگ پس زمینه را روی color-- تنظیم کن اما اگر این متغیر وجود ندارد مقدار black را در نظر بگیر. بنابراین رنگ دکمه به راحتی هنگام hover تغییر پیدا می کند.
پروژه ی دوم ما پیشرفته تر است. در این پروژه میخواهیم چنین چیزی بسازیم. یعنی هنگام تایپ یک رنگ، مربع همان رنگ را بگیرد و با تکان دادن Slider نیز مربع ها به حالت سه بعدی جا به جا شوند.
کدهای HTML شامل سه قسمت می شوند:
بنابراین:
<body> <main class="booth"> <aside class="slider"> <label>Move this ? </label> <input class="booth-slider" type="range" min="-50" max="50" value="-50" step="5" /> </aside> <section class="color-boxes"> <div class="color-box" id="1"><input value="red" /></div> <div class="color-box" id="2"><input /></div> <div class="color-box" id="3"><input /></div> <div class="color-box" id="4"><input/> </div> <div class="color-box" id="5"><input /></div> <div class="color-box" id="6">;<input /></div> </section> <footer class="instructions"> ?? Move the slider<br /> ?? Write any color in the red boxes </footer> </main> </body>
کدهای CSS نیز به طور خلاصه باید این کارها را انجام دهند:
بنابراین:
@import url('https://fonts.googleapis.com/css?family=Shadows+Into+Light+Two'); :root { --primary-color: rgba(241,196,15 ,1); --secondary-color: teal; --slider: 0; } body { margin: 0; color: rgba(255,255,255,0.9); background: url('http://bit.ly/2FiPrRA') 0 100%/340px no-repeat, var(--primary-color); font-family: 'Shadows Into Light Two', cursive; } main.booth { min-height: 100vh; display: flex; justify-content: center; align-items: center; } /* Slider */ .slider, .instructions { position: absolute; background: rgba(0,0,0,0.4); padding: 1rem 2rem; border-radius: 5px } .slider { right: 10px; top: 10px; } .slider > * { display: block; } /* Instructions */ .instructions { text-align: center; bottom: 0; background: initial; color: black; } /* Color Boxes */ .color-boxes { background: red; box-shadow: 10px 10px 30px rgba(0,0,0,0.4); border-radius: 0.3rem; transform: perspective(500px) rotateY( calc(var(--slider) * 1deg)); transition: transform 0.3s } .color-box { padding: 1rem 3.5rem; margin-bottom: 0.5rem; border: 1px solid rgba(255,255,255,0.2); border-radius: 0.3rem; box-shadow: 10px 10px 30px rgba(0,0,0,0.4); } /* Handle colors for each color box */ .color-box:nth-child(1) { background: var(--bg-1) } .color-box:nth-child(2) { background: var(--bg-2) } .color-box:nth-child(3) { background: var(--bg-3) } .color-box:nth-child(4) { background: var(--bg-4) } .color-box:nth-child(5) { background: var(--bg-5) } .color-box:nth-child(6) { background: var(--bg-6) }
در آخر با استفاده از جاوا اسکریپت مقدار عنصر input (همان range) را گرفته و وضعیت مستطیل ها را به روز رسانی می کنیم:
const inputs = document.querySelectorAll('.color-box > input') const root = document.documentElement const range = document.querySelector('.booth-slider') //as slider range's value changes, do something range.addEventListener('input', handleSlider) //as the value in the input changes, do something. inputs.forEach(input => { input.addEventListener('input', handleInputChange) }) function handleInputChange (e) { let value = e.target.value let inputId = e.target.parentNode.id let inputBg = `--bg-${inputId}` root.style.setProperty(inputBg, value) } function handleSlider (e) { let value = e.target.value root.style.setProperty('--slider', value) }
امیدوارم مقاله بررسی خطاهای رایج در متغیرهای CSS به درک بهتر شما کمک کرده باشد.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.