مقدمة
إذا كنت مطور واجهات أمامية سبق لك العمل مع معالج مسبق لملفات CSS، فمن المحتمل أنك صادفت أو استخدمت ميزة التداخل. لقد كانت ميزة شائعة، وبالنسبة لي، كانت إحدى الميزات التي دفعتني لاستخدام معالج مسبق لملفات CSS.
هذا العام، تم دعم خاصية التداخل في CSS في جميع المتصفحات الرئيسية: كروم، فايرفوكس، وسفاري. إنها ميزة أساسية في CSS تُسهّل كتابة أكواد CSS. في هذه المقالة، سأوثّق ما تعلمته عن التداخل في CSS حتى الآن، وأشارككم النتائج التي توصلت إليها، بالإضافة إلى حالات استخدام وأمثلة توضيحية.
لا توجد متطلبات مسبقة يجب اتباعها سوى حماسك وتركيزك.
لطالما كانت ميزة التداخل في CSS منتظرة من قبل العديد من المطورين. كنا نعتمد سابقًا على معالجات CSS المسبقة مثل Sass أو Less. دعوني أقدم لكم لمحة سريعة عنها:
لنأخذ المثال التالي. لدينا أيقونة موجودة في مُحدِّد .nav__item.
.nav__item {
.icon {
display: flex;
padding: 1rem;
}
}الكود أعلاه هو كود Sass صحيح. عند تجميعه، سيظهر بالشكل التالي في المتصفح:
.nav__item .icon {
display: flex;
padding: 1rem;
}باستخدام خاصية التداخل في CSS الأصلي، سيعمل نفس الكود كما هو. إليك رسم توضيحي يُظهر مقارنة بين خاصية التداخل في CSS الأصلي وأدوات مطوري المتصفح.
لاحظ كيف يعرض المتصفح CSS بشكل مشابه (تقريبًا) لكيفية عرضه في CSS.
إذا تم تجميع هذا الكود البرمجي CSS في Sass، فسيعرضه المتصفح على النحو التالي:
فوائد التداخل في CSS
في رأيي، هناك أسباب وجيهة تجعل استخدام CSS المتداخل مفيدًا:
- يُعدّ CSS أسهل في القراءة.
- أسلوب التجميع معًا
- تقييد أنماط محددة
- تنسيق عناصر HTML التي لا تحتوي على فئات أو معرفات.
قواعد التداخل في CSS
لتثقيفكم حول تداخل CSS، سأحاول تقديم أمثلة مرئية لمشاكل CSS المختلفة وكيف يمكن أن يساعد التداخل في حلها.
أولاً وقبل كل شيء، عليك أن تتعرف على رمز العطف (&). هناك العديد من المواقف التي يكون فيها هذا الرمز ضرورياً.
تضمين عنصر بدون فئة أو معرف
في هذا المثال، العنصر <a> تم تنسيقها باستخدام .nav__item. استخدام علامة <head> اختياري لكي يكون CSS صالحًا.
.nav__item {
& a {
display: block;
padding: 1.5rem 1rem;
}
}
/* Same as: */
.nav__item a {
}يمكنك أيضًا إلغاء تحديد الخيار:
.nav__item {
a {
display: block;
padding: 1.5rem 1rem;
}
}
/* Same as: */
.nav__item a {
}لاحظ أن هذا تحديث حديث ويُسمى "التداخل المرن لـ CSS". وهو يعمل في أحدث إصدار من متصفح Chrome Canary و Safari Technology Preview. اطلع على هذه المقالة حول التداخل المرن بقلم آدم أرجيل.
تضمين عنصر ذي فئة
لنأخذ نفس المثال السابق، ولكن لنفترض أن العنصر <a> يحتوي على فئة HTML.
.nav__item {
.link {
display: block;
padding: 1.5rem 1rem;
}
}
/* Same as: */
.nav__item .link {
}لا داعي لاستخدام رمز هنا. اسم الفئة سيفي بالغرض.
أدوات دمج CSS المتداخلة
من مزايا خاصية التداخل الأصلي في CSS استخدام أدوات الربط. دعونا نلقي نظرة على بعض الأمثلة.
في المثال أدناه، أريد تحديد أي عنصر يحمل الفئة .nav__item ويسبقه عنصر آخر يحمل نفس الفئة. استخدمتُ مُحدِّد العنصر الشقيق المجاور لهذا الغرض.
في خاصية التداخل في CSS الأصلية، يمكننا استخدام رمز العطف (&) لمحاكاة ذلك. لاحظ أنني كررته مرتين.
.nav__item {
& + & {
border-left: 2px solid;
}
}
يكمن السر في التكرار الثاني لعلامة العطف (&). هنا، يدرك المتصفح أنني أريد استخدام مُحدِّد العنصر الشقيق المجاور. دعني أريك شكلاً توضيحياً لذلك:
ومن الأمثلة الأخرى على التداخل مُحدد الأبناء. فهو يستطيع تحديد الابن المباشر لعنصر ما.
.nav__item {
> a {
padding: 1rem;
}
}رمز العطف (&)
.nav__item {
& a {
color: blue;
}
}كان هذا مطلوبًا في مواصفات التداخل الأصلية لـ CSS. في متصفح Safari TP 179 والإصدارات الأحدث، ومتصفح Chrome Canary 120، لم يعد استخدام علامة العطف (&) ضروريًا للعناصر المتداخلة.
ونتيجة لذلك، فإن الأعمال التالية هي:
.nav__item {
a {
color: blue;
}
}المشكلة الوحيدة هي أنه يتعين عليك الرجوع إلى الإصدار السابق من المواصفات، والذي يجب أن يتضمن الترميز والترميز.
مثال على التداخل: نشط، تركيز، تمرير المؤشر
:active و :focus و :hover هي فئات CSS زائفة يتم تفعيلها بواسطة إجراء المستخدم.
باستخدام خاصية التداخل في CSS، يمكننا تضمين جميع العناصر دفعة واحدة لتجنب تكرار الكود. لنأخذ خاصية :hover كمثال:
button {
&:hover {
background-color: var(--bg-color);
}
&:focus {
outline: solid 2px;
}
}الفرق عند استخدام معالج مسبق للتداخل هو أن المتصفح يعرضه على النحو التالي:
button:hover {
background-color: var(--bg-color);
}
button:focus {
outline: solid 2px;
}دعونا نلقي نظرة على كيفية عرض تداخل CSS في متصفحات Chrome و Safari و Firefox.
لدي بعض الأفكار حول تجربة المستخدم في أدوات المطورين لتداخل CSS وسأتناولها لاحقًا في المقال.
مثال على التداخل: نشر المحتوى
من الأمثلة الأولى لاختبار CSS المتداخل هو تنسيق محتوى المنشور. تخيل مقالاً يحتوي على عناوين ونصوص وصور واقتباسات وغير ذلك.
العناوين الرئيسية
نميل إلى تصميم العناوين على النحو التالي:
.post-content h1,
.post-content h2,
.post-content h3,
.post-content h4 {
/* styles here */
}باستخدام CSS المتداخل، يصبح الأمر أسهل:
.post-content {
h1,
h2,
h3,
h4 {
color: var(--heading-color);
font-weight: var(--heading-font-bold);
margin-bottom: var(--size-2);
}
}يمكننا أيضًا فعل الشيء نفسه باستخدام مُحدِّد :is().
.post-content {
:is(h1, h2, h3, h4) {
color: var(--heading-color);
font-weight: var(--heading-font-bold);
margin-bottom: var(--size-2);
}
}عنصر الفقرة
من الأمثلة الشائعة على ذلك تنسيق رابط موجود داخل فقرة. في هذه الحالة، يُعدّ استخدام خاصية التداخل في CSS حلاً مثالياً.
.post-content {
& p {
color: var(--color-black);
& a {
font-weight: bold;
text-decoration: underline;
}
}
}قد يتطلب الرابط أيضًا تأثيرًا عند تمرير المؤشر فوقه أو عند التركيز عليه.
.post-content {
& p {
color: var(--color-black);
& a {
font-weight: bold;
text-decoration: underline;
&:hover {
/* hover styles */
}
}
}
}يمكننا أيضًا تضمين استعلامات الوسائط.
.post-content {
& p {
/* base styles */
@media (min-width: 400px) {
/* do something */
}
}
}في بعض الحالات، قد يكون نظام إدارة المحتوى عنصرًا <p> قم بتغليفه بعنصر آخر، ولأغراض التنسيق، يجب استخدامه فقط للعناصر المباشرة <p> زيّنها.
.post-content {
/* Select the direct <p> elements */
> p {
/* base styles */
}
}اقتباس من الفقرة
في هذا المثال، يحصل الاقتباس على نمط مخصص خاص به والعنصر <p> داخل الاقتباس، حدد خيار إعادة تعيين الهامش السفلي إلى الصفر.
.post-content {
& blockquote {
/* custom quote styling */
& p {
margin-bottom: 0;
}
}
}شكل العمود
يحتوي نموذج الإرسال على صورة و
في مثالي، إذا
.post-content {
& figure {
& img {
/* the figure's image styles */
}
/* changes to the <figure> container, if it has a figcaption element */
&:has(figcaption) {
display: flex;
align-items: start;
}
& figcaption {
/* caption styling */
}
}
}قائمة المنشورات
أحتاج إلى إضافة إطار لجميع عناصر القائمة باستثناء العنصر الأخير. ولتحقيق ذلك، استخدمتُ مُحدِّد :not().
.post-content {
li {
&:not(:last-child) {
border-bottom: 1px solid;
}
}
}لاستخدام :not()، نحتاج إلى إضافة علامة العطف (&) قبلها.
تباعد مخصص للعناوين
ينبغي أن تكون المسافة التالية <h3> و <h4> سأقوم بالتقليص إذا تبع أحدها جزء من التعليمات البرمجية.
.post-content {
& h3 + [class*="language-"],
& h4 + [class*="language-"] {
margin-top: 0.5rem;
}
}كما رأيتم في هذا المثال العملي، فإن استخدام التداخل في CSS أمر بسيط، خاصة إذا كنت قادمًا من خلفية معالج CSS المسبق.
مثال على التداخل: مكون البطاقة
سأعرض مكون بطاقة بسيط يستخدم تداخل CSS لتحقيق الأنماط المطلوبة.
بافتراض وجود عنصر .card بأنماط افتراضية أو أساسية، سأوضح استخدام CSS المتداخل.
.card {
/* default card styles */
}
استفسارات حول حاويات التداخل
إذا كان عرض الحاوية أكبر من 400 بكسل، فأريد أن تتحول البطاقة إلى حاوية مرنة.
.card {
/* default card styles */
/* if the container width is 400px or bigger */
@container card (min-width: 400px) {
display: flex;
}
}تنسيق عنصر الفقرة
أريد استخدام عنصر الفقرة عبر <h3> بهذه الطريقة، يمكنني تطبيق الهوامش والحشو على العنصر. <p> سأضيف. إذا لم يكن موجودًا، فلن تحتوي واجهة المستخدم على مساحة إضافية.
.card__content {
& h3 + p {
border-top: 1px solid #000;
padding-top: 0.5rem;
margin-top: 0.5rem;
}
}عندما يكون عرض الحاوية 400 بكسل أو أكثر، يجب أيضًا تحويل عنصر .card__content إلى حاوية مرنة.
.card__content {
& h3 + p {
border-top: 1px solid #000;
padding-top: 0.5rem;
margin-top: 0.5rem;
}
@container card (min-width: 400px) {
display: flex;
flex-direction: column;
justify-content: center;
}
}التداخل مع مثال: إدخال النموذج
من الأمثلة الشائعة على ذلك تنسيق عنصر نائب للإدخال. تكمن المشكلة في أن لكل متصفح بادئة خاصة به (يا إلهي، نحن في عام 2023).
بما أن أنماط البادئة تتطلب نقطتين رأسيتين، فيجب علينا استخدام الرمز &، وإلا ستتعطل الأنماط.
input {
--placeholder-color: #969696;
/* other styles */
&::-webkit-input-placeholder {
color: var(--placeholder-color);
}
&::-moz-placeholder {
color: var(--placeholder-color);
opacity: 1;
}
&:-moz-placeholder {
color: var(--placeholder-color);
}
}قد تتساءل عن الفرق بين استخدام CSS المتداخل أو كتابة نمط البادئة مباشرة بدونه.
/********** Option 1: native nesting **********/
input {
&::-webkit-input-placeholder {
color: var(--placeholder-color);
}
}
/********** Option 2: without nesting **********/
input::-webkit-input-placeholder {
color: var(--placeholder-color);
}لا يوجد فرق بينهما. كلاهما لهما نفس الخصائص (0، 1، 1).
التداخل مع مثال: تنسيق عنصر من خلال العنصر الأب
يمكننا استخدام خاصية التداخل في CSS لتغيير أنماط العنصر الفرعي بناءً على موقعه. على سبيل المثال، إذا كان عنصر .button موجودًا داخل عنصر .box، فيجب أن يشغل العرض الكامل.
<div class="box">
<h2>Get access to all features</h2>
<p>Create an account now and get access to all exclusive features.</p>
<a href="/offer" class="button">Create an account</a>
</div>.button {
.box & {
width: 100%;
}
}
/* equivalent to */
.box .button {
}الأخطاء التي لاحظتها أثناء استكشاف خاصية التداخل في CSS
باستخدام المحدد العام غير الموقع
لنفترض أن لدينا بطاقة ونريد تحديد جميع العناصر الموجودة بداخلها. باستخدام خاصية التداخل الأصلي في CSS، يجب أن يعمل هذا:
.card {
* {
/* styles here */
}
}لاحظت أن هذا لا يعمل في Chrome Stable، ولكنه يعمل بشكل جيد في Chrome Canary 121 و Safari 17.1 و Firefox 119.
الحل هو إضافة علامة الترقيم.
.card {
& * {
/* styles here */
}
}استخدام سمات البيانات غير الموقعة
في هذه المشكلة، لا يؤدي تحديد سمة بيانات بدون علامة صح إلى النتيجة المتوقعة.
.card {
[data-type="featured"] {
/* styles here */
}
}لاحظت أنه لا يعمل في Chrome Stable، ولكنه يعمل بشكل جيد في Chrome Canary 121 و Safari 17.1 و Firefox 119.
لإصلاح ذلك، نحتاج إلى إضافة فاصلة:
.card {
&[data-type="featured"] {
/* styles here */
}
}تم إصلاح كلا هذين الخطأين في الإصدار الخاص بتداخل CSS المريح في Chrome Canary.
تحديد دعم التداخل في CSS
يمكن استخدام @supports للتحقق من دعم تداخل CSS. في حالتنا، نريد التحقق مما إذا كان المتصفح يتعرف على علامة العطف (&).
@supports selector(&) {
.post-content {
& h2 {
/* styles here. */
}
}
}يمكنك استكشاف خيارات أخرى لتحديد الدعم في هذا الكود من براموس.
سأستخدم اليوم إضافة PostCSS للدمج، التي تُحوّل أكواد CSS المتداخلة إلى أكواد CSS عادية. سأزيل الإضافة عندما يصبح استخدامها آمناً.
أدوات مطوري تجربة المستخدم لتداخل CSS
أنا لست من المعجبين بتجربة المستخدم الحالية لتداخل CSS في أدوات مطوري المتصفح.
لقد عملت على مقال منفصل استكشفت فيه بعض الاقتراحات حول كيفية رغبتي في أن يكون تداخل CSS في أدوات المطورين.
نتيجة
تُعدّ خاصية التداخل في CSS ميزةً رئيسيةً تُحسّن طريقة كتابة CSS. يُمكن استخدام هذه الخاصية حاليًا، ولكن يجب مراعاة جمهورك المُستهدف، نظرًا لأنّ دعمها لا يزال حديثًا.
























