تکنیکهای تکمیلی CSS
هر چیزی که برای ساختن یک سایت حرفهای لازم است و تا اینجا نگفته بودیم. این فصل، پل ارتباطی بین دانش پایه شما و پروژه نهایی فصل بعد است.
۱. متغیرهای CSS
تا اینجا هر بار رنگ سایت را دستی نوشتیم. اگر بخواهید رنگ اصلی سایتتان را عوض کنید، باید دهها جا را تغییر دهید و حتماً یکی دو مورد را فراموش میکنید. متغیر این مشکل را کاملاً حل میکند.
:root {
--primary: #2f4f4f;
--primary-dark: #223a3a;
--accent: #ff6347;
--bg-light: #f5f5f5;
--text: #333333;
--muted: #777777;
--border: #e0e0e0;
--radius: 10px;
--space: 20px;
}
body {
background-color: var(--bg-light);
color: var(--text);
}
.btn {
background-color: var(--primary);
border-radius: var(--radius);
padding: 12px var(--space);
}
.btn:hover {
background-color: var(--accent);
}
متغیرها: نمونه 01-css-variables
شرح مثال
-
root:یک شبهکلاس است که به ریشه سند اشاره میکند، یعنی تگhtml. متغیرهایی که اینجا تعریف شوند، در کل صفحه در دسترساند. - نام هر متغیر حتماً با دو خط تیره شروع میشود. این اجباری است، نه سلیقهای.
-
برای استفاده، نام متغیر را داخل
var()میگذاریم.
حالا برای عوض کردن رنگ اصلی کل سایت، تنها یک خط در بالای فایل تغییر میکند و همه جا با هم بهروز میشود.
هر چیزی که بیش از دو بار تکرار میشود: رنگها، گردی گوشهها، فاصله استاندارد، سایهها. اگر عددی تنها یک بار در کل فایل استفاده میشود، نیازی به متغیر ندارد.
۲. سایه
سایه به عنصرها عمق میدهد و باعث میشود کارتها انگار روی صفحه شناور باشند. این سادهترین راه حرفهایتر کردن یک طرح است.
.card {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.card-hover {
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
}
.inner {
box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.2);
}
.title {
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
}
سایه: نمونه 02-shadow
شرح مثال
box-shadow چهار مقدار میگیرد:
| مقدار | معنی |
|---|---|
| اول | جابهجایی افقی سایه |
| دوم | جابهجایی عمودی. مثبت یعنی سایه به پایین. |
| سوم | میزان محو شدن. عدد بزرگتر یعنی سایه نرمتر. |
| چهارم | رنگ سایه |
کلمه inset در ابتدا، سایه را به داخل جعبه میبرد و حس فرورفتگی میدهد. text-shadow هم دقیقاً همینطور کار میکند اما برای متن، و مقدار inset ندارد.
سایههای زیبا ملایم هستند. از رنگ سیاه با
شفافیت کم استفاده کنید، نه از خاکستری توپر.
rgba(0, 0, 0, 0.1) یعنی سیاه با ده درصد ماندگاری،
که زیر آن هر رنگی باشد طبیعی به نظر میرسد.
سایههای تیره و تند، طرح را قدیمی نشان میدهند.
۳. گرادیانت و شفافیت
.gradient {
background-image: linear-gradient(to left, #2f4f4f, #ff6347);
}
.faded {
opacity: 0.5;
}
.overlay-photo {
background-image:
linear-gradient(rgba(20, 40, 40, 0.7), rgba(20, 40, 40, 0.7)),
url('images/school.jpg');
background-size: cover;
background-position: center;
color: white;
}
گرادیانت و شفافیت: نمونه 03-gradient-opacity
شرح مثال
linear-gradient یک تصویر میسازد که از یک رنگ به رنگ
دیگر محو میشود. اولین مقدار جهت است و بقیه رنگها.
چون یک تصویر است، در background-image نوشته میشود،
نه در background-color.
opacity شفافیت کل عنصر را تنظیم میکند: عدد ۱ یعنی کاملاً مات و ۰ یعنی کاملاً نامرئی. نکته مهم اینکه این ویژگی روی همه چیز اثر میگذارد، از جمله متن داخل عنصر. اگر تنها پسزمینه را میخواهید شفاف کنید، از rgba استفاده کنید.
rgba همان rgb است با یک عدد چهارم:
میزان ماندگاری از صفر تا یک. پس
rgba(0, 0, 0, 0.5) یعنی سیاه نیمهشفاف.
بخش سوم مثال، تکنیکی است که تقریباً هر سایتی از آن استفاده میکند: پرده تیره روی عکس. یک گرادیانت که هر دو رنگش یکسان و نیمهشفاف است، مانند یک شیشه دودی روی عکس عمل میکند. نتیجهاش این است که متن سفید روی هر عکسی خوانا میماند. دقت کنید که گرادیانت قبل از عکس نوشته میشود، چون لایههای پسزمینه از بالا به پایین چیده میشوند. در فصل بعد دقیقاً از همین کد برای هدر پروژه استفاده میکنیم.
۴. transform
.move {
transform: translateY(-5px);
}
.grow {
transform: scale(1.05);
}
.rotate {
transform: rotate(5deg);
}
.combined {
transform: translateY(-5px) scale(1.03);
}
.card {
transition: transform 0.3s ease;
}
.card:hover {
transform: translateY(-8px);
}
transform: نمونه 04-transform
شرح مثال
| تابع | کارش |
|---|---|
translateX و translateY | جابهجایی افقی و عمودی |
scale | بزرگ یا کوچک کردن. عدد ۱ یعنی اندازه اصلی. |
rotate | چرخاندن بر حسب درجه |
میشود چند تابع را با فاصله پشت سر هم نوشت و همه با هم اعمال میشوند. اما دقت کنید که نمیتوانید دو خط transform جدا بنویسید؛ دومی اولی را پاک میکند.
برای بالا بردن یک کارت میشد margin-top منفی هم داد، اما آن کار باعث میشود بقیه عنصرهای صفحه جابهجا شوند و چیدمان تکان بخورد. transform تنها نمایش عنصر را عوض میکند و جای واقعیاش دستنخورده میماند. بهعلاوه مرورگر برای آن از کارت گرافیک استفاده میکند و حرکت بسیار نرمتر است.
transform تقریباً همیشه همراه transition
و hover: میآید. سه خط آخر مثال، پرکاربردترین
الگوی افکت کارت در کل طراحی وب است.
۵. object-fit و calc
.card-image {
width: 100%;
height: 200px;
object-fit: cover;
}
.logo {
width: 100px;
height: 100px;
object-fit: contain;
}
.full-bleed {
width: calc(100% + 40px);
margin-right: -20px;
margin-left: -20px;
}
.main-area {
width: calc(100% - 250px);
}
object-fit و calc: نمونه 05-object-fit-calc
شرح مثال
مشکل: در یک ردیف کارت، عکسها اندازههای مختلفی دارند و کارتها نامرتب میشوند. اگر عرض و ارتفاع ثابت بدهید، عکسها کشیده و بدشکل میشوند.
راهحل: object-fit که دقیقاً مانند background-size عمل میکند، اما روی تگ img:
-
coverکادر را کامل پر میکند و نسبت تصویر را حفظ میکند. لبهها بریده میشوند. برای عکس کارتها همیشه همین را بخواهید. -
containکل تصویر را نشان میدهد و ممکن است فضای خالی بماند. برای لوگو مناسب است.
calc() اجازه میدهد داخل CSS محاسبه کنید، حتی بین واحدهای متفاوت. این کاری است که هیچ راه دیگری برای انجامش نیست: مرورگر نمیداند صد درصد چند پیکسل است، اما calc در لحظه نمایش حسابش میکند.
calc(100% - 250px) درست است، اما calc(100%-250px) اصلاً کار نمیکند. دور علامتهای جمع و تفریق حتماً باید فاصله باشد.
ترکیب calc با حاشیه منفی، تکنیک «تصویر تمامعرض کارت»
را میسازد: تصویر از لبه تا لبه کارت کشیده میشود و
padding کارت را نادیده میگیرد.
۶. شبهکلاسهای پیشرفته
تا اینجا تنها hover: و focus: را دیدیم. چند شبهکلاس دیگر هم هستند که بر اساس جایگاه عنصر انتخاب میکنند.
li:first-child {
font-weight: bold;
}
li:last-child {
border-bottom: none;
}
tr:nth-child(odd) {
background-color: #f7f7f7;
}
tr:nth-child(even) {
background-color: white;
}
li:nth-child(3) {
color: #ff6347;
}
input:focus {
border-color: #2f4f4f;
}
.btn:active {
transform: scale(0.97);
}
شبهکلاسهای پیشرفته: نمونه 06-pseudo-class-advanced
شرح مثال
| شبهکلاس | انتخاب میکند |
|---|---|
:first-child | اولین فرزند والدش |
:last-child | آخرین فرزند |
:nth-child(odd) | فرزندان فرد: اول، سوم، پنجم |
:nth-child(even) | فرزندان زوج |
:nth-child(3) | دقیقاً سومی |
:focus | عنصری که نشانگر داخلش است |
:active | لحظهای که کاربر کلیک را نگه داشته |
nth-child(odd): پرکاربردترینشان است و جدول راهراه میسازد که خواندن سطرهایش بسیار آسانتر است. last-child: هم برای برداشتن خط جداکننده آخرین مورد یک فهرست عالی است، تا خط اضافهای زیر فهرست نماند.
active: حس فشرده شدن دکمه را میدهد. کوچک کردن بسیار جزئی دکمه در لحظه کلیک، بازخوردی است که کاربر آن را نمیبیند اما حس میکند.
۷. شبهعنصرها
شبهکلاس یک عنصر موجود را انتخاب میکند. شبهعنصر یک قطعه تازه میسازد که در HTML وجود ندارد. علامتش دو تا دو نقطه است.
.section-title {
position: relative;
padding-bottom: 12px;
}
.section-title::after {
content: "";
position: absolute;
right: 0;
bottom: 0;
width: 60px;
height: 4px;
background-color: var(--accent);
border-radius: 2px;
}
.new-card::before {
content: "جدید";
position: absolute;
top: 10px;
left: 10px;
background-color: var(--accent);
color: white;
padding: 4px 12px;
border-radius: 20px;
font-size: 13px;
}
.check-list li::before {
content: "✔ ";
color: green;
}
شبهعنصرها: نمونه 07-pseudo-element
شرح مثال
-
before::قطعهای قبل از محتوای عنصر میسازد وafter::بعد از آن. - ویژگی
contentاجباری است. بدون آن، شبهعنصر اصلاً ساخته نمیشود، حتی اگر ده خط استایل دیگر برایش بنویسید. اگر تنها شکل میخواهید و نه متن، بنویسیدcontent: "". -
شبهعنصر بخشی از عنصر والد است، پس با
position: absoluteداخل والدِrelativeجای میگیرد. همان الگوی فصل نهم.
آن خط تزیینی نارنجی زیر عنوانها، بدون شبهعنصر نیاز به یک div خالی و بیمعنی در HTML داشت. با after:: عنصر تزیینی در جای درست خودش یعنی CSS میماند و HTML تمیز باقی میماند. قانون کلی این است: هر چیزی که تنها تزیین است، در CSS ساخته شود نه در HTML.
۸. نکتههای تکمیلی
<a href="#contact">تماس با ما</a>
<section id="contact">...</section>
<a href="mailto:info@school.ir">ایمیل بزنید</a>
<a href="tel:01133445566">تماس بگیرید</a>
<a href="https://kadoosedu.ir" target="_blank">سایت کادوس</a>
html {
scroll-behavior: smooth;
}
.clickable {
cursor: pointer;
}
.gray-photo {
filter: grayscale(100%);
transition: filter 0.3s;
}
.gray-photo:hover {
filter: grayscale(0);
}
.blurred {
filter: blur(3px);
}
نکتههای تکمیلی: نمونه 08-extra-touches
شرح مثال
-
لینک داخلی. اگر
hrefبا#شروع شود، به عنصری با همانidدر همان صفحه میرود. اینجاست که آیدی فصل سوم به کار میآید. scroll-behavior: smoothباعث میشود این پرش به جای ناگهانی بودن، نرم و روان انجام شود. یک خط، تأثیر بسیار.-
mailto:برنامه ایمیل کاربر را باز میکند وtel:روی گوشی شمارهگیر را. برای صفحه تماس بسیار مفیدند. -
cursor: pointerشکل موس را به دست تبدیل میکند. روی هر چیزی که قابل کلیک است و لینک یا دکمه نیست، لازم است. -
filterجلوههای تصویری میسازد.grayscaleسیاهوسفید میکند وblurمحو. ترکیب سیاهوسفید باhover:که رنگ را برمیگرداند، برای گالریها جلوه زیبایی میسازد.
<title> عنوان سربرگ مرورگر است و در نتایج
گوگل هم به عنوان تیتر آبی نمایش داده میشود.
<meta name="description"> هم آن متن توضیحی
زیر تیتر است. هر صفحه باید هر دو را داشته باشد و
محتوایشان باید برای هر صفحه متفاوت باشد.
۹. نمونه نهایی فصل
<body>
<header class="hero">
<h1>دبیرستان دانش</h1>
<a href="#courses" class="btn">رشتهها را ببینید</a>
</header>
<section id="courses">
<h2 class="section-title">رشتههای تحصیلی</h2>
<div class="cards">
<div class="card new-card">
<img src="images/math.jpg" alt="ریاضی">
<h3>ریاضی و فیزیک</h3>
</div>
<div class="card">
<img src="images/lab.jpg" alt="آزمایشگاه">
<h3>علوم تجربی</h3>
</div>
</div>
<ul class="check-list">
<li>آزمایشگاه مجهز</li>
<li>کتابخانه بزرگ</li>
<li>کلاسهای کمجمعیت</li>
</ul>
</section>
</body>
:root {
--primary: #2f4f4f;
--accent: #ff6347;
--bg-light: #f5f5f5;
--text: #333333;
--radius: 10px;
--shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.08);
--shadow-lg: 0 10px 25px rgba(0, 0, 0, 0.15);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: Tahoma, sans-serif;
}
html {
scroll-behavior: smooth;
}
body {
background-color: var(--bg-light);
color: var(--text);
line-height: 1.9;
}
/* هدر بزرگ با پرده تیره روی عکس */
.hero {
height: 60vh;
background-image:
linear-gradient(rgba(20, 40, 40, 0.7), rgba(20, 40, 40, 0.7)),
url('images/school.jpg');
background-size: cover;
background-position: center;
color: white;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 20px;
text-shadow: 0 2px 6px rgba(0, 0, 0, 0.4);
}
.btn {
background-color: var(--accent);
color: white;
text-decoration: none;
padding: 14px 32px;
border-radius: var(--radius);
cursor: pointer;
transition: transform 0.3s ease;
}
.btn:hover {
transform: scale(1.05);
}
.btn:active {
transform: scale(0.97);
}
section {
padding: 50px 40px;
}
/* عنوان بخش با خط تزیینی */
.section-title {
position: relative;
color: var(--primary);
padding-bottom: 12px;
margin-bottom: 30px;
}
.section-title::after {
content: "";
position: absolute;
right: 0;
bottom: 0;
width: 60px;
height: 4px;
background-color: var(--accent);
border-radius: 2px;
}
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 20px;
margin-bottom: 35px;
}
.card {
position: relative;
background-color: white;
border-radius: var(--radius);
overflow: hidden;
box-shadow: var(--shadow-sm);
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.card:hover {
transform: translateY(-8px);
box-shadow: var(--shadow-lg);
}
.card img {
width: 100%;
height: 190px;
object-fit: cover;
display: block;
filter: grayscale(40%);
transition: filter 0.3s;
}
.card:hover img {
filter: grayscale(0);
}
.card h3 {
color: var(--primary);
padding: 15px 18px;
}
/* نشان جدید روی کارت */
.new-card::before {
content: "جدید";
position: absolute;
top: 12px;
left: 12px;
z-index: 5;
background-color: var(--accent);
color: white;
padding: 4px 14px;
border-radius: 20px;
font-size: 13px;
}
/* فهرست با تیک */
.check-list {
list-style: none;
background-color: white;
padding: 20px 25px;
border-radius: var(--radius);
box-shadow: var(--shadow-sm);
}
.check-list li {
padding: 10px 0;
border-bottom: 1px solid #eeeeee;
}
.check-list li::before {
content: "✔ ";
color: var(--accent);
font-weight: bold;
}
.check-list li:last-child {
border-bottom: none;
}
نمونه نهایی فصل: نمونه 09-final-example
شرح مثال
این صفحه تقریباً هر چیزی را که در این فصل خواندیم به کار میبرد و شکل و حال یک سایت واقعی و امروزی را دارد.
- متغیرها. هیچ رنگی در فایل به شکل دستی نوشته نشده، حتی سایهها هم متغیر شدهاند. برای عوض کردن تم کل صفحه، تنها بلوک
root:تغییر میکند. -
هدر بزرگ. ترکیب گرادیانت نیمهشفاف روی عکس،
بهعلاوه فلکسباکس برای وسطچین کردن، بهعلاوه
text-shadowتا متن روی هر عکسی خوانا بماند. -
دکمه. سه حالت دارد: عادی، بزرگشونده در
hover:و کمی فشرده درactive:. بهعلاوه لینک داخلی به بخش رشتهها که باscroll-behavior: smoothنرم اسکرول میکند. -
عنوان بخش. خط تزیینی نارنجی با
after::ساخته شده، بدون هیچ تگ اضافهای در HTML. -
کارتها. تصویرها با
object-fit: coverهماندازه شدهاند، درhover:کارت بالا میآید و سایهاش بزرگتر میشود و رنگ عکس هم برمیگردد. نشان «جدید» هم یکbefore::است. -
فهرست. تیک سبز هر مورد با
before::آمده و خط زیر آخرین مورد باlast-child:برداشته شده است.
در بخش کارتها نوشتهایم repeat(auto-fit, minmax(240px, 1fr)). معنیاش این است: «هر چند ستون که جا میشود بساز، به شرطی که هیچ ستونی باریکتر از ۲۴۰ پیکسل نشود». نتیجهاش یک گالری کاملاً واکنشگراست، بدون حتی یک media query. این پیشرفتهترین نکته این کتاب است و اگر آن را به خاطر بسپارید، در پروژههای واقعی بسیار به کارتان میآید.
پوشه 13-advanced-css شامل نمونههای
01-css-variables تا 09-final-example.
خلاصه فصل
| ویژگی | کارش |
|---|---|
:root و --name | تعریف متغیر |
var(--name) | استفاده از متغیر |
box-shadow | سایه جعبه. با inset به داخل. |
text-shadow | سایه متن |
linear-gradient | محو شدن یک رنگ در رنگ دیگر |
rgba | رنگ با شفافیت |
opacity | شفافیت کل عنصر، شامل متنش |
transform | جابهجایی، بزرگنمایی، چرخش |
object-fit: cover | هماندازه کردن تصویرها بدون کشیدگی |
calc() | محاسبه بین واحدهای متفاوت |
:first-child :last-child | اولین و آخرین فرزند |
:nth-child(odd) | فرزندان فرد، برای جدول راهراه |
:active | لحظه فشرده شدن |
::before و ::after | ساختن قطعه تزیینی. content اجباری است. |
scroll-behavior: smooth | اسکرول نرم برای لینکهای داخلی |
filter | جلوههایی مانند سیاهوسفید و محو |
تمرینهای فصل سیزده
- فایل CSS یکی از تمرینهای قبلی را بردارید و همه رنگهایش را به متغیر تبدیل کنید. بعد با عوض کردن یک خط، تم کل صفحه را تغییر دهید.
- یک هدر بزرگ با عکس و پرده تیره بسازید که متن سفیدش کاملاً خوانا باشد.
- کارتی بسازید که با رفتن موس روی آن، بالا بیاید و سایهاش بزرگتر شود.
- زیر همه عنوانهای بخش، یک خط تزیینی با
after::اضافه کنید. - یک جدول راهراه با
nth-child(odd):بسازید. - یک گالری با
repeat(auto-fit, minmax(240px, 1fr))بسازید و پنجره را باریک کنید تا رفتارش را ببینید. - تصویرهایی با اندازههای مختلف در کارتها بگذارید و با
object-fit: coverمرتبشان کنید.