اذهب إلى المحتوى

كل الأنشطة

تحدث تلقائيًا

  1. الساعة الماضية
  2. السلام عليكم. ظهرت لي رسائل الخطأ التالية بشكل مفاجئ. في الكونسول: رسالة الخطأ cookie.js:32 Uncaught Error: Cannot find module 'net' at webpackMissingModule (cookie.js:32:1) at ../node_modules/tough-cookie/lib/cookie.js (cookie.js:32:1) at options.factory (react refresh:6:1) at __webpack_require__ (bootstrap:24:1) at fn (hot module replacement:62:1) at ../node_modules/request/lib/cookies.js (cookies.js:3:1) at options.factory (react refresh:6:1) at __webpack_require__ (bootstrap:24:1) at fn (hot module replacement:62:1) at ../node_modules/request/index.js (index.js:18:1) صفحة الويب: ERROR in ../node_modules/sshpk/lib/private-key.js 7:13-30 Module not found: Error: Can't resolve 'crypto' in 'C:\Users\saadaoui\Desktop\dev_tawassol\node_modules\sshpk\lib' BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default. This is no longer the case. Verify if you need this module and configure a polyfill for it. If you want to include a polyfill, you need to: - add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }' - install 'crypto-browserify' If you don't want to include a polyfill, you can use an empty module like this: resolve.fallback: { "crypto": false } ERROR in ../node_modules/sshpk/lib/signature.js 7:13-30 Module not found: Error: Can't resolve 'crypto' in 'C:\Users\saadaoui\Desktop\dev_tawassol\node_modules\sshpk\lib' BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default. This is no longer the case. Verify if you need this module and configure a polyfill for it. If you want to include a polyfill, you need to: - add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }' - install 'crypto-browserify' If you don't want to include a polyfill, you can use an empty module like this: resolve.fallback: { "crypto": false } ERROR in ../node_modules/sshpk/lib/utils.js 27:13-30 Module not found: Error: Can't resolve 'crypto' in 'C:\Users\saadaoui\Desktop\dev_tawassol\node_modules\sshpk\lib' BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default. This is no longer the case. Verify if you need this module and configure a polyfill for it. If you want to include a polyfill, you need to: - add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }' - install 'crypto-browserify' If you don't want to include a polyfill, you can use an empty module like this: resolve.fallback: { "crypto": false } ERROR in ../node_modules/tough-cookie/lib/cookie.js 33:10-24 Module not found: Error: Can't resolve 'net' in 'C:\Users\saadaoui\Desktop\dev_tawassol\node_modules\tough-cookie\lib' ERROR in ../node_modules/tough-cookie/lib/cookie.js 34:15-35 Module not found: Error: Can't resolve 'url' in 'C:\Users\saadaoui\Desktop\dev_tawassol\node_modules\tough-cookie\lib' BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default. This is no longer the case. Verify if you need this module and configure a polyfill for it. If you want to include a polyfill, you need to: - add a fallback 'resolve.fallback: { "url": require.resolve("url/") }' - install 'url' If you don't want to include a polyfill, you can use an empty module like this: resolve.fallback: { "url": false } ERROR in ../node_modules/tunnel-agent/index.js 3:10-24 Module not found: Error: Can't resolve 'net' in 'C:\Users\saadaoui\Desktop\dev_tawassol\node_modules\tunnel-agent' ERROR in ../node_modules/tunnel-agent/index.js 4:8-22 Module not found: Error: Can't resolve 'tls' in 'C:\Users\saadaoui\Desktop\dev_tawassol\node_modules\tunnel-agent' ERROR in ../node_modules/tunnel-agent/index.js 5:9-24 Module not found: Error: Can't resolve 'http' in 'C:\Users\saadaoui\Desktop\dev_tawassol\node_modules\tunnel-agent' BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default. This is no longer the case. Verify if you need this module and configure a polyfill for it. If you want to include a polyfill, you need to: - add a fallback 'resolve.fallback: { "http": require.resolve("stream-http") }' - install 'stream-http' If you don't want to include a polyfill, you can use an empty module like this: resolve.fallback: { "http": false } ERROR in ../node_modules/tunnel-agent/index.js 6:10-26 Module not found: Error: Can't resolve 'https' in 'C:\Users\saadaoui\Desktop\dev_tawassol\node_modules\tunnel-agent' BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default. This is no longer the case. Verify if you need this module and configure a polyfill for it. If you want to include a polyfill, you need to: - add a fallback 'resolve.fallback: { "https": require.resolve("https-browserify") }' - install 'https-browserify' If you don't want to include a polyfill, you can use an empty module like this: resolve.fallback: { "https": false } ERROR in ../node_modules/tunnel-agent/index.js 8:11-28 Module not found: Error: Can't resolve 'assert' in 'C:\Users\saadaoui\Desktop\dev_tawassol\node_modules\tunnel-agent' BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default. This is no longer the case. Verify if you need this module and configure a polyfill for it. If you want to include a polyfill, you need to: - add a fallback 'resolve.fallback: { "assert": require.resolve("assert/") }' - install 'assert' If you don't want to include a polyfill, you can use an empty module like this: resolve.fallback: { "assert": false } vs code => terminal ERROR in ../node_modules/tunnel-agent/index.js 3:10-24 [1] Module not found: Error: Can't resolve 'net' in 'C:\Users\saadaoui\Desktop\dev_tawassol\node_modules\tunnel-agent' [1] [1] ERROR in ../node_modules/tunnel-agent/index.js 4:8-22 [1] Module not found: Error: Can't resolve 'tls' in 'C:\Users\saadaoui\Desktop\dev_tawassol\node_modules\tunnel-agent' [1] [1] ERROR in ../node_modules/tunnel-agent/index.js 5:9-24 [1] Module not found: Error: Can't resolve 'http' in 'C:\Users\saadaoui\Desktop\dev_tawassol\node_modules\tunnel-agent' [1] [1] BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default. [1] This is no longer the case. Verify if you need this module and configure a polyfill for it. [1] [1] If you want to include a polyfill, you need to: [1] - add a fallback 'resolve.fallback: { "http": require.resolve("stream-http") }' [1] - install 'stream-http' [1] If you don't want to include a polyfill, you can use an empty module like this: [1] resolve.fallback: { "http": false } [1] [1] ERROR in ../node_modules/tunnel-agent/index.js 6:10-26 [1] Module not found: Error: Can't resolve 'https' in 'C:\Users\saadaoui\Desktop\dev_tawassol\node_modules\tunnel-agent' [1] [1] BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default. [1] This is no longer the case. Verify if you need this module and configure a polyfill for it. [1] [1] If you want to include a polyfill, you need to: [1] - add a fallback 'resolve.fallback: { "https": require.resolve("https-browserify") }' [1] - install 'https-browserify' [1] If you don't want to include a polyfill, you can use an empty module like this: [1] resolve.fallback: { "https": false } [1] [1] ERROR in ../node_modules/tunnel-agent/index.js 8:11-28 [1] Module not found: Error: Can't resolve 'assert' in 'C:\Users\saadaoui\Desktop\dev_tawassol\node_modules\tunnel-agent' [1] [1] BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default. [1] This is no longer the case. Verify if you need this module and configure a polyfill for it. [1] [1] If you want to include a polyfill, you need to: [1] - add a fallback 'resolve.fallback: { "assert": require.resolve("assert/") }' [1] - install 'assert' [1] If you don't want to include a polyfill, you can use an empty module like this: [1] resolve.fallback: { "assert": false } شكرا على المساعدة
  3. اليوم
  4. عليك بالتوجه إلى الرابط التالي وتسجيل الدخول إذا طلب منك ذلك: https://accounts.hsoub.com/settings?service=11 ثم ستجد الاسم واسم العائلة، قم بتغييره للاسم الذي تريده، وبالأسفل اضغط على حفظ التعديلات. وستجد أنه تم تعديل الاسم هنا، وإذا لم يتم ذلك، قم بتسجيل الخروج ثم إعادة تسجيل الدخول.
  5. لماذا يسجل الموقع اسمي خطا مع العلم انني غيرته مراتان . الاسم المسجل بالموقع Tamer Faour الاسم الصحيح Tamer Hamad Faour
  6. البارحة
  7. اليوم أصبحت أغلب تطبيقات الويب تبنى باستخدام أطر العمل , و قليلون الذين يطلبون مستقلين بالخبرات الأساسية فقط , و لكن لاتقلقي فبما أنك أتممتي دورة تطوير واجهات المستخدم فيكون من السهل جدا عليكي أن تتعلمي أي اطار عمل و لن يستغرق منك ذلك وقتا طويلا, و أنصحك بأن تقومي بتطوير أكثر من مشروع قبل أن تستلمي أي مشروع من العملاء , يمكنك أن تقومي بالاطلاع على المشاريع الموجودة في مواقع العمل الحر و تختاري منها مايناسب خبراتك و مهاراتك و تقومي بتطويرها لكي تكسبي الخبرة و تحتفظي بها لديك لتضعيها في معرض أعمالك . أما بالنسبة لتطبيقات الواجهة الخلفية فلاأنصحك أن تبدأي بها الأن , أتم مجال الواجهات الأمامية و تعمقي فيه و اكسبي الخبرة فيه ثم انتقلي لتتعلمي الواجهات الخلفية. يمكنك الإطلاع على هذه التعليقات في أسئلة مشابهة لسؤالك , سوف تستفيد منها الكثير .
  8. إن كنت تريد أن تتعلم تحليل البيانات فيمكنك الاشتراك في دورة الذكاء الاصطناعي, ستتعلم فيها كل ما تحتاج إليه من الصفر دون حاجة إلى معرفة مسبقة،هذا رابط الدورة يمكنك الدخول اليه والقراءة عن الدورة أكثر. في هذا المسار ستتعلم الأساسيات و التي هي: لغة البرمجة بايثون. أدوات التحليل:مثل مكتبات pandas, و numpy و غيرها. بالإضافة إلى ذلك ستتعلم بعض المهارات المتقدمة مثل تعلم الألة و الخوارزميات الشهيرة في تعلم الألة . و بعدها عليك أن تستمر في البحث و التعلم و أهم شيء هو التطبيق العملي فالخبرة لاتأتي من مشاهدة الدروس فقط و إنما عليك أن تطبق كل شيء تتعلمه لكي تفهمه جيدا و تصبح خبيرا , و الاستمرار والمتابعة هو أهم عامل للنجاح. و هذا مقال يشرح علم تحليل البيانات بشكل مفصل https://academy.hsoub.com/programming/general/تحليل-البيانات/
  9. وعليكم السلام، ربما بسبب إحتواء الملف على كمية كبيرة من البيانات ولديك معالج أو رامات لا تستطيع تحمل ذلك. أو يوجد مشكلة في برنامج Excel نفسه وبحاجة إلى إعادة تثبيت. قم بتجربة إنشاء ملف Excel فارغ ثم فتحه، وإن لم تحدث مشكلة، إذن ربما بسبب كمية بيانات كبيرة بالملف الآخر أو مشكلة بالملف نفسه. للتأكد قم بفتح الملف على Google sheets على السحابة من خلال حساب جوجل الخاص بك.
  10. مرحبا @عزالدين بن تيتي، المشكلة على الأغلب في الملف خصوصا إذا كانت ملفات أخرى الخاصة بإكسال تشتغل بدون مشاكل، فقد يكون الملف نفسه معطوبا مما يتسبب في تعطل الجهاز، أو قد يحتوي الملف على برمجيات خبيثة تسببت في حدوث مشكلات في جهازك، جرب فتح الملف على جهاز آخر لمعرفة ما إذا كان سليما، و أيضا استخدم برنامج مكافحة الفيروسات لفحص جهازك والتأكد من خلوه من البرمجيات الخبيثة، أو كحل أخير قد يكون هناك مشكلة في برنامج إكسال لديك، حاول إعادة تثبيته. بالتوفيق إن شاء الله.
  11. في الويندوز، النواة Kernel تم تطويرها بواسطة لغة C بنسبة كبيرة وجزء منها مطور بواسطة Assembly. والنواة هي المسؤولة عن إدارة الموارد الأساسية مثل المعالج والذاكرة والأقراص الصلبة، وتتميز لغة C بسرعتها وكفاءتها، مما يجعلها مناسبة لهذه المهام. وعند الوصول للإجزاء القريبة من واجهة المستخدم ستجد أنه يتم استخدام لغة C++ أكثر ولغة C بشكل أقل. بينما لينكس ستجد أن النواة تم تطويرها بواسطة لغة C بنسبة كبيرة وجزء منها تم تطويره بواسطة Assembly كما في الويندوز. بينما تطبيقات المستخدم ستجد أنه يتم استخدام بايثون وC++ بهم.
  12. لدي نموذج في قاعدة بيانات mongo هذا هو /** * Module dependencies. */ const mongoose = require("mongoose"); /** * Schema definition */ const ModelSchema = new mongoose.Schema( { name: { type: String, required: true, unique: true, }, pathname:{ type: String, required: true, unique: true, }, title: { type: String, unique: true, default: function() { return this.name; } }, desc: { type: Array, required: true, default:[""] }, image: { data: Buffer, contentType:String }, }, { timestamps: true, } ); ModelSchema.set("toJSON", { virtuals: true, versionKey: false, transform: (doc, ret) => { delete ret._id; }, }); const Model = mongoose.model("MainCategory", ModelSchema); module.exports = Model; اريد ارسال الصور له عبر صفحة react import React, { useEffect, useState } from 'react' import { AppFooter, AppHeader, AppSidebar, DocsExample } from '../../../components' import axios from 'axios' import { CButton, CForm, CFormInput, CFormLabel, CFormTextarea } from '@coreui/react' export default function programs() { const [name, setname] = useState('') const [image, setimage] = useState(null) const [pathname, setpath] = useState('') const [title, settitle] = useState() const handleImageChange = (e) => { const file = e.target.files[0]; const formData = new FormData(); formData.append("image", file); setimage(formData); }; const handleSubmit = async (e) => { e.preventDefault() try { await axios.post('https://api.wesamelnagah.com/api/maincategory', { name, pathname, image, headers: { "Content-Type": "multipart/form-data", }, // title }) await axios.post('https://api.wesamelnagah.com/api/uplode',image, { headers: { "Content-Type": "multipart/form-data", }, }) setname('') setimage(null) setpath('') } catch (error) { console.log(error) } } return ( <div className="programs_container"> <AppSidebar /> <div className="wrapper d-flex flex-column min-vh-100"> <AppHeader /> <div className="body flex-grow-1"> <CForm onSubmit={handleSubmit}> <div className="mb-3"> <CFormLabel htmlFor="exampleFormControlInput1"> عنوان الباقة</CFormLabel> <CFormInput type="text" id="exampleFormControlInput1" onChange={(e) => setname(e.target.value)} /> <CFormLabel htmlFor="exampleFormControlInput1"> مسار الباقة</CFormLabel> <CFormInput type="text" id="exampleFormControlInput1" onChange={(e) => setpath(e.target.value)} /> </div> <div className="mb-3"> <CFormLabel htmlFor="formFile">صورة الباقة</CFormLabel> <CFormInput type="file" id="formFile" onChange={handleImageChange} /> </div> <div className="d-grid gap-2 col-6 mx-auto"> <CButton color="primary" type="submit"> Submit </CButton> </div> </CForm> </div> <AppFooter /> </div> </div> ) } هل يستطيع احد مساعدتي للقيام بذلك
  13. هل يوجد مسار لمحلل البيانات ؟ وإن كان يوجد مسار لمحلل البيانات فما هو مسار محلل البيانات من الصفر إلى الاحتراف ؟ وماذا بعد تعلم الأساسيات في مجال تحليل البيانات ؟
  14. لدي سؤال بخصوص العمل في مواقع العمل الحر اتممت دورة تطوير واجهات المستخدم لكني وجدت بعد الاطلاع ان المواقع العمل الحر تتطلب مهارات اكثر من مهارات التي تعلمتها في الدورة كتعلم اطار react وvue وتعلم الواجهات الخلفية انا حاليا اعمل على تطوير مهاراتي في مجال تطوير الواجهات الامامية واحاول تعلم الواجهات الخلفية واريد نصيحة هل اؤجل موضوع العمل الحر حتى اطور من مهاراتي وماهي المهارات التي يجب ان اتعلمها حتى اقام بانشاء مواقع حقيقة ودبناميكيه تناسب سوق العمل
  15. شكرا لك لدي طلب اخر بعد اذنك اريد حفظ اسم الصورة ومسارها مع الكائن الذي سيرسل الى قاعدة البيانات
  16. كان يجب ان تقوم بتغير اول معامل فقط هكذا formData.append("image", file); وقم بطباعة ال body فى الخادم وتاكد من ارسال الصورة بشكل صحيح
  17. لم تظهر ايضا ... هكذا عدلت اسم الحقل هل هذا صحيح const handleImageChange = (e) => { const file = e.target.files[0]; const formData = new FormData(); formData.append("image", image); setimage(formData); console.log(image.type); };
  18. السلام عليكم عندي مشكل واجهني في برنامج excel اتمنى الافاده المشكل كالتالي: لدي فاتورة اكسل اريد ان اضيف اليها شريط زمني بحيث كل يوم اغير من بيانات الفاتورة دون عمل عدة نسخ للفاتورة وكما اريد الرجوع الى اي يوم اريد لتاكد من بيانات فاتورة سابقة وشكرا لكل من افادني
  19. عند ارسال ملف عن طريق axios يجب وضع الملف فى formData حتى يتم رفعه الى الخادم بشكل صحيح ووضع "Content-Type": "multipart/form-data" فى ال headers . لذلك قم بتغير الدالة handleImageChange هكذا حتى يتم وضع formData . const handleImageChange = (e) => { const file = e.target.files[0]; const formData = new FormData(); formData.append("file", file); setimage(formData); console.log(file.type); }; ولكن قم باستبدال كلمة file باسم الحقل الذى تقوم باستقباله فى الخادم. وقم بتغير هذا السطر ايضا. الى الكود التالى . await axios.post('https://api.wesamelnagah.com/api/uplode',image, { headers: { "Content-Type": "multipart/form-data", }, }) والان من المفترض ان يتم تحميل الصورة جيدا على الخادم.
  20. import React, { useEffect, useState } from 'react' import { AppFooter, AppHeader, AppSidebar, DocsExample } from '../../../components' import axios from 'axios' import { CButton, CForm, CFormInput, CFormLabel, CFormTextarea } from '@coreui/react' export default function programs() { const [name, setname] = useState('') const [image, setimage] = useState(null) const [pathname, setpath] = useState('') const [title, settitle] = useState() const handleImageChange = (e) => { const file = e.target.files[0]; setimage(file); console.log(file.type); }; const handleSubmit = async (e) => { e.preventDefault() try { await axios.post('https://api.wesamelnagah.com/api/maincategory', { name, pathname, // title }) await axios.post('https://api.wesamelnagah.com/api/uplode', { image, }) setname('') setimage(null) setpath('') } catch (error) { console.log(error) } } console.log(typeof image); return ( <div className="programs_container"> <AppSidebar /> <div className="wrapper d-flex flex-column min-vh-100"> <AppHeader /> <div className="body flex-grow-1"> <CForm onSubmit={handleSubmit}> <div className="mb-3"> <CFormLabel htmlFor="exampleFormControlInput1"> عنوان الباقة</CFormLabel> <CFormInput type="text" id="exampleFormControlInput1" onChange={(e) => setname(e.target.value)} /> <CFormLabel htmlFor="exampleFormControlInput1"> مسار الباقة</CFormLabel> <CFormInput type="text" id="exampleFormControlInput1" onChange={(e) => setpath(e.target.value)} /> </div> <div className="mb-3"> <CFormLabel htmlFor="formFile">صورة الباقة</CFormLabel> <CFormInput type="file" id="formFile" onChange={handleImageChange} /> </div> <div className="d-grid gap-2 col-6 mx-auto"> <CButton color="primary" type="submit"> Submit </CButton> </div> </CForm> </div> <AppFooter /> </div> </div> ) } لدي هذا الform وعند ارسال الصور ترجع لي استجابة نجاح ولكن الصورة لا تذهب الى المجلد الخاص بالصور مع العلم انني عندما قمت باختبار api على postman نجحت وذهبت الصور الى المجلد المقصود فاين الخطا في كود react ؟
  21. ان امتداد vsdx هو امتداد خاص ب Microsoft Visio وهو عبارة عن برنامج لرسم xmd و diagrams . يمكنك فتح الملف عن طريق البحث على جوجل عن diagram online و فتح اول موقع لديكى ثم وضع الملف فى الموقع وسيتم فتحه . وهذه صورة لمحتوى الملف
  22. احتاج مساعده في فتح الملف باسرع وقت amal1.vsdx
  23. يُعد استخدام الشبكة Grid ميزة من ميزات تخطيط الصفحات اعتمادًا على CSS. لكن ما جرى قبل ظهور هذه الخاصية هو اعتماد أسلوب تعويم العناصر float أو استخدام ميزات أخرى. إذًا كان عليك أن تتخيل مثلًا صفحتك بعدة أعمدة ( 4 أو 6 أو 12 وهكذا) ومن ثم العمل على ترتيب المحتوى ضمن هذه الأعمدة التخيلية. ما ستكتشفه في هذا المقال هي الأساليب القديمة في تخطيط الصفحات كي تفهم طريقة عملها إن اضطررت للعمل على مشروع قديم. عليك قبل البدء في قراءة هذا المقال أن: تطلع على أساسيات HTML. تفهم أساسيات عمل CSS. تخطيط الصفحات والشبكات قبل ظهور تخطيط شبكات CSS قد يتفاجأ القادمون الجدد الذين لديهم خلفية في التصميم أن شبكات CSS لم تظهر إلا مؤخرًا، وقد استخدمت قبلها أساليب متنوعة ليست مثالية في إنشاء تصميمات شبيهة بالشبكات، ندعوها الآن بالأساليب القديمة أو الموروثة legacy. تعتمد المشاريع الحديثة على تخطيط شبكات CSS برفقة واحدة أو أكثر من أساليب التخطيط الحديثة لإنشاء أساس لأي تخطيط. لكن، قد تصادف تخطيط شبكة يعتمد على الأساليب القديمة بين الفينة والأخرى، لهذا من المفيد أن تتعرف على طريقة عملها ولماذا تختلف هذه الشبكات عن شبكات CSS. سنشرح في هذا المقال كيف تعمل منظومات الشبكات القديمة وإطارات عمل الشبكات grid frameworks اعتمادًا على التعويم ومبدأ الصندوق المرن. وقد تتفاجأ إن درست شبكات CSS بتعقيد هذه المنظومات، لكن معرفتك ستساعدك على كتابة شيفرة تراجع أو شيفرة آمنة من أجل المتصفحات التي لا تدعم الأساليب الحديثة في التخطيط. إضافة إلى ذلك، ستكون قادرًا على العمل على مشاريع سابقة تعتمد هذه الطرق القديمة في التخطيط. ومن المهم أن تتذكر دائمًا أن منظومات الشبكات القديمة لا تعمل إطلاقًا بالطريقة التي يعمل بها تخطيط شبكات CSS، بل تعتمد فكرة إعطاء العناصر أبعادًا محددةً ثم دفعها بطريقة تجعلها تبدو أنها شبكة. تخطيط من عمودين لنبدأ بأكثر الأمثلة بساطة وهو تخطيط مكون من عمودين. بإمكانك متابعة العمل معنا بإنشاء ملف باسم index.html على حاسوبك ثم نقل قالب HTML الخاص بالمثال إليه ومن ثم وضع الشيفرة التالية في أماكنها المناسبة ضمن القالب. سترى في نهاية المثال كيف ستبدو نتيجة العمل مباشرة. أولًا لابد من توفير محتوىً ما لوضعه ضمن الأعمدة، لهذا، استبدل كل ما هو موجود ضمن جسم الصفحة بالشيفرة التالية: <h1>2 column layout example</h1> <div> <h2>First column</h2> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat vulputate. Duis felis orci, pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies tellus laoreet sit amet. Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet orci vel, viverra egestas ligula. Curabitur vehicula tellus neque, ac ornare ex malesuada et. In vitae convallis lacus. Aliquam erat volutpat. Suspendisse ac imperdiet turpis. Aenean finibus sollicitudin eros pharetra congue. Duis ornare egestas augue ut luctus. Proin blandit quam nec lacus varius commodo et a urna. Ut id ornare felis, eget fermentum sapien. </p> </div> <div> <h2>Second column</h2> <p> Nam vulputate diam nec tempor bibendum. Donec luctus augue eget malesuada ultrices. Phasellus turpis est, posuere sit amet dapibus ut, facilisis sed est. Nam id risus quis ante semper consectetur eget aliquam lorem. Vivamus tristique elit dolor, sed pretium metus suscipit vel. Mauris ultricies lectus sed lobortis finibus. Vivamus eu urna eget velit cursus viverra quis vestibulum sem. Aliquam tincidunt eget purus in interdum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. </p> </div> يحتاج كل عمود إلى عنصر خارجي كي يضم محتواه لهذا سنحاول فعل ذلك. اخترنا في مثالنا العنصر الحاوي <div>، وبإمكانك أيضًا اختيار عنصر آخر أكثر ملائمة من ناحية الدلالة مثل <article> و <section> و <aside>. أما بالنسبة لتنسيق CSS، فعليك أولًا تطبيق ما يلي على صفحتك لضبطها مبدئيًا: body { width: 90%; max-width: 900px; margin: 0 auto; } سيشكل جسم الصفحة 90% من نافذة العرض لكن دون أن يزيد عن 900 بكسل وعندها سيحافظ على هذا الاتساع ويتمركز في وسط الصفحة. ستمتد العناصر الأبناء له (العنصر <h1> والعنصران <div>) حتى يشغلا كامل اتساع الجسم. ولو أردنا أن يعوم العنصران <div> إلى جوار بعضهما، لا بد عندها من ضبط اتساعهما ليشغلا 100% من اتساع العنصر الأب أو أقل. لهذا أضف الشيفرة التالية إلى نهاية تنسيقات CSS: div:nth-of-type(1) { width: 48%; } div:nth-of-type(2) { width: 48%; } ضبطنا اتساع كلا العنصرين ليشغل 48% من مساحة العنصر الأب وبالتالي سيشغلان معًا 96% من المساحة الكلية له، وتركنا 4% لتمثل قناة تفصل بينهما وتعطي المحتوى مجالًا للتنفس. علينا الآن تعويم الأعمدة كالتالي: div:nth-of-type(1) { width: 48%; float: left; } div:nth-of-type(2) { width: 48%; float: right; } تكون النتيجة النهائية للمثال كالتالي: See the Pen Legacy layout by Hsoub Academy (@HsoubAcademy) on CodePen. ستلاحظ أننا استخدمنا نسب مئوية لتقدير الاتساعات، وهي استراتيجية جيدة كونها تنشئ تخطيطًا مرنًا أو "سائلًا" يمكن ضبطه ليلائم مختلف أبعاد الشاشات ويحافظ على نفس نسبة الاتساع الذي يأخذه كل عمود ضمن الشاشات الأصغر. حاول أن تغيّر أبعاد نافذة المتصفح وراقب ما يحدث! ملاحظة: يمكنك أن تتابع طريقة عمل هذا المثال على جيت-هاب (كما يمكنك الاطلاع على شيفرته المصدرية) إنشاء إطار عمل لشبكة وفق الأسلوب القديم تستخدم معظم أطر العمل القديمة سلوك التعويم float كي تعوّم أحد الأعمدة إلى جانب الآخر والحصول على تخطيط يشبه الشبكة. ويساعدك العمل على إنشاء شبكة من هذا النوع في معرفة طريقة عملها ويقدم لك بعض المفاهيم المتقدمة كي تبني على الأساسيات التي تعلمناها في مقال تعويم العناصر في CSS. يُعد إطار العمل الأسهل لهذا النوع من الشبكات هو الإطار ذو الاتساع الثابت. وكل ما نحتاجه هو معرفة مقدار الاتساع المطلوب لتصميمنا، وكم عدد الأعمدة وما هو اتساعها واتساع الأقنية الفاصلة بينها. بينما إن أردنا أن نبني شبكتنا على شكل أعمدة تتسع وتتقلص وفقًا لاتساع نافذة المتصفح، لا بد حينها من حساب اتساع الأعمدة والأقنية كنسب مئوية. سنلقي نظرة في القسم التالي على كيفية إنشاء التخطيطين السابقين، وسننشئ شبكة من 12 عمودًا وهو خيار شائع جدًا وواسع الاستخدام لحالات كثيرة كونه عدد قابل للقسمة على 2 و 4 و 6. شبكة بسيطة ثابتة الاتساع لننشئ بداية شبكة ذات أعمدة ثابتة الاتساع، وعليك أن تبدأ بإنشاء نسخة عن ملف المثال على حاسوبك والتي تضم الشيفرة التالية لجسم الصفحة: <div class="wrapper"> <div class="row"> <div class="col">1</div> <div class="col">2</div> <div class="col">3</div> <div class="col">4</div> <div class="col">5</div> <div class="col">6</div> <div class="col">7</div> <div class="col">8</div> <div class="col">9</div> <div class="col">10</div> <div class="col">11</div> <div class="col">12</div> </div> <div class="row"> <div class="col span1">13</div> <div class="col span6">14</div> <div class="col span3">15</div> <div class="col span2">16</div> </div> </div> إن الغاية من ذلك الحصول على شبكة من سطرين و 12 عمودًا، إذ يظهر السطر الأول قياس كل عمود بينما يعرض السطر الثاني مناطق مختلفة القياسات من الشبكة. أضف ضمن العنصر <style> الشيفرة التالية والتي تعطي لحاوية التغليف اتساعًا مقداره 980 بكسل مع حشوة إلى جهة اليمين مقدارها 20 بكسل. يترك لنا ذلك اتساعًا مقداره 960 بكسل للأعمدة والأقنية الفاصلة بينها، والسبب في أن الحشوة قد استهلكت مساحة من الاتساع الكلي هو أننا ضبطنا قيمة الخاصية box-sizing على القيمة border-box: * { box-sizing: border-box; } body { width: 980px; margin: 0 auto; } .wrapper { padding-right: 20px; } استخدم الآن حاوية السطر التي تغلف كل سطر من أسطر الشبكة لتمييز كل سطر عن الآخر وذلك من خلال إضافة شيفرة التنسيق التالية بعد شيفرة التنسيق السابقة: .row { clear: both; } ويعني تطبيق هذا التباعد أنه لا ضرورة لملئ السطر بالعناصر حتى نحصل على 12 عمودًا، بل ستبقى الأسطر منفصلة وغير متداخلة مع بعضها. أما بالنسبة للأقنية الفاصلة فقط جعلنا اتساعها 20 بكسل وأنشأناها على شكل هامش إلى يسار العمود بما في ذلك العمود الأول وذلك لموازنة الحشوة الموجودة إلى يمين الحاوية والتي كان اتساعها 20 بكسل. وبالتالي لدينا الآن 12 قناة تفصل بين الأعمدة اتساعها 12x20=240. لا بد من طرح المساحة السابقة من 960 بكسل وتكون النتيجة 720 بكسل للأعمدة جميعها وبتقسيم هذه القيمة على 12 وهو عدد الأعمدة سيكون اتساع العمود 60 بكسل. ننشئ كخطوة ثانية الصنف col. الذي يضبط العمود ويعوّمه إلى اليسار، إذ ضبطنا فيه الخاصية margin-left على القيمة 20px لإنشاء قناة فصل، ومنحناه اتساعًا width مقداره 60 بكسل، إليك قواعد التنسيق اللازمة: .col { float: left; margin-left: 20px; width: 60px; background: rgb(255, 150, 150); } سيظهر السطر الأول بأعمدة مفردة وكأنه شبكة. ملاحظة: منحنا كل عمود لونًا أحمر فاتح لكي ترى تمامًا الاتساع الذي يشغله. أما تخطيط الحاوية التي نريدها أن تمتد إلى عدة أعمدة فيتطلب أصنافًا خاصة لضبط قيم الاتساع للأعمدة المطلوبة إضافة إلى اتساع الأقنية بينها. نحتاج في مثالنا إلى صنف جديد ليسمح للحاويات أن تمتد بين العمودين 2 و 12. وينتج كل اتساع عن إضافة اتساع كل عمود من تلك الأعمدة إلى اتساع أقنية الفصل والتي عددها أقل دائمًا بواحد من عدد الأعمدة. أضف الشيفرة التالية إلى آخر شيفرة CSS: /* Two column widths (120px) plus one gutter width (20px) */ .col.span2 { width: 140px; } /* Three column widths (180px) plus two gutter widths (40px) */ .col.span3 { width: 220px; } /* And so on… */ .col.span4 { width: 300px; } .col.span5 { width: 380px; } .col.span6 { width: 460px; } .col.span7 { width: 540px; } .col.span8 { width: 620px; } .col.span9 { width: 700px; } .col.span10 { width: 780px; } .col.span11 { width: 860px; } .col.span12 { width: 940px; } بهذه الأصناف التي أنشأناها سنتمكن من وضع أعمدة مختلفة الاتساع ضمن الشبكة. حاول أن تحفظ التغييرات وتعيد تحميل الصفحة لترى تأثيرها. ملاحظة: إن وجدت صعوبة في تطبيق المثال السابق، الق نظرة عليه بشكله النهائي على جت-هاب (تستطيع أيضًا تنفيذه مباشرة هناك). حاول أن تعدّل الأصناف التي تطبقها على عناصرك أو حتى إضافة أو إزالة بعض الحاويات، لترى كيف يمكن أن يتغير التخطيط. إذ يمكنك مثلًا أن تجعل السطر الثاني يبدو كالتالي: <div class="row"> <div class="col span8">13</div> <div class="col span4">14</div> </div> لقد حصلنا الآن على شبكة يمكنك فيها تعريف عدد الأسطر والأعمدة في كل منها، ومن ثم وضع المحتوى الذي تريد في كل حاوية. إنشاء شبكة مرنة أو "سائلة" تعمل كما رأينا الشبكة السابقة جيدًا، لكن مشكلتها هو اتساعها الثابت. لكن ما نحتاجه حقًا هو شبكة مرنة تنمو وتتقلص وفقًا لاتساع نافذة عرض المتصفح. ولإنجاز الأمر، يمكن تحويل وحدات الاتساع من البكسل إلى نسب مئوية. تُعطى المعادلة التي تحوّل الاتساع الثابت إلى نسبة مئوية مرنة التالي: target / context = result بالنسبة إلى مثالنا سيكون الاتساع المستهدف للعمود target هو 60 بكسل والسياق أو الاتساع الكلي context هو 960 بكسل. سنستخدم هذه المعادلة لحساب النسب المئوية: 60 / 960 = 0.0625 بإزاحة الفاصلة العشرية مرتبتين إلى اليمين نحصل على النسبة المئوية 6.25%، ونستطيع الآن استبدال اتساع العمود المقدّر 60 بكسل بالنسبة المئوية 6.25%. سنفعل الشيء نفسه لضبط اتساع الأقنية الفاصلة: 20 / 960 = 0.02083333333 لهذا نستبدل قيمة الخاصية margin-left في الصنف col. وقيمة الخاصية padding-right في الصنف wrapper. لتصبحان 2.083%. تحديث الشبكة في مثالنا لتبدأ العمل في هذا القسم أنشئ نسخة جديدة عن المثال السابق على جهازك أو نسخة جديدة عن ملف المثال لتستخدمه كنقطة انطلاق. غيّر قاعدة التنسيق الثانية في المحدد wrapper. كالتالي: body { width: 90%; max-width: 980px; margin: 0 auto; } .wrapper { padding-right: 2.08333333%; } لم نغير قيمة الاتساع width لتصبح كنسبة مئوية فقط، بل أضفنا الخاصية max-width كي لايصبح التخطيط واسعًا أكثر مما هو مطلوب. عدّل بعد ذلك القاعدة الرابعة في المحدد col. كالتالي: .col { float: left; margin-left: 2.08333333%; width: 6.25%; background: rgb(255, 150, 150); } سنبدأ الآن الجزء الذي يتطلب مزيدًا من العمل، ونحتاج إلى تحديث كل قواعد المحددات col.span. كي تستخدم النسب المئوية بدلًا من البكسل. يستغرق الأمر وقتًا لإنجاز الحسابات، لكن لتوفير الوقت أجريت هذه الحسابات مسبقًا. حدّث الكتلة السفلية من قواعد CSS كالتالي: /* Two column widths (12.5%) plus one gutter width (2.08333333%) */ .col.span2 { width: 14.58333333%; } /* Three column widths (18.75%) plus two gutter widths (4.1666666) */ .col.span3 { width: 22.91666666%; } /* And so on… */ .col.span4 { width: 31.24999999%; } .col.span5 { width: 39.58333332%; } .col.span6 { width: 47.91666665%; } .col.span7 { width: 56.24999998%; } .col.span8 { width: 64.58333331%; } .col.span9 { width: 72.91666664%; } .col.span10 { width: 81.24999997%; } .col.span11 { width: 89.5833333%; } .col.span12 { width: 97.91666663%; } احفظ التغييرات التي أجريتها على الشيفرة وأعد تحميل الصفحة ثم حاول تغيير اتساع نافذة المتصفح. من المفترض أن ترى كيف يتغير اتساع الأعمدة بما يلائم اتساع نافذة المتصفح. ملاحظة: إن وجدت صعوبة في تطبيق المثال السابق، الق نظرة عليه بشكله النهائي على جت-هاب (تستطيع أيضًا تنفيذه مباشرة). إجراءات حسابات أسهل باستخدام الدالة ()calc بإمكاننا استخدام الدالة ()calc لتنفيذ العمليات الحسابية ضمن شيفرة CSS، إذ تسمح لك بإدخال معادلات رياضية بسيطة لحساب قيمة CSS. هذه الدالة مفيدة خصوصًا عندما تضطر لتنفيذ علاقات رياضية معقدة، كما تساعد في تنفيذ حسابات باستخدام وحدات مختلفة كان تريد مثلًا أن يكون ارتفاع العنصر 100% من ارتفاع العنصر الأب دائمًا بينما يكون ارتفاعه 50 بكسل. بالعودة إلى شبكتنا، نجد أن أي عمود يمتد ليغطي أكثر من عمود في شبكتنا له الاتساع 6.25% مضروبًا بعدد الأعمدة التي يمتد عليها ومضافًا إليه الاتساع 2.083% مضروبًا بعدد الأقنية الفاصلة (وهو عدد الأعمدة ناقصًا واحد). تسمح لنا الدالة ()calc بإجراء الحسابات السابقة ضمن قيمة الخاصية width، فمن أجل أي عمود يمتد على أربعة أعمدة مثلًا يمكن تنفيذ الشيفرة التالية: .col.span4 { width: calc((6.25% * 4) + (2.08333333% * 3)); } جرّب أن تستبدل الشيفرة في كتلة CSS الأخيرة بالقواعد التالية، ثم أعد تحميل الصفحة لترى النتيجة: .col.span2 { width: calc((6.25% * 2) + 2.08333333%); } .col.span3 { width: calc((6.25% * 3) + (2.08333333% * 2)); } .col.span4 { width: calc((6.25% * 4) + (2.08333333% * 3)); } .col.span5 { width: calc((6.25% * 5) + (2.08333333% * 4)); } .col.span6 { width: calc((6.25% * 6) + (2.08333333% * 5)); } .col.span7 { width: calc((6.25% * 7) + (2.08333333% * 6)); } .col.span8 { width: calc((6.25% * 8) + (2.08333333% * 7)); } .col.span9 { width: calc((6.25% * 9) + (2.08333333% * 8)); } .col.span10 { width: calc((6.25% * 10) + (2.08333333% * 9)); } .col.span11 { width: calc((6.25% * 11) + (2.08333333% * 10)); } .col.span12 { width: calc((6.25% * 12) + (2.08333333% * 11)); } ملاحظة1: إن وجدت صعوبة في تطبيق المثال السابق، الق نظرة عليه بشكله النهائي على جت-هاب (تستطيع أيضًا تنفيذه مباشرة). ملاحظة2: قد لا تتمكن من تطبيق المثال لأن المتصفح لا يدعم الدالة ()calc مع أنها مدعومة جيدًا في أغلب المتصفحات وصولًا إلى مايكروسوفت إنترنت إكسبلورر IE9. منظومات الشبكات الدلالية وغير الدلالية إن إضافة أصناف التنسيق إلى شيفرة HTML لتعريف التخطيطات يعني أن شيفرتك ومحتوى صفحتك مرهونان تمامًا بمنظورك الشخصي، لهذا قد تسمع أن هذه الطريقة في استخدام أصناف CSS هي طريقة غير دلالية أي لا تصف تمامًا كيف ينظَّم المحتوى بدلًا من استخدام الأصناف لتوصيف المحتوى، وهذا هو الأمر في حالتنا مع الأصناف span. لا يُعد النهج الذي استخدمناه هو المنهج الوحيد، بل يمكنك أن تقرر ما هي أبعاد شبكتك ثم تضيف معلومات عن هذه الأبعاد إلى قواعد الصفوف الدلالية الموجودة. فلو كان لديك العنصر <div> الذي يمتلك الصنف content وأردته أن يمتد على 8 أعمدة، يمكن إضافة القاعدة التالية إلى المحدد content.: .content { width: calc((6.25% * 8) + (2.08333333% * 7)); } ملاحظة: إن كنت تستخدم معالج أولي للتنسيق مثل Sass تكون قادرًا على إنشاء توجيه mixin@ لإدراج تلك القيم في أي مكان تريده من الصفحة. تمكين حاويات الإزاحة في الشبكة تعمل شبكتنا جيدًا طالما أننا نريد أن تتدفق الحاويات ابتداءً من الطرف اليميني للشبكة. لكن إن أردنا ترك فراغ بحجم عمود قبل أول حاوية أو بين حاويتين، لا بد عندها من إيجاد نوع من الإزاحة باستخدام صنف تنسيق يضيف هامشًا إلى اليسار كي يدفع الموقع عبر الشبكة. لنحاول أن نفعل ذلك، ولنبدأ بالشيفرة السابقة أو استخدم ملف المثال كنقطة انطلاق. شننشئ أيضًا صنفًا يعمل على إزاحة الحاوية بمقدار اتساع عمود واحد. أضف الشيفرة التالية في شيفرة CSS: .offset-by-one { margin-left: calc(6.25% + (2.08333333% * 2)); } أو إن أردت حساب النسب المئوية لاتساع الأعمدة بنفسك، استخدم الشيفرة التالية: .offset-by-one { margin-left: 10.41666666%; } بإمكانك الآن إضافة هذا الصنف إلى أية حاوية تريد كي تترك مساحة فارغة باتساع عمود من ناحية اليسار. فلو كان لدينا مثلًا شيفرة HTML التالية: <div class="col span6">14</div> استبدلها بهذه الشيفرة: <div class="col span5 offset-by-one">14</div> ملاحظة: انتبه إلى ضرورة تقليل عدد الأعمدة التي تريدها أن تمتد كي تترك مساحة للإزاحة. جرّب تحميل وتحديث الصفحة لترى الفرق، وبإمكانك أن ترى المثال على جيت-هاب وأن تجربته هنالك مباشرة. سيظهر المثال بشكله النهائي كالتالي: تمرين: هل بإمكانك كتابة صنف offset-by-two لإزاحة عمود بمقدار عمودين؟ محدودية الشبكة المعوّمة عند استخدام شبكة كهذه لا بد من حساب مجموع الاتساعات الإجمالي بشكل صحيح، وأن لا تضع عناصر في صف تجعله يمتد إلى أعمدة أكثر مما يمكنه أن يضم. ونظرًا للطريقة التي يعمل وفقها مبدأ التعويم، إن أصبح عدد أعمدة الشبكة أكثر مما تستوعبه الشبكة ستنتقل العناصر في نهاية السطر إلى سطر جديد وتخرّب الشبكة. تذكر أيضًا، إن ازداد اتساع محتوى عنصر أكثر من قدرة السطر على استيعابه سيطفح المحتوى خارج العمود ويبدو الأمر كارثيًا. وتبقى المحدودية الأهم لهذا الشبكة هي أنها وحيد البعد، فما نفعله هو التعامل مع أعمدة وجعل العناصر تتمدد على عدد منها ولا نتعامل مع أسطر فعليًا. من الصعب إذًا التعامل مع هذه التخطيطات القديمة للتحكم بارتفاع العناصر دون أن تحدد هذه الإرتفاع صراحة وهذه مقاربة لا تتمتع بالمرونة إطلاقًا، فلا يمكن أن تضمن النتائج ما لم تضمن أنّ المحتوى سيكون دائمًا بارتفاع محدد. شبكات الصندوق المرن إن اطلعت على مقالنا السابق حول [تخطيط الصندوق المرن]() فقد ترى أن هذا التخطيط هو الحل المثالي لإنشاء شبكة عناصر. إذ توجد بالفعل الكثير من تخطيطات الشبكات المعتمدة على الصندوق المرن وتخطيطات صندوق مرن التي تحل الكثير من المشاكل التي شرحناها في هذا المقال. لكن لم يُصمم الصندوق المرن لإنشاء منظومة شبكة لهذا ستظهر مشاكل عدة عند استخدامه. وكمثال بسيط يشرح ما نقصده، سنعود إلى نفس شيفرة المثال السابق ومن ثم نستخدم شيفرة CSS التالية لتنسيق الأصناف wrapper و raw و col: body { width: 90%; max-width: 980px; margin: 0 auto; } .wrapper { padding-right: 2.08333333%; } .row { display: flex; } .col { margin-left: 2.08333333%; margin-bottom: 1em; width: 6.25%; flex: 1 1 auto; background: rgb(255, 150, 150); } حاول أن تجري التعديلات السابقة على نسختك من المثال أو الق نظرة على نسخته على جت-هاب ( كما يمكنك الاطلاع على طريقة عمله أيضًا) ما فعلناه هنا هو تحويل كل سطر إلى حاوية مرنة فلا زلنا نحتاج إلى الأسطر في شبكات الصندوق المرن كي نستطيع استخدام العناصر التي يصل مجموع اتساعاتها إلى أقل من 100%. لهذا ضبطنا الخاصية display للحاوية على القيمة flex. ضبطنا أيضًا قيمة الخاصية flex في الصنف col. على القيمة 1 لتجعل العنصر يتمدد، وكذلك الخاصية flex-shrink على القيمة 1 كي يتقلص العنصر. أما قيمة الخاصية flex-basis فكانت auto لأن العنصر له اتساع محدد، وتستخدم تلك القيمة هذا الاتساع كقيمة للخاصية flex-basis. لدينا 12 صندوق في السطر الأول ضمن شبكة تنمو وتتقلص بشكل متماثل مع تغيّر اتساع نافذة العرض. وفي السطر الثاني لدينا فقط 4 أعمدة تتمدد وتتقلص أيضًا على أساس الاتساع المحدد 60 بكسل. وهكذا ستتمكن الأعمدة الأربعة في السطر الثاني من التمدد أكثر من الأعمدة في السطر الأول وستشغل هذه الأعمدة مساحة السطر الثاني بأكملها: ولإصلاح الأمر لابد من استخدام الأصناف span لتزويدنا باتساع يستبدل تلك القيمة التي تستخدمها الخاصية flex-basis للعنصر المحدد. وهذه الأصناف لا تحترم أيضًا تخطيط الشبكة الذي تنتظم وفقه العناصر لأنها لا تعرف شيئًا عن الشبكة. فالصندوق المرن تخطيط وحيد البعد ويتعامل مع أسطر أو أعمدة وليس الاثنان معًا. لهذا السبب لا يمكن إنشاء شبكة صريحة من أعمدة وأسطر، وهذا يعني أننا لا زلنا بحاجة إلى حساب نسب مئوية للأبعاد كما في عملية تعويم العناصر floating. مع ذلك قد تقرر استخدام الشبكة المرنة بدلًا من التعويم لأنها تقدم ميزات أفضل من ناحية المحاذاة وتوزيع المساحات الفارغة. لكن لا بد من الانتباه أنك تستخدم أداة لم تخصص لهذا الغرض، وقد تشعر أنك تدور في حلقات إضافية حتى تصل إلى النتيجة المطلوبة. شبكات تؤمنها أطراف خارجية أخرى بعد أن تعرفنا على طريقة حساب الأبعاد في شبكتنا، بإمكاننا الآن استيعاب بعض المنظومات التي صممتها أطراف أخرى للاستخدامات العامة. فإن بحثت في الويب عن " أطر عمل شبكات CSS" أو "CSS Grid framework" ستجد عددًا كبيرًا من الخيارات منها Bootstrap و Foundation والتي تضم تخطيط شبكة خاصة بها. كما ستجد منظومات شبكات مستقلة جرى تطويرها باستخدام CSS أو باستخدام معالجات أولية. لنلق نظرة على إحدى هذه المنظومات المستقلة لنعرض التقنيات الشائعة في إطارات عمل الشبكات. سنستخدم شبكة تمثلًا جزءًا من إطار العمل Skeleton وهو إطار عمل CSS بسيط. لهذا انتقل إلى موقع الويب الخاص بإطار العمل ثم نزّل الملف المضغوط الخاص بإطار العمل واستخرج ملفاته إلى حاسوبك ثم انسخ الملفين skeleton.css و normalize.css إلى مجلد جديد. انسخ أيضًا الملف html-skeleton.html إلى نفس المجلد السابق. اربط الملفين Normalize و skeleton بصفحة الويب بإضافة ما يلي إلى ترويسة الصفحة: <link href="normalize.css" rel="stylesheet" /> <link href="skeleton.css" rel="stylesheet" /> يتضمن الملف أكثر من نظام شبكة كما يضم شيفرة لتنسيق خط الكتابة وتنسيق عناصر أخرى يمكنك الاستفادة منها كنقطة انطلاق. سنترك كل شيء كما هو افتراضيًا، فالشبكة الافتراضية هي التي نحتاجها حاليًا. ملاحظة: تُعد المكتبة Normalize مكتبة تنسيقات CSS مفيدة حقًا كتبها نيكولاس غالفر، وتجري بعض الإصلاحات الأساسية على التخطيط ليظهر التنسيق الافتراضي للعناصر أكثر اتساقًا ضمن المتصفح. نستخدم تاليًا نفس شيفرة HTML للمثال السابق، لهذا أضف ما يلي إلى جسم ملف HTML: <div class="container"> <div class="row"> <div class="col">1</div> <div class="col">2</div> <div class="col">3</div> <div class="col">4</div> <div class="col">5</div> <div class="col">6</div> <div class="col">7</div> <div class="col">8</div> <div class="col">9</div> <div class="col">10</div> <div class="col">11</div> <div class="col">12</div> </div> <div class="row"> <div class="col">13</div> <div class="col">14</div> <div class="col">15</div> <div class="col">16</div> </div> </div> كي نبدأ باستخدام Skeleton لا بد أن يمتلك عنصر التغليف <div> الصنف container وهو موجود أصلًا في ملف HTML. ويجمّع هذا الصنف المحتوى في مركز الحاوية التي تأخذ اتساع أعظمي مقداره 960 بكسل. بإمكانك أن ترى كيف لن يتجاوز اتساع الصناديق 960 بكسل. إن ألقيت نظرة على الملف skeleton.css سترى التنسيقات التي تُطبّق عند استخدام ذلك الصنف. إذ سترى كيف يتوضع المحتوى في مركز الحاوية باستخدام هوامش يمينية ويسارية بقيمة auto، كما تُطبّق حشوات يسارية ويمينية مقدارها 20 بكسل.وتُضبط أيضًا قيمة الخاصية box-sizing على border-box كما فعلنا سابقًا كي يجري تضمين اتساع الحشوات والإطار ضمن اتساع الحاوية الكلي. .container { position: relative; width: 100%; max-width: 960px; margin: 0 auto; padding: 0 20px; box-sizing: border-box; } يكون العنصر جزءًا من الشبكة إن كان ضمن سطر row، لهذا سنحتاج -كما هو الحال في مثالنا السابق- إلى عنصر <div> آخر يمتلك الصنف ويأتي بين العنصر <div> الخاص بالمحتوى والعنصر <div> الخاص بالحاوية. لنرتب الآن الصناديق ضمن الحاوية، فالإطار Skeleton مكوّن من شبكة ذات 12 عمودًا. وتحتاج صناديق السطر الأول إلى أصناف one column كي تجعلها تمتد على عمود واحد. أضف الشيفرة التالية: <div class="container"> <div class="row"> <div class="one column">1</div> <div class="one column">2</div> <div class="one column">3</div> /* and so on */ </div> </div> اعط الآن حاويات السطر الثاني أصنافًا تشرح عدد الأعمدة التي ستمتد عليها هذه الحاويات كالتالي: <div class="row"> <div class="one column">13</div> <div class="six columns">14</div> <div class="three columns">15</div> <div class="two columns">16</div> </div> احفظ التغييرات على ملف HTML وحمّل الصفحة من جديد في المتصفح لترى ما يحدث! ملاحظة: إن واجهت مشكلة في تشغيل هذا المثال، حاول أن توسّع نافذة العرض التي تستخدمها فلن تُعرض الشبكة كما وصفنا إن كانت نافذة العرض ضيّقة. لم ينفع الأمر، حاول أن توازن ما فعلت بالملف html-skeleton-finished.html (أو اطّلع على طريقة تنفيذه مباشرة). إن ألقيت نظرة على الملف skeleton.css بإمكانك معرفة كيف يعمل المثال. فالملف يتضمن الأصناف "three columns" التالية لتنسيق العناصر بثلاثة أعمدة: .three.columns { width: 22%; } إن إطار العمل Skeleton وغيره من إطارات عمل الشبكات يُعرّف مسبقًا أصناقًا يمكنك استخدامها في صفحاتك. وتعمل كما لو أجريت الحسابات بالنسبة المئوية بنفسك. وكما ترى، لن تحتاج إلى كتابة الكثير من التنسيقات باستخدام Skeleton، فهي تتعامل مع العناصر المعوّمة نيابة عنا بمجرد إضافة أصناف التنسيق الملائمة إلى شيفرة HTML. إن هذه القدرة على التحكم بالتخطيط هو ما يجعل إطارات العمل لبناء شبكات خيارًا جذّابًا. لكن، ومع ظهور تخطيط شبكة CSS، يبتعد المطوّرون عن استخدام أطر العمل لاستخدام تلك التقنية المدمجة التي تقدمها CSS بشكل أصيل. الخلاصة تعرّفنا في هذا المقال كيف تعمل مختلف منظومات الشبكات، وهذا أمر مهم عند العمل مع مواقع قديمة، ولفهم الفرق بين شبكة CSS الأصيلة وهذه الأنظمة الأقدم للشبكات. ترجمة -وبتصرف- للمقال: Legacy layout methods اقرأ أيضًا المقال السابق: دليلك إلى استعلامات الوسائط Media Queries في CSS التحكم في تخطيط الصفحة وضبط محاذاة العناصر في CSS مدخل إلى تخطيط صفحات الويب باستخدام CSS التخطيط متعدد الأعمدة باستخدام CSS
  24. معرض أعمالك أنصحك بتحديثه باستمرار، لأن معرض الأعمال الجيد هو مؤشر مهم على تفاني المستقل في عمله، التحديث مهم لأن مهارات الفرد تتغير وتتطور بشكل مستمر، ولا تدري أي الفرص التي ستأتي إليك في المستقبل، لهذا لا يجب أن تغفل عن تحديثه بأحدث المهارات والمشاريع التي أنجزتها وتحذف أو تخفي تلك المشاريع التي عملتها وأنت مبتدئ وفي أيامك الأولى.
  25. صراحة أنصحك بأن تبدأ بمستقل أو ربما خمسات في البداية، لأن الحصول على عملاء عليهما أسهل بكثير من Upwork (أتحدث عن تجربة شخصية، قد يخالفني البعض الرأي) وهذا بسبب أن المنافسة في السوق العربي أكثر رحمة منها في السوق العالمي، فعلى الرغم من أن الأعمال على Upwork أكثر، لكن فرصة أن ينظر إليك صاحب المشروع (فضلا عن أن يتكلم معك!) ضعيفة بسبب كثرة المتقدّمين. من الطبيعي أن تكون معظم المشاريع في غير تخصصك، لكن مع الوقت سوف تجد مشاريعا في تخصصك ويمكنك إرسال عروضك إليها. هذا الأمر لن يتم بين ليلة وضحاها بالطبع. سوف تحتاج إلى المحاولة عدّة أسابيع قبل أن يقبلك أحد أصحاب المشاريع. في البداية لا تتوجه نحو المشاريع الكبيرة والمرتفعة الثمن، بل نحو المشاريع البسيطة قدر الإمكان، حتى تزيد فرصة قبولك وحتى لا تتسبب بمشاكل كبيرة مع صاحب المشروع بسبب نقص خبرتك في البداية. عند إرسال عرضك، تجنّب مدح نفسك بل اعرض ما قمت بعمله سابقا مما يشبه ما يطلبه صاحب المشروع، أو على الأقل إشرح لصاحب المشروع ما فهمته من طلبه واعرض له خطتك بشكل مختصر لكيفية العمل على مشروعه. هذا سيزيد فرصة قبولك كثيرا.
  26. مدى عن البرتفيليو الخاص بي ؟
  27. Freelancer Plus يعتمد أكثر على احتياجاتك وميزانيتك، فمن مميزاتها أنها تزيد في فرص الحصول على المشاريع و تساعدك عبر توفير أدوات و تطبيقات ذكية لتحسين كفاءتك في الموقع، وكمبتدئ لا أنصحك به حاليا. كنصيحة قم بالتركيز على بناء محفظة أعمال قوية والتي من خلالها يمكنك جذب عملاء، ثم لا تتردد في التقدم لعدد كبير من المشاريع حتى يرى العملاء محفظتك و عملك السابق، يمكنك البدء على مستقل وخمسات لأنهما أسهل ومناسبين للمبتدئين في هذا المجال. و بالتأكيد لا يجب أن تنسى أن تتفاعل مع العملاء بشكل جيد و منظم مع احترام الاوقات و المواعيد كي تكسب العملاء وتستمرّ في تقديم خدماتك لهم.
  1. عرض المزيد
×
×
  • أضف...