البحث في الموقع
المحتوى عن 'خصائص'.
-
تعلّمنا في الدرسين السابقين كيفية إنشاء ونشر موقعنا الأوّل. في الحقيقة موقعنا حاليًّا بسيط وذو محتوى قليل وليس جذّابًا بعد. سنتعلّم في هذ الدرس كيف نستخدم تنسيقات CSS لتنسيق الصفحة. كما سنتعلّم في درس لاحق كيف نضيف المزيد من التنسيقات إلى موقعنا وذلك بمساعدة إطار عمل اسمه Bootstrap. البنية والتنسيق Structure and Style لنتذكّر معًا: يُعبّر HTML عن بنية صفحة الويب، في حين تُعرّف CSS المظهر العامّ للصفحة. يُعتبر فصل بنية الصفحة عن تنسيقها أمر في غاية الأهميّة وله الكثير من المزايا رغم أنّه ليس إلزاميًّا. لذلك سنعمل دومًا على جعل رُماز HTML وتنسيقات CSS في ملفات منفصلة. الربط مع ملف CSS ملف CSS هو ملف نص عادي له الامتداد (css.) ونربط معه من داخل ملف HTML. أنشئ ملف جديد ضمن المجلّد Portfolio وسمّه main.css. افتح الملف index.html واضف العنصر <link> ضمن العنصر <head>. سنخبر الصفحة index.html عن طريق العنصر <link> أن تُحمّل ملف CSS، أي سننشئ رابط بينهما: <link rel="stylesheet" href="main.css"> أضف العنصر السابق إلى العنصر <head>. ستبدو الشيفرة لديك مُشابهة لما يلي: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <link rel="stylesheet" href="main.css"> <title>Web Portfolio of Marco</title> </head> <body> <h1>Web Portfolio of Marco</h1> <h2>Welcome!</h2> <p>Thanks for stopping by.</p> <p>Please have a look around. In the blog section I document my experiences in programming. You may also look at my web projects. Have fun.</p> <img src="marco.jpg" alt="Picture of me"> <p>Marco :-)</p> </body> </html> ملاحظة مهمّة: لكي يكون من الممكن الوصول لملف CSS، يجب أن تحتوي السمة href على المسار الصحيح للملف. وهذا يعني بدوره أنّه إذا كان ملف CSS في مجلّد فرعي، يحب أن نضم هذا المجلّد الفرعي إلى مسار الملف كما هو واضح. يمكنك مراجعة هذا الموضوع في الدرس الأوّل في فقرة عناوين URL النسبيّة والمطلقة. الألوان إلى الآن ما يزال ملف CSS فارغًا، لنبدأ الآن بكتابة أولى تنسيقات CSS. تحوي CSS ما يُعرف بالقواعد CSS Rules. يمكننا باستخدام قاعدة CSS أن نُخبر المتصفّح كيف يُعالج جزءًا مُحدّدًا من مستند HTML. كمثال على ذلك، سنغيّر لون الخلفيّة ولون النص للعنوان من المستوى الثاني h2 ضمن الملف index.html الخاص بنا. أضف ما يلي إلى ملف CSS: الملف main.css h2 { background-color: #607d8b; color: #ffffff; } يجب أن تحصل على شكل شبيه بما يلي: أكواد الألوان Color Codes تظهر الألوان على الشاشة كمزيج من نسب متفاوتة من الأحمر والأخضر والأزرق (RGB). يمكن التعبير عن المزج بين هذه الألوان الثلاثة في CSS بطريقتين: كقيم RGB عشرية (محصورة بين 0 إلى 255 لكل لون) أو كقيم RGB ستة عشرية hex values. وفي الواقع تُستَخدم القيم الستة عشرية في الغالب. إذا نظرنا إلى مثالنا الأخير، فنجد أنّنا قد عيّنا لونًا أزرقًا مائلًا للرمادي كلون خلفية باستخدام كود اللون 607d8b# بالترميز الستة عشري. أمّا لو أردنا استخدام الترميز العشري المُكافئ له فسنكتب (rgb(96, 125, 139. في التمثيل الستة عشري، يُعبّر أوّل رمزين من اليسار عن اللون الأحمر، والرمزين في الوسط عن اللون الأخضر، ويُعبّر الرمزان الأخيران عن اللون الأزرق. العمل مع أكواد الألوان يُعتبر التعامل مع الألوان كأكواد، شائع جدًا لكنه صعب في الحقيقة. لأنّك تتعامل مع قيم ورموز وليس مع ألوان، يُنصح دوماً استخدام أداة لانتقاء الألوان color picker. إذا كنت تستخدم المحرّر Brackets عندها يمكن أن تفتح أداة انتقاء اللون الموجودة ضمن ملف CSS الذي تعمل ضمنه. فقط تحتاج لأن تنقر بزر الفأرة الأيمن على كود اللون وتختار تحرير سريع Quick Edit أو أن تضغط Ctrl+E من لوحة المفاتيح. يؤدي ذلك إلى ظهور أداة اختيار الألوان حيث يمكنك اختيار اللون الذي يناسبك بسهولة. كما يمكنك اختيار ترميز اللون بالصيغة التي ترغبها من خلال ثلاثة أزرار موجودة في الأسفل. أدوات اختيار الألوان من الانترنت إذا لم تتوفّر أداة لاختيار الألوان ضمن المحرّر لديك، فيمكنك استخدام عدد كبير جدًّا من هذه الأدوات ولكن على الانترنت، فعلى سبيل المثال لا الحصر: HTML Color Codes ColorPicker ألواح الألوان من الانترنت نحتاج في كثير من الأحيان إلى أكثر من لون واحد لاستخدامه في موقعنا. لذلك نحتاج إلى أداة تزوّدنا بمجموعة من الألوان المنسجمة، والتي تتناغم مع بعضها لإضفاء تأثير جميل على الموقع. وهذا ما تفعله ألواح الألوان color palettes. هناك بعض المواقع على الانترنت التي توفّر مثل هذه الميزة. أمثلة على مواقع بمجموعات ألوان معرّفة مسبقًا: Colour Lovers Design Seeds Google Color Palette أمثلة على مواقع تولّد مجموعات ألوان حسب رغبة المستخدم: Kuler: يُعرّف قاعدة لون (سنتكلّم عن القواعد بعد قليل)، ويسمح لنا بالحصول على خمسة ألوان منسجمة معًا. Paletton: أداة متقدّمة للحصول على مجموعات ألوان منسجمة. Colourco.de: مولّد ألواح ألوان عملي أيضًا. قواعد CSS رأينا كيف تُغيّر CSS من هيئة عناصر HTML من خلال تأثيرها على الألوان. لنلقي نظرة عن كثب حول CSS وطريقة عملها. تُعتبر القاعدة rule البنية الأساسية لـ CSS وهي تتكوّن من ثلاثة عناصر: المحدِّد Selector والخاصية Property والقيمة Value. تُشير القاعدة السابقة إلى أنّ جميع عناصر <h2> يجب أن يكون لها لون خلفية له الكود 607d8b#. محددات CSS تُقرّر المحدّدات أيّ عناصر HTML ستُطبّق عليها قاعدة CSS. ملاحظة: سنتعلّم هنا المحدّدات الأكثر أهمية. من أجل الاطلاع على أنواع المُحدّدات الأخرى ابحث في Google عن CSS Selectors. محددات النوع Type Selectors تستهدف محدّدات النوع جميع العناصر التي يكون لها وسم HTML مُحدّد. فلو أردنا مثلًا استهداف جميع عناصر الفقرة p ضمن المستند بتنسيقات معيّنة، فسنكتب شبيه بما يلي: CSS p { ... } HTML <p>...</p> <p>...</p> محددات الصنف Class Selectors تُستخدم هذه المحدّدات بشكل متكرّر، وتُعتبر أنّها مُخصّصة أكثر قليلًا من مُحدّدات النوع، كما أنّه بإمكانها استهداف مجموعة مخصّصة من العناصر بدلًا من عناصر النوع الواحد فقط. لاستخدام محدّدات الصنف نضيف السمة class إلى العنصر المراد استهدافه، ونسند إليها قيمة مُعبّرة من اختيارنا. عند استخدام محدّد الصنف فإنّنا نستخدم نقطة عادية يليها قيمة السمة class التي أضفناها إلى العنصر. سيستهدف محدّد الصنف في المثال التالي، جميع العناصر التي لها سمة class تحمل القيمة highlight: CSS .highlight { ... } HTML <p class="highlight">...</p> <p>...</p> <p class="highlight new">...</p> لاحظ من شيفرة HTML في الأعلى، أنّ التنسيق سيُطبّق على عنصر p الأوّل والثالث فحسب، لأنّ عنصر p الثاني لا يمتلك سمة class لها القيمة highlight. كما نلاحظ أنّ عنصر p الثالث له أكثر من قيمة ضمن سمة class الخاصة به (highlight وnew). في الحقيقة يمكن استخدام عدة قيم لعنصر واحد بشرط أن نفصل بينها بفراغات. محددات معرف العنصر ID Selectors تشبه هذه المحدّدات محدّدات الصنف. فهي تستهدف جميع عناصر HTML التي تملك السمة id بقيمة مُعيّنة. من المهم أن نوضّح أنّ السمة id عبارة عن مُعرّف العنصر ضمن شيفرة HTML ورغم أنّه ليس من الملزم وضعها مع كل عنصر، إلّا أنّه في حال وجودها يجب أن تكون القيمة التي تحملها فريدةً ضمن كامل مستند HTML. نستنتج إذًا أنّ أي محدّد معرّف عنصر سيستهدف في الواقع عنصر واحد فقط ضمن مستند HTML. عند استخدام محدّد معرّف العنصر فإننا نكتب الرمز # يليه معرّف العنصر (قيمة السمة id). سيستهدف محدّد معرّف العنصر في المثال التالي عنصر واحد فقط ضمن مستند HTML بحيث تكون قيمة السمة id له هي navigation: CSS #navigation { ... } HTML <p id="navigation">...</p> <p>...</p> محددات الفروع Descendant Selectors يمكنك باستخدام هذا النوع من المحدّدات استهداف العناصر الأبناء لعنصر مُعيّن. ونقصد بالعناصر الأبناء لعنصر معيّن، تلك العناصر التي تقع ضمن هذا العنصر بصرف النظر عن المستوى الذي تقع فيه. انظر المثال التالي: <p id="level1"> <p id="level2"> <a href="myfile.html">My File</a> </p> </p> نلاحظ بأنّ كلًّا من العنصر <p> (ذو المعرّف level2) والعنصر <a> هما ابنان للعنصر <p> (ذو المعرّف level1). لأنّهما يقعان ضمنه بصرف النظر عن المستوى. في حين يُعتبر العنصر (ذو المعرّف level2) ابنًا مباشرًا للعنصر <p> (ذو المعرّف level1). أمّا بالنسبة لمحدّدات الفروع فنلق نظرة خاطفة على هذ المثال البسيط قبل أن نبدأ بالشرح: CSS p a { ... } HTML <p> <a href="http://code.makery.ch">My Website</a> </p> <a href="http://www.example.com">Example Website</a> نلاحظ بأنّ محدّد الفروع p a يستهدف جميع عناصر <a> أينما وُجدَت داخل عنصر <p>. وبناءً عليه نجد أنّ التنسيق سيُطبّق على My Website وليس على Example Website لأنّ الأخيرة موجودة ضمن عنصر <a> لا يقع ضمن أي عنصر <p> كما هو واضح. ملاحظة: ليس من الضروري أن يكون العنصر <a> في المثال في الأعلى ابنًا مباشرًا للعنصر<p>. فمحدّد الفروع السابق يستهدف أي عنصر <a> موجود ضمن أي مستوى ضمن العنصر <p>. إذا أردنا استهداف الابن المباشر فحسب، فيمكننا استخدام مُحدّد الابن ( > ). خصائص CSS تُقرّر قواعد CSS كيف يجب أن تظهر عناصر HTML. هناك العديد من الخصائص التي يمكن تعريفها في CSS. في الواقع لقد صادفنا اثنتان منهم: background-color وcolor. لن نتوسّع في الحديث عن خصائص CSS المختلفة، لأنّ هذا الدرس ليس مرجعًا لهذه الخصائص، لكن سنتعلّم كيف نجد المزيد من المعلومات عنها بأنفسنا. سنستفيد بشكل أكبر عندما نتعلّم هذه الخصائص عندما نحتاج إليهم فعليّا. توجد حالتان مختلفتان يمكن أن نصادفهما لنتعلُّم المزيد عن CSS. الحالة الأولى: عندما نصادف خاصية CSS لا نعرفها في هذه الحالة نبحث عن معلومات عنها في الانترنت، اكتب اسم الخاصية متبوعًا بكلمة css ضمن محرّك البحث. يمكنك أن تجرّب هذه الطريقة الآن لتحصل على معلومات حول خاصية CSS جديدة وهي: padding: 5px; استخدم css padding كعبارة بحث. لا تكتفي بالاطلاع على نتيجة البحث الأولى، بل اطّلع على النتائج الخمس الأولى أو أكثر إن أحببت. بعد ذلك قرّر أيُّ المواقع ستوفّر المعلومات المناسبة لك. جرّب تطبيق قاعدة CSS السابقة (أي القاعدة padding: 5px) على عنصر h2 في مشروعنا. الحالة الثانية: نريد تغيير أسلوب عرض أحد العناصر ولكن لا نعرف خاصية CSS المناسبة ابحث في الانترنت عن الشيء الذي ترغب أن تقوم به، متبوعًا بكلمة css. ربما تحتاج إلى إجراء عدة عمليات بحث قبل أن تجد ضالّتك. فإذا أردنا مثلًا تغيير حجم النص. في هذه الحالة استخدم الكلمات التالية text size css في محرّك البحث. ومرّة أخرى لا تكتفي بالنتيجة الأولى فقط من نتائج البحث. قيم CSS لقد صادفنا قبل قليل بعضًا من قيم CSS، فمثلًا القيم الست عشرية مثل ffffff# أو تلك القيم المتعلّقة بتعيين قياسات الأحجام مثل 5px. يتوجّب علينا أحيانًا وبحسب خاصية CSS المستخدمة استخدام كلمات مُعيّنة مثل left أو right لمحاذاة النصوص على سبيل المثال. أكثر قيم CSS المستخدمة هي القيم المتعلّقة بتعيين قياسات الأحجام. لذلك سنتناولها بشيء من التفصيل. غالبًا ما يُعرّف الحجم باستخدام البيكسل Pixel، ونرمز له اختصارًا بالرمز px. p { font-size: 16px; } توجد إمكانية أخرى وهي تعيين الأحجام باستخدام النسبة المئوية Percentage. دائمًا ما تكون النسب المئوية نسبيّةً بالنسبة للعنصر الأب. في المثال التالي سيشغل العنصر p ما مقداره 60% من عرض width العنصر الأب الذي يقع ضمنه، في حين سيشغل العنصر الأب عرض النافذة كاملًا. p { width: 60%; } توجد وحدة قياس مشهورة أخرى للأحجام وهي em. والـ em ترتبط دومًا بحجم الخط. ويعني ذلك أنّنا إذا غيّرنا حجم الخط فإنّ حجم العنصر المُقاس بالوحدة em سيتغيّر أيضًا. كمثال على ذلك إذا كان لعنصر ما حجم خط مقداره 20px وعرض 5em، فسيكون عرض العنصر الفعلي في هذه الحالة 100px (أي 20 مضروبة بـ 5). انظر إلى الشيفرة التالية: p { font-size: 20px; width: 5em; } محددات الصنف في مشروعنا إذا أردنا تكبير العنوان الرئيسي في موقعنا: "Web Portfolio of Marco". فسيكون ذلك ممكنًا بتعريف قاعدة CSS للعنصر h1 كما يلي: h1 { font-size: 65px; } المشكلة التي ستصادفنا هنا أنّ جميع عناصر h1 الموجودة في المستند ستكبُر بتأثير هذه القاعدة. لذلك فإذا أردنا أن نُكبّر عنوان h1 الأوّل الموجود في المستند فسنستخدم لهذا الغرض مُحدّد صنف class selector. سنضيف السمة class إلى عنصر h1 المراد استهدافه، ويمكننا بالطبع إسناد أي قيمة لهذه السمة، سنختار القيمة title: <h1 class="title">Web Portfolio of Marco</h1> يمكننا الآن استهداف عنصر h1 هذا بكتابة قاعدة CSS بالشكل التالي: .title { font-size: 65px; } إذا جرت الأمور على ما يرام فستحصل على شكل شبيه بما يلي: سننتقل الآن إلى الدرس الرابع، والذي يتحدّث عن أدوات التطوير البرمجية المتاحة ضمن متصفّح الانترنت. ترجمة -وبتصرّف- للمقال HTML & CSS Tutorial - Part 3: Introduction to CSS لصاحبه Marco Jakob.
-
كُنّا في درس سابق قد تحدثنا عن كيفية تخطيط صفحات الويب باستعمال CSS2 وكيف أنّ ذلك لم يكن بالأمر السهل، لذلك في هذا الدرس سوف نقوم بنفس التخطيط ولكن باستعمال تقنيات CSS3 الجديدة. تٌقدّم لنا CSS3 مجموعة من التقنيات والتحسينات لتساعدنا على تخطيط صفحات الويب بشكل أفضل وأسهل ودون الحاجة إلى الكثير من الأكواد كما كان الحال في CSS2. كما أنها مُصممة لتدعم السلوكات المتغيرة/الديناميكية وبالتالي يمكننا القول بأنها " لغة قابلة للبرمجة". دعونا إذًا نرى بعض الخصائص والتقنيات الجديدة التي توفرها هذه اللغة ونحاول استخدامها لدعم حالة الاستخدام التي كنّا قد بدأنا بها في الدرس السابق. دالة ()calc الخاصة بلغة CSS3تُستخدم دالة ()calc الجديدة لحساب القيم بشكل ديناميكي (ضع في الحسبان أن دعم هذه الدالة يختلف من متصفح لآخر). وفي داخل هذه الدالة يمكنك كتابة أي معادلة/تعبير (expression) باستخدام المعاملات الحسابية المعروفة (+، -، *، /). سوف يساعدنا استخدام هذه الدالة على التخلص من الكثير من الأكواد التي كان لا بد منها في CSS2، وفي حالتنا هذه فإنها سوف تساعدنا في تمدد العناصر بشكل أفضل (سوف يصبح استخدام تقنية CSS Expansion التي ذكرناها سابقًا أكثر سهولة). أنظر للكود الموجود في الأسفل: #nav, #subnan { position: fixed; height: calc(100% - 10em); /* replaces */ z-index: 20; }لاحظ أننا استخدمنا الدالة ()calc في الخاصية height وهذا سوف يساعدنا بالحصول على نفس النتيجة التي حصلنا عليها باستخدام CSS2 عندما استخدمنا الخاصيتين top: 6em و bottom: 4em، وبهذا يمكن للأمور أن تصبح أكثر مرونة وسوف نحتاج إلى خاصية واحدة (height مع ()calc) بدل اثنتين (top وbottom). استخدام CSS3 Flexbox في تخطيط الصفحاتتُعتبر Flexbox من الخصائص والتقنيات الجديدة التي ظهرت في CSS3 وهي تجعل من تخطيط الصفحات وترتيب عناصرها أمرًا سهلًا ومتشابهًا في مختلف أحجام الشاشات والأجهزة، وبالتالي فهي مفيدة جدًا عند القيام بتصميم مواقع متجاوبة. وهذه بعض الخصائص والميزات التي تتمع بها Flexbox: تمكننا من موضعة العناصر الأبناء (child elements) بشكل أسهل ويصبح تخطيط الصفحات المعقدة أبسط وأسهل ودون الحاجة إلى الكثير من الأكواد فيصبح لدينا كود أنظف وقابل للقراءة بشكل أفضل.يمكن وضع العناصر الأبناء بأي إتجاه نريده وتصبح أبعاد تلك العناصر مرنة أكثر بحيث يمكنها التجاوب مع مساحة العرض.تستطيع العناصر الأبناء أن تتمدد وتتقلص تلقائيًا لتشغل المساحة الفارغة.كما أنّ Flexbox يقدم مجموعة خاصة به من المفاهيم والمصطلحات، ونذكر بعض منها: Flex container: العنصر الذي يحتوي على الخاصية display بالقيمة flex أو inline-flex بحيث يصبح هذا العنصر هو العنصر الحاوي (الأب) للعناصر التي نريد التعامل معها.Flex item: هو أي عنصر موجود في الـFlex container. (ملاحظة: أي نص موجود بشكل مباشر داخل الـFlex container سيتم احتواؤه داخل anonymous flex item).Axes: أي flexbox يجب أن يحتوي على الخاصية flex-direction بحيث تُحدد هذه الخاصية المحور الرئيسي (main axis) الذي سوف تتموضع حوله الـflex items. ويوجد أيضًا المحور العرضي (cross axis) ويكون هذا المحور عموديًا على المحور الرئيسي.Lines: يمكن للـflex items أن تصطف/تتموضع في خط واحد أو خطوط متعددة وذلك ما تحدده الخاصية flex-wrap.Dimensions: يحتوي flexbox على main size و cross size كبديل عن height وwidth بحيث تُحدد هاتين القيمتين حجم المحور الرئيسي (main axis) والعرضي (cross axis) على التوالي.بعد هذه المقدمة القصيرة عن flexbox يمكننا الآن استخدامها في تخطيط الصفحات. <body class="layout-flexbox"> <header id="header"></header> <div class="content-area"> <nav id="nav"></nav> <aside id="subnav"></aside> <main id="main"></main> </div> <footer id="footer"></footer> </body>نريد في حالة الاستخدام التي نعمل عليها أن تكون العناصر الرئيسية (header ،content ،footer) مصفوفة بشكل عمودي، وبالتالي سوف نستخدم القيمة column في الخاصية flex-direction كما يلي: .layout-flexbox { display: flex; flex-direction: column; }ومع أنّ العناصر الرئيسية يجب أن تكون مصفوفة بشكل عمودي إلّا أنّ العناصر في منطقة المحتوى (nav ،subnav ،main) نريدها مصفوفة بشكل أفقي. وبما أنّ كل flex container يمكن أن يحتوي على خاصية flex-direction واحدة فقط فإننا سنقوم بتعريف العديد من flex containers داخل بعضها البعض حتى يمكننا التحكم في تخطيط الصفحة كما نشاء (أي حتى يصبح بإمكاننا أن نجعل العناصر تصطف كما نريد وألّا نصبح مقيدين باتجاه واحد فقط). ولهذا السبب قمنا بإضافة حاوي (container) آخر (<div class="content-area">) ليحتوي على عناصر nav ،#subnav# و main#. وبهذا يمكن للعناصر الرئيسية أن تصطف بشكل عمودي بينما تصطف عناصر منطقة المحتوى بشكل أفقي. نريد الآن أن نقوم بموضعة الـflex items لذلك سوف نستخدم الخاصية flex وهي اختصار(shorthand) للخصائص flex-grow ،flex-shrink وflex-basis. وهذه الخصائص تُحدد كيف تقوم الـflex items بتوزيع المساحة الفارغة المتبقية بينها، وهذا تعريف بسيط بهذه الخصائص: flex-grow: تُحدد كم يمكن للعنصر (flex item) أن ينمو/يتمدد نسبة للعناصر الأخرى في نفس الحاوي.flex-shrink: تُحدد كم يمكن للعنصر (flex item) أن يتقلص نسبة للعناصر الأخرى في نفس الحاوي.flex-basis: يُحدد الحجم الافتراضي للعنصر (أي حجمه قبل أن ينمو أو يتقلص). عندما نقوم بإعطاء الخاصيتين flex-grow وflex-shrink القيمة "صفر" فإننا نقوم بمنع العنصر من أن يتقلص أو ينمو حتى لو كان هناك مساحة فارغة (أي أنّ حجم العنصر يبقى ثابتًا). وهذا ما سوف نقوم به للترويسة (header) والتذييل (footer) لأننا نريد أن يبقى حجمهما ثابتًا: #header { flex: 0 0 5em; } #footer { flex: 0 0 3em; }وإذا أردنا لعنصر أن يستغل أي مساحة ثابتة فإننا نعطي الخاصيتين flex-grow وflex-shrink القيمة "1" ونعطي الخاصية flex-basis القيمة auto. وهذا ما نريده بالنسبة لمنطقة المحتوى (نريدها أن تستغل أي مساحة فارغة). وكما ذكرنا سابقًا فإننا نريد للعناصر الموجودة داخل <div class="content-area"> أن تصطف بشكل أفقي، لذلك سوف نعطيها الخاصية display: flex حتى يصبح هذا العنصر عبارة عن flex container وسوف نعطيها أيضًا الخاصية flex-direction: row حتى نجعل العناصر الموجودة في داخله (nav ،#subnav# و main#) تصطف بشكل أفقي، وبالتالي نحصل على تنسيقات CSS التالية: .content-area { display: flex; flex-direction: row; flex: 1 1 auto; margin: 1em 0; min-height: 0; }في منطقة المحتوى نريد أن يكون حجم كلا العنصرين nav# وsubnav# ثابت وبالتالي سوف نعطيها الخاصية flex بقيم مناسبة: #nav { flex: 0 0 5em; margin-right: 1em; overflow-y: auto; } #subnav { flex: 0 0 13em; overflow-y: auto; margin-right: 1em; }لاحظ أنني استعملت الخاصية overflow-y: auto وذلك حتى نتعامل مع المحتوى إذا ما تجاوز ارتفاع الحاوي. متصفح Firefox هو من يحتاج لهذه الخاصية. سوف يأخذ العنصر main# المساحة الفارغة المتبقية: #main { flex: 1 1 auto; overflow-y: auto; }كل شيء يبدو جيدًا إلى الآن، لذلك دعونا نقوم بإضافة السلوك المتغير/الديناميكي ونرى ما يحصل. سوف تكون أكواد الجافاسكربت مشابهة لما استخدمناه سابقًا باستثناء أن اسم الـclass للعنصر الحاوي سيكون layout-flexbox بدلًا من layout-classic: $('.layout-flexbox #nav’).on('click', 'li.nav-toggle', function() { $('#nav').toggleClass('expanded'); });سوف نضيف "class expanded" إلى تنسيقات CSS كما يلي: #nav { flex: 0 0 5em; /* collapsed size */ margin-right: 1em; overflow-y: auto; &.expanded { flex: 0 0 10em; /* expanded size */ } }لاحظ أننا هذه المرة لم نحتج إلى أن ندع العناصر الأخرى تعلم بشأن تغير العرض وذلك لأنّ flexbox تعالج الأمر دون تدخل منا. الشيء الوحيد المتبقي هو إخفاء القائمة الفرعية، ولكن احزر ماذا؟ لن نحتاج لكتابة أي أكواد إضافية لأن flexbox سيعلم بشأن المساحة الفارغة وسوف يتكفل بجعل كل شيء يعمل كما هو مطلوب. يوفر لنا flexbox أيضًا مجموعة من الطرق التي تمكننا من توسيط العناصر في الاتجاهين العمودي والأفقي. يمكننا الآن معرفة أهمية وجود مثل هذه التقنية في لغة CSS وكيف أنّها تساعد على جعل الكود أفضل وله القابلية للتطور والتوسع. ولكن على الناحية الأخرى فإنّ هذه التقنيات تحتاج إلى وقت أكثر لإتقانها مقارنة بخصائص CSS الأخرى. تخطيط الصفحات باستخدام CSS3 Gridإذا كنت تعتقد أن flexbox شيء جديد فأنت حتمًا لم تسمع عن CSS3 Grid، فهي ما زالت في مرحلة مبكرة (مرحلة draft) ودعم المتصفحات لها شبه معدوم (يمكنك تفعيلها في متصفح Google Chrome عن طريق الدخول إلى chrome://flags واختيار "experimental Web Platform features"). وفائدتها هي أنها تعمل في طبقة العرض (presentation layer) وبالتالي لن نحتاج إلى معرفة كيفية ظهور العناصر في التوصيف (markup) الخاص بملفات HTML (أي أنّ كل شيء سيتم باستخدام CSS بعض النظر عن ترتيب العناصر في HTML). الفكرة العامة هي أن يكون هناك شبكة تخطيط (grid) مرنة ومُعرّفة بشكل مسبق يمكن أن نستخدمها لموضعة العناصر بداخلها. وكما هو الحال في flexbox فإنها تعمل على مفهوم المساحات الفارغة وتسمح لنا بتعريف إتجاهين (عمودي وأفقي) في نفس العنصر مما يؤدي إلى تقليل حجم الكود وزيادة مرونته. يُقدّم لنا Grid Layout نوعين من الـgrids وهما explicit وimplicit، ولجعل الأمور بسيطة سوف نركز على explicit فقط. وكما هو الحال مع flexbox فإنّ Grid يقدم مجموعة خاصة به من المفاهيم والمصطلحات، ونذكر بعض منها: Grid container: هو أي عنصر يملك الخاصية display بالقيمة "grid" أو "inline-grid" بحيث تتموضع العناصر داخله ويتم محاذاتها بناءً على grid مُعرّف مسبقًا (explicit mode). والـgrid هو عبارة عن مجموعة من الخطوط العمودية والأفقية المتقاطعة والتي تفصل الـGrid container إلى مجموعة من الخلايا (cells). وهناك مجموعتين من الخطوط؛ الأولى لتعريف الأعمدة (columns) والثانية تكون عمودية على هذه الأعمدة لتعريف الصفوف (rows).Grid track: هي المسافة بين خطّين متجاورين، وكل Grid track يتم إعطاؤه دالة تحجيم (sizing function) للتحكم بكيفية نمو كل عمود أو صف وبالتالي التحكم في البعد بين الخطوط المحيطة بكل خط.Grid cell: هي المسافة بين صفّين متجاورين وعمودين متجاورين من خطوط الـgrid، وهو أصغر وحدة من الـgrid يمكن الرجوع والاستناد إليها عندما نقوم بموضعة عناصر الـgrid.Flexible length: هو بُعد يتم تحديده بوحدة fr وهو يُمثّل جزء من المساحة الفارغة في الـGrid container. إليك عناصر HTML التي سوف نستخدمها: <body class="layout-grid"> <header id="header"></header> <nav id="nav"></nav> <aside id="subnav"></aside> <main id="main"></main> <footer id="footer"></footer> </body>لاحظ بأننا في تخطيط الصفحة هذا لن نحتاج إلى عنصر إضافي يعمل كحاوٍ لمنطقة المحتوى كما كان الحال مع flexbox، وذلك لأنّ هذا النوع من تخطيط الصفحات (Grid layout) يسمح لنا بتعريف مساحة كل عنصر في كلا الإتجاهين وبنفس الـGrid container. لنبدأ الآن بإضافة تنسيقات CSS: .layout-grid { display: grid; grid-template-columns: auto 0 auto 1em 1fr; grid-template-rows: 5em 1em 1fr 1em 3em; }قمنا باستخدام الخاصية display: grid على الحاوي (Grid container)، وكذلك استخدمنا الخاصيتين grid-template-columns وgrid-template-rows وهما تمثلان المساحة بين الـGrid tracks. بمعنى آخر، فإنّ هاتين القيمتين لا تمثلان مكان تواجد خطوط الـgrid وإنّما تمثلان مقدار المساحة بين الـGrid tracks. ضع في الحسبان أنّ وحدات القياس يمكن أن تكون أي واحدة من التالية: وحدة طول (length).نسبة مئوية معينة من حجم الحاوي (Grid container).مساحة من المحتوى الذي يحتله العمود أو الصف.جزء من المساحة الفارغة في الـgrid.فعلى سبيل المثال، في الخاصية grid-template-column: auto 0 auto 1em 1fr سيكون لدينا التالي: track واحد لتعريف عمودين بعرض auto (مساحة القائمة الرئيسية nav#).gutter واحد بقيمة "صفر" (الـmargin الخاص بالعنصر subnav# موجود في مستوى العنصر، ويمكن أن يكون موجودًا أو لا وبهذه الطريقة نضمن أن لا يكون هناك gutter مزدوج).track واحد لتعريف عمودين بعرض auto (مساحة القائمة الفرعية subnav#).gutter واحد بقيمة 1em.track واحد بقيمة 1fr للعنصر main# (سوف يأخذ المساحة المتبقية).لاحظ أننا استخدمنا القيمة auto في الـtrack، وهذا يسمح لنا بالحصول على أعمدة ديناميكية بحيث يتم تعريف مكان وحجم خطوط الـgrid بناءً على المحتوى الخاص بها. (سوف نحتاج أيضًا إلى تعريف حجم العنصرين nav# وsubnav# وهذا ما سنفعله بعد قليل). وبطريقة مشابهة، سوف تملك الصفوف الخاصية grid-template-row: 5em 1em 1fr 1em 3em مما يجعل العنصرين header# و footer# ثابتين ويؤدي أيضًا إلى أنّ العناصر الموجودة بين هذين العنصرين سوف تستخدم المساحة الفارغة المتبقية في حين تكون قيمة الـgutters بقيمة 1em. لنرى الآن كيف سنقوم بموضعة العناصر داخل الـgrid الذي قمنا بتعريفه: #header { grid-column: 1 / 6; grid-row: 1 / 2; } #footer { grid-column: 1 / 6; grid-row: 5 / 6; } #main { grid-column: 5 / 6; grid-row: 3 / 4; overflow-y: auto; }إنّ تنسيقات CSS الخاصة بالعنصر header# تُخبرنا بأننا نريد أن تكون الترويسة موجودة بين الخطين 1 و6 (أي العرض كامل) بالنسبة للأعمدة وبين الخطين 1 و2 بالنسبة للصفوف. ونفس الشيء بالنسبة للعنصر footer# فنريده أن يكون موجودًا بين الخطين 1 و6 (أي العرض كامل) بالنسبة للأعمدة وبين الخطين 5 و6 بالنسبة للصفوف. أمّا بالنسبة لمنطقة المحتوى فقد تمّ إعطاؤها الخصائص المناسبة حتى تشغل المساحة التي يفترض بها أن تشغلها. لاحظ أنّ الخاصية grid-column هي اختصار (shorthand) للخاصيتين grid-column-start وgrid-column-end و أنّ الخاصية grid-row هي اختصار للخاصيتين grid-row-start وgrid-row-end. لنعد الآن إلى العنصرين nav# وsubnav#. بما أننا قمنا مسبقًا بوضع هذين العنصرين داخل الـtrack بقيم auto فسوف نحتاج إلى تحديد مساحتهما (نفس الشيء سيكون بالنسبة لـ"expanded" فسوف نقوم فقط بتغيير عرضها وسوف يتكفل Grid بالباقي). #nav { width: 5em; grid-column: 1 / 2; grid-row: 3 / 4; &.expanded { width: 10em; } } #subnav { grid-column: 3 / 4; grid-row: 3 / 4; width: 13em; margin-left: 1em; }يمكننا الآن أن نقوم بتغيير وضع القائمة الرئيسية nav# وإخفاء أو إظهار القائمة الفرعية subnav# وكل شيء سيعمل بشكل جيد وملائم. كما أنّ Grid Layout تسمح لنا باستعمال أسماء مستعارة لتسمية الخطوط حتى نستطيع أن نُغير في الـgrid كما نريد دون أن يؤدي ذلك إلى خلل في الأكواد لأنّها ستكون مربوطة باسم معين وليس بأحد خطوط الـgrid. خاتمةحتى باستخدام تقنيات CSS القديمة فإنّ هناك الكثير مما يستطيع مطورو الويب فعله واستغلاله. ومع ذلك فقد يكون ذلك مهمة ليست سهلة وتحتاج إلى الكثير من الأكواد والتي قد تكون مكررة في كثير من الأحيان. ولكن كما شاهدنا فإنّ CSS3 بدأت تقدم طرق وتقنيات أفضل لتخطيط صفحات الويب والتي بدورها تُسهّل العمل على مطوري الويب. لذلك أعتقد أنه يجب على أي مطور ويب أن يتقن ويتعلم هذه التقنيات حتى يُحسّن من تجربة المستخدم وحتى يقوم بكتابة كود أنظف وأفضل. وهذه المقالة قدمت جزءًا صغيرًا فقط مما يمكن فعله باستخدام تقنيات CSS3 وهناك الكثير مما يجب عليك تعلمه. ترجمة -وبتصرّف- للمقال CSS Layout Tutorial: From Classic Approaches to the Latest Techniques لصاحبه Laureano Martin Arcanio.
-
يُوفر ميكروسوفت وورد مجموعة متقدمة من الخصائص التي تسهّل عملك على المستندات الكبيرة وتساعدك في توفير الكثير من الوقت. سنشرح في هذا الدرس كيفية استخدام ثلاث من هذه الخصائص، وهي الإشارات المرجعية Bookmarks، التسميات التوضيحية Captions والإسناد الترافقي Cross-reference. الإشارات المرجعية Bookmarks تُستخدم الإشارات المرجعية لتحديد موقع نقطة، فقرة نصيّة، أو عنصر آخر في المستند. ومن ثُم تُستخدم الإشارة المرجعية التي تم إنشاؤها للوصول إلى ذلك الموقع دون الحاجة إلى التمرير عبر كامل المستند للعثور عليه. وهذه الخاصية مفيدة جدا في المستندات الكبيرة وتوفّر الكثير من الوقت عند استخدامها. مثلا، لدينا المستند الموضّح في الصورة أدناه، والذي يحتوي على 23 صفحة: في مثل هذه المستندات الكبيرة (أو أكبر)، وعندما نرغب مثلا في مراجعة فقرة معينة، سيكون من المضيعة للوقت التمرير عبر كل الصفحات للعثور على الفقرة. لكن باستخدام الإشارات المرجعية يمكننا الوصول إلى موقع الفقرة بسهولة جدا. يحتوي مستندنا الموضّح على العديد من الأقسام والأقسام الفرعية، وما نريده هنا هو إنشاء إشارة مرجعية عند كل من هذه الأقسام. نضع المؤشر عند بداية عنوان القسم الرئيسي الأول، نذهب إلى تبويب إدراج Insert ثم ننقر على إشارة مرجعية Bookmark ضمن مجموعة ارتباطات Links: نقوم بإدخال اسم للإشارة المرجعية، ويفضّل أن يكون اسما مختصرا ودلاليا، ثم ننقر على إضافة Add: لن نلاحظ أي تغيير في المستند بعد إضافة الإشارة المرجعية، وهذا طبيعي جدا. ننتقل إلى عنوان القسم (الرئيسي أو الفرعي) التالي، نضع المؤشر أمام العنوان ثم نقوم بإضافة إشارة مرجعية أخرى: نكرر هذه الخطوات على بقية الأقسام. ويجب أن نأخذ في الاعتبار أنّ اسم الإشارة المرجعية يجب أن يكون كلمة واحدة لا تفصلها مسافة. وإذا رغبنا في إدخال اسم يحتوي على كلمتين نستخدم الشارحة التحتية underscore (_) للفصل بينها كما موضّح في الصورة أدناه: يمكننا إضافة العدد الذي نريده من الإشارات المرجعية، علما أنّ إنشاءها لا يقتصر على العناوين فقط، وإنّما يمكن إنشاء إشارات مرجعية لأي كلمة، سطر، أو فقرة. يجب أن ننتبه فقط إلى موضع المؤشر قبل إضافة الإشارة المرجعية. بعد إضافة جميع الإشارات المرجعية، أصبح بإمكاننا الانتقال إلى مواقعها عند الحاجة. هناك عدة طرق للانتقال إلى الإشارات المرجعية. الطريقة الأولى هي بالنقر على عدد صفحات المستند في شريط الحالة لفتح جزء التصفّح: ثم النقر على السهم بجانب حقل البحث واختيار الذهاب إلى Go To: بعد فتح مربع الحوار Find & Replace نحدد إشارة مرجعية Bookmark من تبويب الذهاب إلى Go to، ثم نختار اسم الإشارة المرجعية التي نريد الانتقال إليها من القائمة المنسدلة، وننقر على Go to: الطريقة الثانية، وهي مختصرة جدا، بالضغط على مفتاحي CTRL+G، ليُفتح نفس مربع الحوار Find & Replace، ثم نتبع نفس الخطوات في الطريقة السابقة. والطريقة الأخرى هي بالذهاب إلى تبويب: إدراج Insert > إشارة مرجعية Bookmark من مربع الحوار Bookmark نحدد الإشارة المرجعية التي نريد الانتقال إليها ثم ننقر على Go To: التسميات التوضيحية Captions إذا احتوى المستند الذي تعمل عليه على العديد من الصور، الجداول، الأشكال، إلخ، يمكنك الاستفادة من خاصية التسميات التوضيحية. تتيح هذه الخاصية إضافة اسم توضيحي (رقم +عنوان) للعناصر المذكورة، ويتم تحديث أرقام هذه العناصر تلقائيا كلما قمت بتحديث المستند بإضافة عنصر جديد أو حذفه. بالطبع يمكنك إضافة تسميات توضيحية يدويا باستخدام مربعات النصوص Text Box، لكن استخدام أمر التسميات التوضيحية يمكن أن يوفّر وقتك ويجعلك تستفيد من خاصية الإحالة المرجعية Cross-reference والتي سنأتي إلى شرحها لاحقا في هذا الدرس. كما هو واضح في الصورة الأولى في هذا الدرس، يحتوي المستند الذي نعمل عليه على عدد من المخططات، الصور، والجداول. ولتسمية جميع هذه العناصر سنستخدم أمر التسمية التوضيحية. يجب أولا أن نحدد العنصر الذي نريد إضافة تسمية توضيحية إليه، ثم نذهب إلى تبويب: مراجع References > إدراج تسمية توضيحية Insert Caption في مربع الحوار Caption لدينا عدة خيارات لإنشاء التسمية التوضيحية: في الحقل Caption نقوم بإدخال التسمية التي نريد إدراجها للعنصر. من قائمة التسمية Labels نحدد نوع العنصر، سواء كان صورة، شكل، مخطط، إلخ. من قائمة الموضع Position نحدد موضع إدراج التسمية، فيما أذا كان في أعلى العنصر أو أسفله. نؤشر الخيار Exclude label from caption إذا كنا نرغب في إدراج رقم العنصر فقط بدون نوعه (أي (1) بدلا من صورة (1)). يمكننا تغيير تنسيق الأرقام بالنقر على زر Numbering. بعد تحديد جميع الخيارات المرغوبة ننقر على موافق OK وسيتم إدراج التسمية التوضيحية: يمكننا تخصيص التسمية التوضيحية بتغيير لون النص أو حجمه من تبويب الصفحة الرئيسية Home أو تغيير تعبئة الشكل، نمط النص، وغيرها من التنسيقات من تبويب تنسيق Format السياقي. نقوم بإضافة تسمية توضيحية للعنصر التالي في المستند. لكن هذا العنصر ليس بشكل (Figure) وإنّما صورة (Image): لا يوجد خيار "Image" ضمن قائمة التسمية Label لذلك سننقر على زر تسمية جديدة New Label لإضافتها: ثم نقوم بإضافة عنوان الصورة: توجد هذه الصورة في الصفحة 21 من المستند. لنفترض أننا قمنا بتحديث المستند وإضافة صورة في صفحة ما قبل الصفحة 21: عندما نقوم بإضافة تسمية توضيحية للصورة الجديدة، فإنّ البرنامج يقوم بترقيمها حسب تسلسلها في المستند، وليس حسب أسبقية إدراجها (لاحظ أنّ الصورة الجديدة ستأخذ الرقم 1 بدلا من 2): وسيتم تحديث ترقيم الصورة القديمة تلقائيا ليصبح رقمها 2: وهذا التحديث التلقائي يجنّبك إضاعة الوقت في الحفاظ على أرقام الصورة مرتبة ومتسلسلة، كما يقلل من إمكانية حدوث الأخطاء في الترقيم. الإحالة المرجعية (أو الإسناد الترافقي) Cross-reference تُستخدم الإحالة المرجعية (أو كما يُشار إليها في وورد "الإسناد الترافقي") لتوجيه القارئ مباشرة إلى عنصر ما في المستندات الطويلة. عند إنشاء إسناد ترافقي، يقوم وورد بإدراجها كارتباط تشعبي hyperlink بشكل افتراضي، يمكن النقر على هذا الارتباط للانتقال إلى العنصر المشار إليه. يمكن إنشاء إسناد ترافقي لعدد من العناصر، كالفقرات المرقمة، التسميات التوضيحية، الإشارات المرجعية، الحواشي السفلية footnotes، والعناوين Headings. مثلا، نريد أن نوجه القارئ عند الانتهاء من قراءة الفقرة أدناه إلى الشكل الذي يوضّح ما تتحدث عنه الفقرة: سنقوم بوضع العبارة "Refer to" داخل قوسين، نضع المؤشر بعد كلمة "to" ثم نذهب إلى تبويب إدراج Insert وننقر على أمر إسناد ترافقي Cross-reference: يمكننا الوصول إلى نفس الأمر من تبويب مراجع Reference أيضا، وفي الحالتين سيُفتح نفس مربع الحوار. في مربع الحوار Cross-reference، ومن قائمة Reference type نختار نوع العنصر الذي نرغب في إنشاء إسناد ترافقي له، وهو شكل Figure في حالتنا هذه: ومن قائمة Insert reference to نحدد فيما إذا كنا نريد إدراج كل التسمية التوضيحية Entire caption (أي الرقم والعنوان)، نص التسمية التوضيحية فقط Only caption text، رقم الصفحة Page number، إلخ: نبقي على خيار Insert as hyperlink مؤشرا لكي يكون الإسناد بشكل ارتباط يمكن النقر عليه للانتقال إلى الشكل، ثم نحدد الشكل الذي نريد الإحالة إليه، وهو الشكل 3 في مثالنا، ثم ننقر على إدراج Insert: سيتم إدراج الإسناد الترافقي، وعند تمرير الفأرة فوقه يظهر تلميح يخبرنا أنّه يمكننا الانتقال إلى الشكل بالنقر على النص مع الضغط على مفتاح CTRL: سنقوم بإدراج إسناد ترافقي آخر، للجدول 4، ولكن هذه المرة سنستخدم نص التسمية التوضيحية فقط بدون الرقم: بعد النقر على إدراج، سيتم إنشاء إسناد ترافقي للجدول 4 داخل القوسين، يمكننا النقر عليه للانتقال إلى الجدول الواقع في مكان آخر من هذا المستند:
-
سيفاجئك العملاء بطرق استخدام منتجك مبتكرة. وهذا لا يأتي من دراسة وتفكّر من جانبهم وإنّما نتيجة لجعلهم منتجك يتكيّف مع احتياجاتهم. يقول Peter Drucker قولته المشهورة: "نادرًا ما يشتري العميل ما تظنّ الشركة أنّها تبيعه"؛ وهذه إشارة إلى أنّه لكي تطوّر منتجًا ما يجب عليك أوّلًا أن تدرس وتفهم الغرض الذي سيُستخدم من أجله. لنوضّح الأمر بمثال: بعد أن أطلقنا Intercom بفترة قصيرة قمنا بإضافة ميزة الخارطة لنتمكّن من معرفة أماكن عملائنا حول العالم. كانت هذه الميزة من النوع الكلاسيكي وكانت رائعة جدًّا لكنّنا لا نعرف لماذا. ولقد استطعنا رؤية كم أصبحت هذه الخارطة شعبيّة من خلال عدد الأشخاص الذين يستخدمونها. لكن التسويق للخارطة كميزة كان صعبًا، لأنّه كان من الصعب معرفة سبب استخدامها. هل هو معرفة المكان الذي يأتي منه أغلب العملاء؟ كلّا، العديد من المُنتجات تفعل ذلك.هل هو رؤية العملاء من مدينة معيّنة؟ كلّا، فقوائم المستخدمين تفعل ذلك بشكل أفضل بكثير.هل هو معرفة عدد مستخدمي المنتج في بلد معيّن؟ كلّا، فقوائم المستخدمين تفعل ذلك بشكل أفضل بكثير أيضًا.إذًا ما هو الغرض من الخارطة بغضّ النظر عن كونها مثيرة للإعجاب؟ لقّد فكّرنا بثلاث طرق استُخدمت فيها هذه الخاصيّة: هنالك أشخاص يفضّلون استعراضها في المعارض التجارية والمؤتمرات (انظر إلى الحاسوب الشخصي): وأشخاص يفضّلون استعراضها على تويتر: وآخرون يفضّلون استعراضها أمام المستثمرين: إذًا ما تفعله الخارطة هو أنّها تبدو رائعة وتثير إعجاب العملاء؛ هذا كل ما تفعله. التحسين على أساس الاستخداملو أردنا تحسين الخارطة قبل معرفة الغرض الذي تُستخدم من أجله لحاولنا إنشاء خارطة أفضل. فيما يلي بعض الأمور التي قد نركّز عليها: الدّقة الجغرافية.المجموعات الجغرافيّة.حدود أفضل للدولة أو المدينة.خاصية السحب لإنشاء مناطق regions.تحسينات خرائطيّة أخرى متنوّعة.قد تستغرق منّا هذه التحسينات عدّة أسابيع أو أشهر، وفي النهاية تؤدّي إلى منتج أسوء؛ لأنّ العميل لم يكن يشتري ما كنّا نظن أنّنا نبيعه. فالخارطة أصبحت عبارة عن قطعة للعرض وليست خارطة. ما الذي يجعل الخارطة تقوم بتلك المهمّة بشكل أفضل؟ أولًا وقبل كل شيء، خارطة مصمّمة لتبدو جيّدة.خارطة تقوم بإخفاء البيانات الحسّاسة بشكل تلقائي مما يجعلها قابلة للمشاركة.خارطة من السهل على العملاء مشاركتها.وهذا بالضبط ما قمنا بعمله. لقد قمنا بعرض على عملائنا فرصة مشاركة خارطة متحرّكة وجميلة، وزوّدناهم بعنوان URL فريد من نوعه وقابل للمشاركة: خارطة أسوء تقوم بعمل أفضلعندما تقوم بالتركيز على الكيفيّة التي تُستخدم فيها الميزة، متجاهلًا فئة أو نوع الميزة، ستتعلم كيف تقوم بتحسينها بسرعة، وهذه التحسينات سيتردد صداها على الفور. بإمكانك مشاهدة المزيد من ردود أفعال العملاء تجاه الخارطة القابلة للمشاركة هنا. حقوق التّصميم عائدة لـHongyuan وحقوق تطوير الميزة عائدة لـEoin وPatrick. ترجمة -وبتصرّف-للمقال This is not a map لصاحبه: Des Traynor. حقوق الصورة البارزة: Designed by Freepik.
-
- غرض الاستخدام
- تجربة المستخدم
- (و 8 أكثر)
-
إنّ إطلاق خاصيّة ناجحة يتطلب نفس المهارات لإطلاق منتجٍ ناجح، والفرق هو أنّك يجب أن تتعامل أيضًا مع القرارات السابقة، وترضي العملاء الحاليين كذلك. الأمر صعب. إنّ غالبية الخصائص الجديدة تتخبّط أو تُخفق، ولكنّك لا تُلاحظ ذلك. ينتهي المطاف بالخصائص الجديدة بكونها غير مقدّرة، غير مستخدمة، وسرعان ما يتم نبذها؛ وهذا هو بيت القصيد. عليك أن تعرف أنّ التطوير والتحسين صعب في عالم البرمجيّات. قد تقوم بإجراء الأبحاث لعدّة أشهر، تقوم بتحليل التّركيبية البشرية للمُستخدمين demographics، المقاييس metrics، البيانات الخاصة بتفهم عادات وثقافات الأفراد ethnographics، التحليلات، خواصّ التكوين النفسي للأفراد psychographics، تستطيع تسميتها ما شئت. كما تقوم بمقابلة العملاء لعدة أيام، أسابيع، أو أشهر في محاولة لفهم احتياجاتهم الحقيقية. ليس ما يقولون إنّهم بحاجة إليه، ليس ما يقولون إنّهم يُريدونه، وليس ما يطلبونه، بل ما يحتاجون إليه حقًّا. ثم تبدأ أنت ببناء ذلك، ومع ذلك ما تزال تُخفق؛ هذه هي المهمّة الصعبة. الحقيقة هي أنّ الخاصيّة لا تُعتبر موجودة ما لم تُستخدم من قبل العميل، وهذا الأمر غالبًا ما يتم نسيانه عند الاندفاع لإتاحة الخاصيّة بشكل سريع. إنّ الأمر لا يتعلّق بإنهاء برمجة الخصائص ودفعها إلى الخادوم، ولا بالتحقق من أنّك قمت بجميع الخطوات اللازمة، الأمر يتعلّق بالوصول إلى منتج يُستخدم من قبل العملاء. لذلك قبل أن تقوم بتقديم الخاصيّة التالية، اسأل نفسك هذه الأسئلة: 1.هل سيراها ويفهمها الجميع؟ عندما قامت شركة مايكروسوفت بعمل استطلاع لمعرفة الخصائص التي يرغب المستخدمون في أن تقوم الشركة بإضافتها إلى Office، وجدوا أنّ 90% من الخصائص هي موجودة أصلًا في البرنامج. افترضت مايكروسوفت أنّ هذا هو تحدّي الوعي بالبرنامج، وبالتالي أطلقت شريط الأدوات الجديد ribbon toolbar الذي يقوم بإبراز جميع الخصائص، وبالتالي لا يتم إبراز أي شيء كما قلت سابقًا، الأمر صعب ومعقّد. بالتأكيد أنت تريد أن يبدو المنتج متكاملًا عندما تصمّم النسخة الأولى منه، وبذلك قد لا تخطط لتوسيعه بالضّرورة، أو تترك مجالًا للخصائص الإضافيّة. وعندما تقوم بإضافة تلك الخصائص ستتيح لها مجالًا، وسيسبب ذلك المشاكل للمستخدمين في قابلية اكتشاف discoverability خصائص المنتج. فإذا وجدت نفسك تجيب على أسئلة حول مكان الخاصيّة باستمرار، اعلم أنّك تواجه مشكلة في قابلية الاكتشاف، وأنّ جميع الخصائص الجديدة ستخفق، أو على الأقل ستتطلب الكثير من الممارسة للعثور عليها واعتمادها. 2. هل تعرض على المستخدمين ما قمت به، أم ما يمكنهم القيام به؟ عندما تقوم بإخبار العملاء أنه تمّت إعادة برمجة المُنتج من الصّفر "ground up rewrite، "معتمد على HTML5"، أو "ذو تصميم متجاوب" أو أي شيء من هذا القبيل، ستفشل في الوصول إلى النتيجة المقصودة، إلّا إذا كنت تبيع للمطوّرين. لا أحد يهتم بما قمت به، أو كيف قمت به، يهتم العملاء بما يستطيعون القيام به من خلال المنتج فحسب. ركّز رسالتك على ما يمكن للمستخدمين تحقيقه الآن مع الخاصيّة الجديدة، وبذلك تستطيع جذب اهتمامهم. 3. هل تقوم بالإعلان عن الخاصية في السياق المناسب؟ إنّ الخصائص الجديدة، خصوصًا الإضافات الصغيرة، تُضاف إلى المنتج ويُعلن عنها في السياق غير المناسب عندما لا يكون العميل يستخدم المُنتج بالفعل. يجب ألّا يكون هدفك "إطلاق الخاصيّة" وإنّما "استخدام الخاصيّة" من قبل العملاء. إنّ البريد الإلكتروني هو وسيلة خاطئة لهذا النوع من الإعلانات؛ حيث أنّه يعتبر مبالغ فيه، وعادةً ما يصل في الوقت الخطأ وفي المُناسبة الخطأ. وبذلك يكون أفضل وقت للترويج للتحسينات الجديدة هو عندما يكون أحدهم يعرف منتجك ويستخدمه بالفعل. 4. كيف سيسمع عملاء الغد عن الخاصية الجديدة؟ طالما يتطوّر المنتج فهو يتوسّع أبعد مما يمكن تعلّمه خلال فترة قصيرة من الزمن. وهذه ليست مشكلة، حيث أنّه ليس من الضرورة أن تكون الخصائص معقولة ومفهومة منذ البداية. تكون الخصائص ملائمة فقط عندما تحل المشاكل. ولتبسيط الموضوع، أنت لا تحتاج إلى إضافة وسوم إلى الملفات ما لم تنتهي عملية رفعها. كما أنّك لا تحتاج إلى دمج الوسوم ما لم يكن لديك العديد من الوسوم المختلفة. لذلك من الطبيعي أن يكون توقيت الرسالة خاطئًا عندما تخبر المستخدمين الجدد عن طريقة دمج الوسوم. هنالك أوقات مناسبة لتقديم الخصائص للعملاء، وعندها تصبح الرسائل الموجّهة مهمّة. مثلًا، قمنا بالترويج لخاصيّة حفظ الردود في Intercom عندما أصبح لدينا عددًا من الردود المُرسلة. كما قمنا بالترويج لخاصيّة اختصارات لوحة المفاتيح الخاصّة بـ Intercom بعد أن استخدم العملاء المنتج لمدة كافية تجعلهم يهتمون بالاختصارات. هذه هي طريقة جعل الرسائل مهمّة. 5. هل تخطط للمتابعة مع المستخدمين وغير المستخدمين؟ يجب عليك بعد أن تطلق الخاصيّة أن تقوم بمتابعة مستخدميها لفهم ومعرفة كيف، لماذا ومتى تُستخدم. ابحث عن طرق لزيادة استخدامها. إليك بعض الأسئلة التي وجّهتها للعملاء حول الخاصيّة الجديدة: متى قمت بملاحظتها؟ ما رأيك فيها؟ هل استخدمتها مباشرةً؟ ما الذي جذبك إليها؟هل احتجت إلى دليل استخدام الخاصيّة؟ هل كان ذلك الدليل كافيًا؟هل كانت هنالك عوائق لاستخدامها؟هل هنالك أوقات تريد استخدام الخاصيّة فيها ولكنّك لا تستطيع؟هل أخبرت أحدًا عن سبب استخدامك للخاصيّة؟ ما الذي قلته؟إنّ متابعة الأشخاص الذي لا يستخدمون الخاصيّة وفهم السبب الذي يمنعهم من ذلك له القدر نفسه من الأهميّة، إن لم يكن أكثر أهميّة، من متابعة مستخدميها. ستجد أحيانًا أن الحواجز التي تعيقهم سهلة الكسر. مثلًا؛ "أنسى دائمًا أن أراجع المنتج"، "لا أعرف إذا كان هنالك أحدًا آخر يستخدمها في الشركة"، "أنا بحاجة إلى الحصول على ملف CSV للبيانات"، إلخ. جميع هذه المشاكل قابلة للحل فيما إذا فهمتها بصورة جيّدة. يجب أن تعرف أنّه خلال عملية التصميم قد تخطئ في أشياء معيّنة، وهذه الحقيقة يتم تجاهلها في العديد من المخططات التفصيلية للمنتج. يخطئ المصمّمون في أحيانٍ كثيرة، وعندها يصبح لديهم خياران؛ تحسين الخاصيّة، أو تجاهلها والانتقال إلى الخاصيّة التالية. إذا اخترت الخيار الثاني، فهذا يعني أنّك ستقع في الفخ الذي وقعت فيه ميكروسوفت: إضافة خصائص لا يعرف أحد بوجودها. ترجمة-وبتصرّف-للمقال: Why New Features Usually Flop لصاحبه: Des Traynor.
-
عندما يحدثني ريادي أعمال مبتدئ عن الميّزات التنافسيّة التي تتمتّع بها شركته النّاشئة، فهناك احتمالٌ ضئيلٌ جدًّا أن يخبرني بميّزة حقيقيّة لا توجد عند الآخرين. معظم الشّركات النّاشئة التي سبق لي أن تعاملتُ معها، كانت تضيف في العروض التي ترسلها فصلًا خاصًّا يتحدّث عن الميّزات التنافسيّة التي تتمتّع بها، في الحقيقة وبدون مبالغة، 95 في المئة من الميّزات المذكورة هي مجرّد عبارات عاطفيّة بعيدة أيّما بعدٍ عن أن تكون صفة تميّز الشركة عن غيرها، وقد لا تكون ميّزة أصلًا. أكبر دليل على أنّ هذه الميّزات التي تسمّيها تنافسيّة ليست كذلك، أنّ جميع الشّركات الأخرى على سطح الأرض تدّعي نفس الادّعاء لنفس الميّزات، فأين التنافسيّة في الموضوع؟ ملاحظة على الهامش: أتمنّى ألّا يصيبك هذا المقال بالإحباط، سنتكلّم في مقال آخر عن الميّزات التي يمكن أن تكون تنافسيّة بحق، لكن تحملني قليلًا الآن. كل ما سأذكره الآن ليس ميزات تنافسية:لدينا المزية xهذه ميّزة نعم، أي أنها قد تميّزك عن غيرك في البداية، لكنّها تبقى كذلك حتى يبدأ أحدٌ آخر بتطبيقها أيضًا، بالتالي لن تحميَك طويلًا من المنافسين. تأكّد دومًا أنّ أيّة شركة –ربّما كما فعلت أنت يومًا ما – قبل أن تبدأ ستمرّ بمرحلة تراقب فيها أداء الشّركات الأخرى في نفس المجال، فتأخذ منها ما يفيد وتتجنّب ما يضرّ. بالتالي أيّة شركة ستأتي من بعدك سوف تبني ميّزاتها بناءً على ميّزاتك أنت، فمهما كنتَ مبدعًا بابتكار ميّزات جديدة سيأتي أحدٌ آخر ويُضيفها إليه. وفي النّهاية ما يهمّ الزبون – عند اختيار مع من سيتعامل – أين وصل كلّ منكما اليوم، وليس من ابتكر هذه الميّزات أولًا. لدينا أكبر عدد من المزاياجرت العادة أنّ الشّركات التي مضى عليها وقتٌ أكبر في السّوق -وظلّت تتابع المتغيّرات اليوميّة- ستمتلك منتجاتُها عددًا من المزايا يفوق أيّ منافس آخر سيأتي في وقت لاحق. المشكلة يا صديقي أنّ الزبائن لا يهمّهم العدد الأكبر من المزايا بقدر ما هم يبحثون عن مزايا بعينها. وهكذا كلّما تأتي منافسة جديدة يبدأ الجميع يضيفون مزايا جديدةً لمنتجاتهم، ومع الوقت سيصبح لدى الجميع عددًا مهولًا منها تغطّي أكثر من 80 في المئة من احتياجات الزبون، بالتالي أيّة مزيّة إضافيّة من نوع "زيادة عدد" لن تسهم حقيقةً في جعلك الأبرز بين المنافسين، إن لم تختر حقًّا ما يبحث عنه الزبون. لدينا براءات اختراع لمزايا منتجاتناوكأنّك تقول: “لا أحد يستطيع منافسة مدوّنتي ﻷنّ جميع حقوق النّشر محفوظة"، ألا يبدو لك الأمر سخيفًا؟ بنفس المبدأ، لا يمكنك أن تدّعي أن امتلاكك لبراءة اختراع لمنتجاتك البرمجيّة سوف يحميَك من المنافسين إلى الأبد، ربّما ينطبق هذا الأمر على بعض الصناعات كالأغذية والأدوية والأمور المشابهة، لكنّني لم أسمع قَط بشركة تفوّقت على منافسين يقدّمون خدماتٍ أجود، لمجرّد امتلاكها براءات اختراع! في الحقيقة براءاتُ الاختراع في مجال البرمجيّات تحديدًا ليست ذات أهميّة خاصّة للشركات الصغيرة والنّاشئة، نفس الأمر ينطبق على المنتجات العتاديّة hardware، فأجهزة مشغّلات mp3 جميعُها تستخدم ملايين براءات الاختراع، لكن رغم ذلك لم يمنع ذلك شركة أبل من السّيطرة على السّوق نحن الأمهر في الشبكات الاجتماعية والظهور بمحركات البحثهل سمعت بالدّراسة التي تقول أنّ ثمانين في المئة من سكّان الولايات المتّحدة الأمريكيّة متأكّدون تمامًا أنّهم يقودون بشكل أفضل من متوسّط السّائقين في البلد؟ (إن فكّرت في الأمر قليلًا ستجده غير منطقيّ) أيضًا ثمانون في المئة تقريبًا من أصحاب الشّركات النّاشئة الّذين قابلتهم أخبروني أنّ أداءهم أعلى من المتوسّط، في كلّ من دعم المواقع لمحرّكات البحث SEO، وتويتر، وبناء المجتمعات الافتراضيّة building communities (لا تسألني عن معنى هذا المصطلح فأنا نفسي لا أعرفه). إنّ الشّبكات الاجتماعيّة وخوارزميّات محرّكات البحث في تطوّر دائم، فالذي يحظى بمقدّمة نتائج البحث في جوجل اليوم قد يختفي غدًا. بل والأكثر من ذلك، فأنت لا تستطيع التحكّم بأداء الشّركات الأخرى في نفس المجال ولا في كونها جيّدة أو حتى أفضل منك. فادّعاؤك بامتلاك ميّزة ليست ثابتةً على الدّوام هو مجرّد دُعابة. لدينا شغف بعملناالجميع لديهم الشّغف! وهل كنتَ تظنّ أنّ باقي الرّياديين يتحمّلون العناء والتّعب وساعات العمل الطّويلة كلّ يوم، دون أن يمتلكوا أيّ شغف أو حبّ للمجال الذي يعملون به؟ الشّغف شرطٌ لازم غير كافٍ، كأنّك تقول: “بالتّأكيد سيتفوّق أبنائي أكثر، فأنا أحبّهم أكثر ممّا تحبّ أنت أبناءك". وإيّاك أن تذكر الشّغف أمام المستثمرين فلن يكونوا سعداء بسماعك تضيفُه لميّزاتك التّنافسيّة. لدينا ثلاثة من حاملي شهادات بدرجة دكتوراه (أو ماجستير) في فريقنالو نظرت إلى روّاد الشركات النّاشئة الناجحين لوجدت أكثرهم لم يحصلوا على أيّة درجة أكاديميّة بعد التخرّج، وكلّ من عاش في عالم البرمجيّات تحديدًا يعلم أنّ معظم ما نتعلّمه في الجامعة بعيدٌ أيّما بعد عمّا نقوم بممارسته كلّ يوم، فمن يهتمّ إذًا بتلك الشّهادات المعلّقة على الجدران؟ حاول أن تطّلع على لقاءات مؤسّسي الشّركات العالميّة النّاجحة، كم منهم أشار إلى درجة الماجستير التي نالها؟ بل كم منهم حصل عليها أساسًا؟ ليس من السّيئ أن يحصل رياديّ على دراساتٍ عليا، لكنّها -في ذات الوقت- ليست ميّزة قيّمة يتباهى بها كرائد أعمال. نحن نعمل بجدهل سمعت بشركة 37signals التي يعمل أفرادها ثلاثين ساعةً في الأسبوع؟ وماذا عن الكاتب ورياديّ الأعمال الشّهير Tim Ferris الذي يعمل فقط أربع ساعات في الأسبوع كلّه! هل تظنّ أنّك إن عملت -وتمكّنت من الاستمرار- سبعين ساعة أسبوعيًّا ستتفوّق على المنافسين؟ حسنًا ربّما، لكن تذكّر أنّ العمل بجدّ لا يعني بالضّرورة العمل بذكاء. ومع ذلك، لنفترض أنّك متفانٍ لدرجة أنّك تبذل سبعين ساعة أسبوعيًّا لتنجز مهامك، هذا الرقم تستطيع بلوغه -بسهولة- أيّة شركة أخرى لديها عشرة مطوّرين، بل حتّى أيّ مشروعٍ مفتوح المصدر يساهم فيه عشرة هواة في أوقات فراغهم! لدينا أرخص الأسعارليس سيّئًا أن تكون أرخص من غيرك، ففيITWatchDog (إحدى الشّركات التي أسّستُها سابقًا) كان عدم غلاء الخدمات مهمًّا جدًّا في استراتيجيّتنا. لكن لا يمكنك الاعتماد على السّعر وحده لتنافس عليه، لو كان الأمر كذلك لاكتفى كلّ منافس جديد بأن يخفّض أسعاره كي يتمكّن من السّيطرة على السّوق. في الواقع فإنّ الشّركات الكبرى تتخلّص من منافسيها عادة بسياسة مشابهة، مايكروسوفت مثلًا توظّف ألف مطوّر للعمل على متصفّح Internet Explorer وحده ومن ثمّ تقدّمه للزبائن مجّانًا فتدمّر بذلك سوق متصفّحات الويب، فكلّ منافس جديد يحاول الآن أن يقدّم منتجه بتكلفة معيّنة -مهما صغرت- سيكون قد استُبعد تلقائيًّا. كذلك الشّركات الجديدة المموَّلة، لن يكون لديها مشكلة في إنفاق ميزانيّات هائلة في مقابل أن تحصل على حصّة في السّوق، حتى لو أدّى ذلك إلى إحراق جميع المنافسين، بما فيهم أنت! ولا تنسَ أيضًا أنّ الجميع يستطيعون أن يتبنّوا مبدأ جذب الزبون بتقديم الخدمات المجّانيّة Freemium، فليس سعر الخدمة عبرة أبدًا! وبالمناسبة، في ITWatchDog تمكنّا من تقديم خدمات رخيصة نسبيًّا بفضل أمرين: الأول أنّنا كنّا نقدّم الخدمة للزّبون مباشرة دون وسطاء، فكان يدفع القيمة الحقيقيّة للخدمة دون أن تتضاعف عدّة مرات قبل أن تصل إليه. الأمر الثّاني أنّنا كنّا نستخدم القِطع الأحدث والأرخص، على عكس الكثير من المنافسين الذين توقّفوا عن متابعة المستجدّات اليوميّة واكتفوا باستخدام قِطعًا أغلى يصل عمرها إلى خمس سنوات. ما خلاصة كل هذا؟لحظة، نسيتُ أن أخبرَك أيضًا أنّ أمورًا مثل بذل قصارى الجهد، والابتكار كلّ تلك الأمور لا تكفي وحدها لجعلك متميّزًا! ولا الإبداع، ولا حقوق الملكيّة الفكريّة، إنّها أمور رائعة نعم، لكن لا يمكنك الاعتماد عليها أبدًا كميّزات تنافسيّة على المدى الطّويل. تذكّر أنّك تعيش في عصرٍ أصبح فيه العالم قرية صغيرة، وأصبح بإمكان الجميع أن يحصلوا على التّقنيّات التي يحتاجونها، وأن يتعلّموا كلّ ما ينقصهم ويتفوّقوا به على الآخرين. عصرٌ تمكّن الجميع فيه من الوصول إلى أفضل أداة في التّسويق والمبيعات والتّواصل، الإنترنت! في هذا الزّمان أصبحت أقوى أدوات ومنصّات البرمجة متاحة بالمجّان، وكذلك الإنترنت السريع والمخدّمات عالية الأداء أصبحت رخيصة نسبيًّا، وأصبح من السّهل أن تجد أشخاصًا أكفّاء مستعدّين -وبكلّ سرور- للعمل 60 ساعة أسبوعيًّا بمقابلٍ يكاد يكفي لشراء وجبة بسيطة واحدة، لمجرّد رغبتهم في أن يؤسّسوا شركة ناشئة جديدة. في هذا العالم الكثير من الطاقات، والإبداعات، والإمكانيّات، والفرص، أكثر من أن يمكن تغطيتها بكلمات فقدت صلاحيّتها مثل "ملكيّة فكريّة". وعلى الجانب الآخر، كلّ شيء يمكن تكراره واستخدامه في مكان آخر بطريقة ما، وحتّى يمكنني أن أقول أنّ أيّ شيء مهما بلغت قيمته، سوف يستعيره أحدهم ويستخدمه هو أيضًا، ولن يهتمّ أحدٌ بعد ذلك مَن الّذي ابتكره في البداية. لذلك ضع في حسابك عند كتابة خطّة عملك business plan أنّ أحدًا ما سوف يقلّدك في يوم من الأيّام مهما كنتَ فريدًا ومتميّزاً. لكن مع ذلك ولحسن الحظّ، هناك وفرة من الطرق التي يمكنك اتّباعها لتحصل على ميّزات لا يمكن ﻷيّ منافس آخر أن يحصل عليها (دون عناء)، لكنّها – مع الأسف – نادرةٌ وصعبة. بالطّبع هي كذلك! وهل كنتَ تظنّ أنّه من السّهل بمكان إطلاق مشروع رياديّ ذي أفكارٍ إبداعيّة يصعب منافستها؟ في مقال قادمٍ -إن شاء الله- سأتحدّث أكثر عن بعض الميّزات التنافسيّة الحقيقيّة التي لا يمكن لشركات أخرى أن تتغلّب عليك فيها، سواءً كانت -هذه الشّركات- عملاقة أو مموّلة بأرقام فلكيّة أو حتى مشاريع مفتوحة المصدر يدعمها مطوّرون هواة من جميع أنحاء العالم. حتى ذلك الحين أودّ أن أعرف رأيك في الافتراضات التي ذكرتُها، هل تظنّ أنّني بالغت قليلًا؟ هل هناك ميّزات أخرى يدّعون أنها تنافسيّة وهي ليست كذلك؟ شاركنا النقاش في التّعليقات. ترجمة -وبتصرّف- للمقال: No, that IS NOT a competitive advantage لصاحبه Jason Cohen. حقوق الصورة البارزة: Designed by Freepik.