تجاوز متغير CSS على عنصر فرعي لا يعيد إنشاء خاصية مخصصة مركبة موروثة من العنصر الأب. فقد حسم العنصر الأب المرجع المتداخل بالفعل. لاستخدام قيمة العنصر الفرعي، عرّف الخاصية المركبة على ذلك العنصر أو ركّب الخاصية النهائية فيه.
يشرح هذا الدليل هذا السلوك ويقدم تمرينًا عمليًا قابلًا لإعادة التنفيذ على سطح المكتب باستخدام Chrome على Mac. تتمثل المهمة في جعل حدّ أحد المكوّنات يتبع تجاوز اللون المحلي مع الإبقاء على القيم الافتراضية المشتركة.
لماذا تحتفظ الخاصية المركبة الموروثة بلون العنصر الأب؟
تأمل مقطع CSS هذا. يفترض وجود عنصر .sample-tile داخل عنصر .sample-board:
.sample-board {
--sample-color: teal;
--sample-border: 6px solid var(--sample-color);
}
.sample-tile {
--sample-color: darkorange;
border: var(--sample-border);
}
يظل حدّ العنصر الفرعي باللون الفيروزي. تنص مواصفات متغيرات CSS على أن الخصائص المخصصة تحسم دوال var() المتداخلة عند وقت حساب القيمة، قبل التوريث. لذلك يرث العنصر الفرعي خاصية مركبة مكافئة لـ 6px solid teal؛ ولا يرث تعبيرًا سيستبدل --sample-color الخاص بالعنصر الفرعي. الخصائص المخصصة في CSS لمتغيرات التتالي، المستوى 1.
لدينا هنا خاصيتان منفصلتان. يؤدي تعيين --sample-color على العنصر الفرعي إلى تغيير القيمة المحلية لتلك الخاصية. لكنه لا يعرّف أيضًا قيمة جديدة لـ --sample-border. يصف مرجع MDN للخصائص المخصصة الخصائص المخصصة العادية غير المسجلة بأنها موروثة، وبأن قيمها المحسوبة تتضمن استبدال متغيراتها. الخصائص المخصصة: متغيرات CSS.
تسلسل الأحداث في هذا المثال هو:
- يحسب العنصر الأب قيمة
--sample-colorعلى أنهاteal. - تستبدل خاصية
--sample-borderهذا اللون، فتنتج6px solid teal. - يرث العنصر الفرعي هذه الخاصية المركبة، ويعيّن بشكل منفصل رمز اللون الخاص به على
darkorange. - يستخدم تصريح
borderفي العنصر الفرعي الخاصية المركبة الفيروزية الموروثة.
هذه ليست لقطة ثابتة دائمة من العنصر الأب. فإذا تغير لون العنصر الأب، يمكن أن تتحدث الخاصية المركبة فيه وتُورّث مجددًا. الحد الفاصل هو العنصر الذي يُحسم عنده المرجع المتداخل: تجاوز أحد العناصر المنحدرة لا يمتد صعودًا إلى تلك العملية الحسابية. متغيرات CSS: حسم الاعتماديات.
أعد تنفيذ السلوك في Chrome على Mac
استخدم صفحة فارغة كي لا تتداخل معها أنماط الصفحة الموجودة. افتح علامة تبويب جديدة في Chrome، وأدخل about:blank في شريط العناوين، ثم اضغط Command + Option + J لفتح Console. توثّق Google اختصار Mac هذا في دليل DevTools. فتح أدوات مطوري Chrome.
ينشئ برنامج وحدة تحكم المتصفح الكامل التالي ثلاثة أشكال مجردة معنونة وورقة أنماطها. لا يحتاج إلى مكتبات أو صور أو طلبات شبكة أو عناصر موجودة في الصفحة. شغّل الكتلة كاملة مرة واحدة على الصفحة الفارغة. النتائج المتوقعة أدناه مستنبطة من قواعد CSS الموثقة؛ وهي ليست معروضة على أنها قياسات مسجلة من المتصفح.
(() => {
const board = document.createElement("section");
board.className = "sample-board";
const style = document.createElement("style");
style.textContent = `
.sample-board {
--sample-color: teal;
--sample-border: 6px solid var(--sample-color);
display: flex;
flex-wrap: wrap;
gap: 24px;
padding: 32px;
font: 16px system-ui;
}
.sample-board .sample-tile {
--sample-color: darkorange;
display: grid;
place-items: center;
width: 120px;
height: 80px;
border: var(--sample-border);
border-radius: 24px;
background: white;
color: black;
}
.sample-board .sample-local {
--sample-border: 6px solid var(--sample-color);
}
.sample-board .sample-direct {
border: 6px solid var(--sample-color);
}
`;
const samples = [
["Inherited", "sample-inherited"],
["Local", "sample-local"],
["Direct", "sample-direct"]
];
const tiles = samples.map(([label, className]) => {
const tile = document.createElement("div");
tile.className = `sample-tile ${className}`;
tile.textContent = label;
board.append(tile);
return tile;
});
document.head.append(style);
document.body.append(board);
function report(stage) {
console.log(stage);
console.table(tiles.map((tile) => {
const computed = getComputedStyle(tile);
return {
sample: tile.textContent,
localColor: computed
.getPropertyValue("--sample-color").trim(),
composite: computed
.getPropertyValue("--sample-border").trim(),
paintedBorder: computed.borderTopColor
};
}));
}
report("Initial values");
board.style.setProperty("--sample-color", "rebeccapurple");
report("After changing the parent color");
})();
يطبع البرنامج جدولين. ألوان الحدود المتوقعة هي:
| العينة | في البداية | بعد تغيير العنصر الأب | السبب |
|---|---|---|---|
Inherited |
فيروزي | أرجواني | تستخدم الخاصية المركبة المحسوبة للعنصر الأب |
Local |
برتقالي | برتقالي | تعرّف الخاصية المركبة على العنصر الفرعي |
Direct |
برتقالي | برتقالي | تستبدل اللون المحلي مباشرةً في border |
تحتفظ العناصر الفرعية الثلاثة جميعها بـ darkorange بوصفه رمز اللون المحلي. والعينة المفيدة للتشخيص هي Direct: إذ لا تزال خاصيتها المركبة الموروثة تتضمن لون العنصر الأب، لكن الحد المرسوم يستخدم الرمز المحلي لأن تصريح الحد لا يستخدم الخاصية المركبة.
تقرأ getComputedStyle() قيم الخصائص المحسومة بعد تطبيق أوراق الأنماط النشطة. لذلك يمكنها إظهار القيمة الفعلية التي يحصل عليها العنصر، بدلًا من مجرد عرض التعبير المكتوب. قد يظهر تمثيل اللون المتسلسل على هيئة قيمة rgb() بدلًا من اسم اللون الأصلي. Window: طريقة getComputedStyle().
أعد تحميل علامة التبويب الفارغة لمسح التمرين. إذا كنت تعمل على صفحة من تأليفك، فضع إصلاح CSS المختار في ورقة الأنماط الخاصة بها؛ تعديلات وحدة التحكم مفيدة للتشخيص، لكنها لا تعدّل ملفات المصدر لديك.
أي إصلاح ينبغي أن تختار؟
عرّف الخاصية المركبة عند حدّ المكوّن
تحتفظ عينة Local برمز الحد القابل لإعادة الاستخدام، وتعرّف تركيبته على العنصر نفسه الذي يوفّر التجاوز. إليك مقطع CSS ذي الصلة من البرنامج:
.sample-board .sample-local {
--sample-color: darkorange;
--sample-border: 6px solid var(--sample-color);
border: var(--sample-border);
}
اختر هذا النمط عندما تحتاج عدة تصريحات إلى القيمة المركبة نفسها. ضع القيم الافتراضية الأساسية على عنصر سلف، وتعريف الخاصية المركبة على المكوّن المسؤول عن التخصيص. يمكن تعريف الخصائص المخصصة على عناصر بعينها، وهي تُورّث إلى العناصر المنحدرة منها؛ وليس من الضروري وضعها على :root. استخدام خصائص CSS المخصصة.
يظل موضع التعريف مهمًا في المستويات الأعمق من الشجرة. فإذا تجاوز عنصر حفيد القيمة الأساسية مرة أخرى، فستظل الخاصية المركبة الموروثة من هذا المكوّن تعكس حسابات هذا المكوّن. أعد تعريف التركيبة عند أي حدّ لعنصر منحدر يحتاج إلى تركيب نتيجة مختلفة.
ركّب الخاصية النهائية في موضع استخدامها
تحذف عينة Direct الرمز الوسيط من تصريح الحد. وهذا مقطع CSS الذي يتضمن قاعدتها الأساسية:
.sample-board .sample-direct {
--sample-color: darkorange;
border: 6px solid var(--sample-color);
}
اختر هذا النمط عندما يحتاج تصريح واحد فقط إلى التركيبة. لا يزال بإمكانك مشاركة رموز منفصلة للعرض والنمط واللون، ثم تركيبها في تصريح border الخاص بالمكوّن. توضح MDN أن var() يمكن أن تستبدل قيمة خاصية أخرى كلها أو جزءًا منها. استخدام خصائص CSS المخصصة.
تجاوز الخاصية المركبة بالكامل عندما تكون هي واجهة التحكم العامة
أحيانًا يكون التخصيص المقصود للمكوّن هو الحد بالكامل. في هذه الحالة، قدّم قيمة بديلة محلية لـ --sample-border، مثل 6px solid darkorange، بدلًا من تغيير أحد المدخلات السابقة فقط.
استخدم دليل الاختيار هذا عند تحديد عقد المكوّن:
| التخصيص المقصود | النمط المناسب |
|---|---|
| يتحكم لون محلي واحد في حدّ واحد | ركّب مباشرةً في border |
| تشترك عدة تصريحات في قيمة مركبة واحدة | عرّف الخاصية المركبة على المكوّن |
| يوفّر المستدعي الحد بالكامل | تجاوز الخاصية المركبة نفسها |
| يجب أن تستخدم العناصر المنحدرة القيمة التي ركّبها العنصر الأب بالضبط | أبقِ الخاصية المركبة الموروثة |
لماذا لا تعيد الخصوصية أو القيمة الاحتياطية أو كلمات التوريث بناءها؟
تحقق أولًا مما إذا كان تجاوز القيمة الأساسية قد نُفّذ بالفعل. فإذا كانت القيمة المحسومة لـ --sample-color في العنصر الفرعي هي darkorange بالفعل، فلن يؤدي جعل التصريح نفسه أعلى خصوصية إلى تغيير --sample-border الموروثة والمنفصلة. لكلتا الخاصيتين قيمتان بالفعل؛ والمشكلة هي موضع تركيب الخاصية المركبة.
وبالمثل، تأخذ --sample-border: inherit القيمة المحسوبة للعنصر الأب. ينقل التوريث العادي القيم المحسوبة بدلًا من إعادة تنفيذ تصريح العنصر الأب المكتوب ضمن سياق العنصر الفرعي. التوريث.
كذلك لن تغيّر قيمة احتياطية مثل var(--sample-border, 6px solid darkorange) حدًا فيروزيًا موروثًا وصالحًا. تتعامل القيمة الاحتياطية var() مع خاصية مخصصة لا تملك قيمة صالحة للاستخدام؛ ولا تقارن تلك القيمة بمدخلات العنصر المنحدر المفضلة. دالة CSS var().
افصل القيم غير الصالحة عن مشكلة التوريث هذه. فعلى سبيل المثال، يمكن أن يوجد رمز غير مسجل يتضمن 12px بوصفه قيمة خاصية مخصصة، لكنه قد ينتج قيمة غير صالحة عند استبداله في border-color. القيمة الاحتياطية داخل استدعاء var() هذا ليست بديلًا عامًا للتحقق من الأنواع. توضح MDN لماذا قد ينشئ استبدال الخصائص المخصصة تصريحات تصبح غير صالحة وقت حساب القيمة. استخدام خصائص CSS المخصصة.
هل يؤدي تسجيل المتغير باستخدام @property إلى إصلاح ذلك؟
تتيح لك @property تحديد الصياغة والقيمة الأولية وسلوك التوريث لخاصية مخصصة. لكنها لا تجعل الخاصية المركبة الموروثة من العنصر الأب تُعاد حسابها وفق المدخلات التي جرى تجاوزها في العنصر الفرعي. تسجيل القيمة الأساسية باستخدام inherits: false يغيّر طريقة الحصول على تلك القيمة، بينما يؤدي تسجيل الخاصية المركبة بهذه الطريقة إلى إيقاف توريثها المعتاد. ولا يوفّر أي منهما التركيبة المحلية الناقصة. توجيه CSS البرمجي @property.
للتسجيل أيضًا حدود توافق مختلفة. تصنّف MDN الخصائص المخصصة العادية على أنها متاحة على نطاق واسع في المتصفحات منذ أبريل 2017، بينما بلغت @property التوفر الأساسي في يوليو 2024، وقد لا تكون متاحة في المتصفحات الأقدم. لا يتطلب الإصلاحان الموضحان أي تسجيل. الخصائص المخصصة: متغيرات CSS، توجيه CSS البرمجي @property.
كيف تشخّص المشكلة نفسها في ورقة الأنماط لديك
استخدم المقارنة ذات الأعمدة الثلاثة من التمرين على العنصر الذي لا يظهر بالشكل الصحيح:
- اقرأ الرمز الأساسي، مثل
--sample-color. - اقرأ الرمز المركب، مثل
--sample-border. - اقرأ الخاصية المعروضة، مثل
border-top-color. - ابحث عن العنصر الذي ينطبق عليه تصريح الخاصية المركبة.
- انقل ذلك التصريح أو كرره عند حدّ التخصيص المقصود، أو ركّب الخاصية مباشرةً في الخاصية النهائية.
لتحديد مواضع القواعد ذات الصلة في Chrome، انقر بزر الفأرة الأيمن على الشكل واختر Inspect. تحدد DevTools العنصر في Elements، وتعرض علامة التبويب Styles قواعد CSS المطبقة عليه. فتح أدوات مطوري Chrome.
عندما تُظهر القيمة الأساسية القيمة المحلية المطلوبة، بينما تظل الخاصية المركبة تتضمن قيمة من أحد العناصر السلف، فتحقق أولًا من موضع تعريف الخاصية المركبة. عرّف التركيبة في الموضع الذي ينبغي أن تُقرأ فيه مدخلاتها، ثم تحقق من الرمز المحسوم والنتيجة المرسومة. يمنح ذلك المكوّن حدًا صريحًا ومتوقعًا للتخصيص.
المصادر
- الخصائص المخصصة في CSS لمتغيرات التتالي، المستوى 1 — W3C.
- الخصائص المخصصة (--*): متغيرات CSS — MDN Web Docs.
- استخدام خصائص CSS المخصصة (المتغيرات) — MDN Web Docs.
- التوريث — MDN Web Docs.
- دالة CSS var() — MDN Web Docs.
- توجيه CSS البرمجي @property — MDN Web Docs.
- Window: طريقة getComputedStyle() — MDN Web Docs.
- فتح أدوات مطوري Chrome — Chrome for Developers.