لقد واجهت مؤخرًا مشكلة في استعلامات الوسائط في مشروع مبني على Angular. لا أتذكر بالضبط القيود التي جعلتني أكتب مزيجًا لتبسيط عملي ، لكنني أريد حقًا مشاركة النتيجة والحصول على تعليقات. لقد قابلت العديد من الأمثلة الأخرى المماثلة ، ولكن بالنسبة للعمل ، من الواضح والأكثر ملاءمة بالنسبة لي استخدام هذا المثال بالتحديد.
بشكل عام ، للراحة ، وضعت المتطلبات التالية لنفسي:
- يجب عرض أحجام الشاشات بشكل منفصل ، بحيث يمكنك تغيير السلوك بشكل عام في مكان واحد (على سبيل المثال ، بدلاً من "320 بكسل" ، قم ببساطة بإرسال "xs").
- يمكن أن يكون هذا الاختلاط مع استعلامات الوسائط في أكثر من اتجاه (على سبيل المثال ، ليس دائمًا فقط max-width).
- يمكن استخدام Mixin بشكل منفصل ، متجاوزًا الفئات الموصوفة بالداخل ، أو موصوفة في جسم الأصل ، متجاوزة خصائصها.
لذلك دعونا نحدد أي أذونات نحتاجها. على سبيل المثال:
$sizes: ("xs":320px, "sm":576px, "md":768px, "lg":992px, "xl":1200px);
بادئ ذي بدء ، دعنا نكتب مزيجًا يقبل بادئة النطاق المطلوب والدقة ، والتي بموجبها نقتصر:
@mixin media($minmax, $media) {
@each $size, $resolution in $sizes {
@if $media == $size {
@media only screen and (#{$minmax}-width: $resolution) {
@content;
}
}
}
}
باختصار ، نمرر اسم دقة الشاشة التي نحتاجها ، ونبحث عن قيمتها بين تلك المعلنة مسبقًا في متغير الأحجام $. بعد أن وجدناها ، نستبدلها بالحد الأدنى أو الحد الأقصى الذي تم تمريره (متغير minmax $).
مثال على الاستخدام ، بما في ذلك في mixin آخر:
@mixin blocks-width {
width: 400px;
@include media("max", "md") {
width: 100%;
}
}
من هذا المثال البسيط ، سنحصل على مزيج يغير عرض الكتلة عند <768 بكسل من 400 بكسل إلى 100٪. يجب أن تعطي الأمثلة التالية نفس النتيجة.
مثال على الاستخدام داخل الفصل:
.blocks-width {
width: 400px;
@include media("max", "md") {
width: 100%;
}
}
مثال على الاستخدام كاستعلام وسائط مستقل:
.blocks-width {
width: 400px;
}
@include media("max", "md") {
.blocks-width {
width: 100%;
}
}
ولكن ماذا لو كنت بحاجة إلى استعلام وسائط ، بما في ذلك استعلام ذو نطاق واضح (حدد دقة واحدة يعمل فيها الاستعلام عن الوسائط)؟ دعونا نوسع الخلطات الخاصة بنا قليلاً.
شخصيًا ، من الملائم بالنسبة لي وصف الدقة على النحو التالي - إذا احتجنا إلى النطاق md ، فإننا نأخذ أحجام الشاشة بين sm و md. إذا أردنا إعادة كتابة mixin بحيث نمرر دقة واحدة فقط ، فسنضطر إلى إيجاد القيمة السابقة من القائمة. نظرًا لأنني لم أجد أي طريقة للقيام بذلك بسرعة ، فقد اضطررت إلى كتابة دالة:
@function getPreviousSize($currentSize) {
$keys: map-keys($sizes);
$index: index($keys, $currentSize)-1;
$value: map-values($sizes);
@return nth($value, $index);
}
للتحقق من كيفية عمله ، استخدم التصحيح:
@debug getPreviousSize('md');
بعد ذلك ، رمزنا المعاد بناؤه قليلاً:
@mixin media($minmax, $media) {
@each $size, $resolution in $sizes {
@if $media == $size {
@if ($minmax != "within") {
@media only screen and (#{$minmax}-width: $resolution) {
@content;
}
} @else {
@if (index(map-keys($sizes), $media) > 1) {
@media only screen and (min-width: getPreviousSize($media)+1) and (max-width: $resolution) {
@content;
}
} @else {
@media only screen and (max-width: $resolution) {
@content;
}
}
}
}
}
}
المنطق هو نفسه بالنسبة للوظيفة السابقة. ولكن ، إذا كنت تريد تطبيق استعلام وسائط فقط في نطاق ، على سبيل المثال ، md ، فعند استدعاء mixin ، اكتب ما يلي:
@include media("within", "md") {
.blocks-width {
width: 100%;
}
}
بعد ذلك سنرى ملف css المترجم التالي:
@media only screen and (max-width: 768px) and (min-width: 577px)
.blocks-width {
width: 100%;
}
علاوة على ذلك ، إذا حددنا أصغر حجم للشاشة (لدينا xs) ، على سبيل المثال:
@include media("within", "xs") {
.blocks-width {
width: 100%;
}
}
ثم نحصل على نطاق من 0 إلى أصغر دقة مطابقة:
@media only screen and (max-width: 320px)
.blocks-widthh {
width: 100%;
}
بطبيعة الحال ، يمكنك إعادة كتابة استعلامات الوسائط هذه في الاتجاه الآخر ، ولكن شخصيًا ، أنا معتاد على التخطيط من أكثر إلى أقل.
شكرآ لك على أهتمامك!
محدث: تم تصحيح mixin بشكل طفيف بحيث لا تتداخل الدقة في نطاقات محدودة :) شكرا لاهتمامكمE_STRICT