conflict resolution چیست؟

با یک مساله ساده بریم جلو. شما فرض کنید توی کدی که نوشتید به صورت صریح و مستقیم گفتید که بکگراند همه پاراگرف‌ها باید قرمز باشه. یعنی این دستورات رو توی کدتون دارید:

p{
    background-color: red;
} 

اما وقتی سایتتون رو تو مرورگر باز میکنید میبینید بک‌گراند بعضی پاراگرافها قرمزه و بک‌گراند بعضی دیگه سبزه. با کمال تعجب کدتون رو یه بار دیگه بررسی میکنید و میگید من که دقیقا گفتم بک‌گراند پاراگرافم  باید قرمز باشه پس چرا بعضی‌ها رو سبز نشون میده؟ هر چقدر هم کدتون رو بالا و پایین میکنید مشکل رو پیدا نمیکنید و ایقدر وقتتون گرفته میشه که آخر کار هم اعصابتون خرد میشه و سیستمتون رو خاموش میکنید و بیخیالش میشید. غافل از اینکه شما یه جایی تو کدتون یه دستور دیگه هم گذاشتید:

div p{
    background-color: green;
} 

همونجور که میدونید توی کد اول نوشتید بک‌گراند همه pها باید قرمز باشه و تو کد دوم نوشتید pهایی که توی div هستند باید سبز باشن. شاید با دیدن کد دوم یه خورده اعصابتون راحت تر بشه و بگید خب مشکل رو پیدا کردم اما ممکنه بعضی هاتون هنوز قانع نشید و بگید چرا بک گراند pهایی که تو div هست باید سبز باشه؟ مگه من تو کد اولی نگفتم همه pها قرمز باشه؟ پس باید p هایی که تو div هستند هم شاملش بشه و رنگشون قرمز بشه.

اینجاست که بحث تعارض یا conflict بوجود میاد. اساس مشکل از اینجا بوجود اومد که دو تا استایل مختلف رو داریم روی یک عنصر مشترک اعمال میکنیم و میخواهیم ببینیم زور کدوم استایل بیشتره. در ادامه در مورد این موضوع میخواهیم صحبت کنیم و امیدوارم با خوندن این مقاله مشکلات و اعصاب خوردیهای شما در کدنویسی رو در حد امکان کاهش بدم

قوانین مربوط به conflict resolution

شما اگر این 4 قانون رو بلد باشید کمتر دچار سردرگمی در کدهاتون میشید:

  1. origin
  2. merge
  3. inheritance
  4. specificity

1 - Origin

این دو مفهوم به هم نزدیکن و برای همین با هم توضیحشون میدم. شما فرض کنید کدهای html و cssتون به شکل زیر نوشته شده:
 
CSS
p{
    background-color: red;
}

p{
    background-color: green;
} 
HTML
<p>
    hello world!
</p> 
به نظرتون در کد بالا، بک‌گراند پاراگرافمون قرمز رنگه یا سبز رنگ؟
نکته ای که اینجا وجود داره اینه که کدهای html و css به ترتیب از بالا به پایین اجرا میشن. پس تو کد cssمون اول میاد بک‌گراند p رو قرمز مقداردهی میکنه و چند خط پایین تر بک‌گراند p رو با سبز جایگزین میکنه. پس اولین قانونی که شما یاد گرفتید اینه که همیشه آخرین استایل برنده است.
اما حتما به این نکته توجه داشته باشید که ما داریم در مورد حالتی صحبت میکنیم که یک: دو تا استایل مختلف روی یک عنصر مشترک اعمال میشه (مثلا استایل سبز و قرمز داره روی عنصر پاراگراف مقدار دهی میشه) و دو: سلکتورها دقیقا یکسان هستند (یعنی جفتشون p هستند. برای اینکه بهتر بفهمی مثال بعدی رو ببین!)
 
حالا بیاید و مثال زیر رو در نظر بگیرید و بگید. به نظرتون رنگ نوشته hello world در کد زیر به چه شکلی میشه؟
CSS
div p{
    color: red;
}

p{
   color: green;
} 
HTML
<div>
    <p>
        hello world!
    </p>
<div>     

اگه از قانون قبلی که میگفت همیشه آخرین استایل برنده است کمک بگیریم احتمالا میگید متن نوشتمون میشه سبز رنگ. چون تو استایل اولی میگه pهایی که تو div هستند رنگشون قرمز بشه و در ادامه میگه همه pها باید سبز رنگ بشن. اگه همچین استدلالی کردید باید بگم استدلالتون اشتباهه. چرا؟ چون تو نکته تکمیلی گفتیم اگر سلکتورها دقیقا مثل هم باشن آخرین استایل برنده است. درسته که اینجا جفتشون میتونن به یک عنصر مشترک اشاره داشته باشن (متن hello world رو هم با استایل p بهش استایل بدیم  و هم با استایل div p) اما سلکتورهاشون یکی نیست. یکی از سلکتورها div p است و یکی دیگه p. پس به عنوان نکته خیلی مهم این رو در نظر داشته باش.

ممکنه بپرسید پس رنگ متنمون چه رنگی میشه؟ که باید بگم میشه قرمز رنگ و علتش رو در specificity و بهتون میگم. بحث رو گم نکنیم ، من قرار بود که 4 تا قانون بهتون بگم که قانون اول origin رو بهتون گفتم

2- Merge

کد زیر رو نگاه کنید و بگید استایل متن hello world به چه صورت میشه؟

CSS
p{
    color: red;
}

p{
    font-size: 14px;
} 
HTML
<p>
   hello world
</p>     

همونجور که میبینید درسته ما دو تا استایل برای p داریم ولی استایلهایی که توی هر کدومش تعریف شده با هم دیگه تعارضی ندارن یا بهتره بگیم کانفلیکتی ندارن. پس این دو تا استایل با هم ادغام (merge) میشن. و میشه به کد css بالا اینجوری هم نگاه کنیم:

CSS
p{
    color: red;
    font-size: 14px;
} 

تا اینجای بحث رو خوب متوجه شدید؟ اگه سوالی داشتید در قسمت نظرات بپرسید.
بریم برای قانون سوم یعنی inheritance:

3- Inheritance

inheritance یا وراثت قانون سومیه که میخواهیم در موردش صحبت کنیم. موضوع سختی نیست اما چون به صورت نوشتاری قراره توضیح بدم باید یه خورده توجهتون رو بیشتر کنید و با دقت دنبال کنید.

فرض کنید که ما تو سایتمون به شکل زیر اومدیم کد نویسی کردیم.

 

<body>

    <div>
        <h1> Heading </h1>
        <p> paragraph </p>
    </div>
    
    <p> lorem ipsum1 </p>
    <p> lorem ipsum2 </p>

</body> 

ما میتونیم به خروجی سایتتمون به صورت درختی نگاه کنیم. یعنی چی؟ ما یه تگی تو صفحه داریم به اسم body که همه تگهای سایت تو این تگ قرار میگیرند. هر کدوم از تگها رو اگه به صورت element بهش نگاه کنیم میتونیم همچین مدلی رو برای صفحه HTMLمون متصور بشیم:

اگر به ترتیب هر کدوم از element ها رو از بالا به پایین و به ترتیب شماره گذاری کنیم مفهوم وراثت رو میشه اینجوری بیان کنیم:

ما توی تگ body  پنج تا element داریم که میتونیم بگیم این elementها فرزندان body هستند. همچنین اگر به المنت 1 نگاه کنید میبینید که المنت 2 و 3 فرزند المنت 1 هستند. پس چی شد؟ المنت 1 فرزند body است، المنت 2 و 3 فرزند المنت 1 است و به همین دلیل میتونیم بگیم فرزند 2 و 3 جز نوادگان body محسوب میشن. به همین ترتیب المنت 4 و 5 (مثل المنت 1) فرزند body محسوب میشن.

حالا این همه پدر فرزندی کردیم که چی بشه؟! که بگیم تو css هم مفهوم وراثت داریم. یعنی یه سری صفات از پدر به فرزند به ارث میرسه. مثلا فرض کنید در مورد صفت color صحبت میکنیم که در body برابر قرمز گذاشتیم و صفت background-color در المنت 1 برابر سبز گذاشتیم. این صفات میتونن به فرزندانشون به ارث برسن. چه جوری؟ اگر به صورت گرافیکی بخواهیم نشون بدیم میتونیم بگیم به این صورت رنگهای قرمز و سبز به فرزندانشون به ارث میرسه:

پس چون در تگ body استایل رنگ متن رو قرمز کردیم همه فرزندانش هم قرمز رنگ میشن. و چون در استایل بک‌گراند المنت1 رو سبز گذاشتیم بک‌گراند همه فرزندان المنت 1 سبز میشن. سوالی که پیش میاد اینه اگر من رنگ متن المنت 1 رو آبی کنم رنگ متنم آبی میشه یا قرمز میمونه؟ که در جواب باید بگم آبی میشه چون برای خودش  دارم استایل تعریف میکنم. پس به صورت خلاصه اینجوری میتونم بگم:

عنصر فرزند استایل والد خود را به ارث می‎بره مگر اینکه به صورت جداگانه برای عنصر فرزند استایل تعریف شده باشد.

حالا که وراثت رو فهمیدی به این سوال جواب بده:
اگر متن رنگ body قرمز باشه و رنگ متن المنت 1 رو آبی تعریف کنم ، رنگ متن المنت 2 و 3 چی میشه؟

اگه جواب سوال بالا رو درست دادی و گفتی آبی بیا و کد زیر رو هم یه نگاه بهش بنداز و بررسی کن استایل هر کدوم از تگها چه طور میشه. پیشنهاد میکنم همین کدها رو کپی کن و تو vscode  یا phpstorm یا هر ادیتوری که باهاش کار میکنی تست کن.

CSS
body{
            text-align: center;
            color:red;
        }
        p{
            color: blue;
        } 
HTML
    <h1>Main Heading</h1>
    <h2>sub heading1</h2>
    <p>Lorem, ipsum 1</p>

    <h2 style="color:green">
        sub heading1
    </h2>
    <p>Lorem ipsum 2</p> 

4- specificity

شاید بشه گفت مهم ترین و کاربردی ترین قانون ما همین قانونه. من در دوره آموزش طراحی سایت (فرانتند) هر 4 تا قانون رو توضیح دادم و اگر دوره رو تهیه کنید این قانون رو خیلی راحت یاد میگیرید چون به صورت ویدیویی بهتر میشه مفاهیم رو منتقل کرد اما من سعی میکنم در این نوشته به ساده ترین شکل ممکن این مورد رو آموزش بدم. اول ببینیم که مورد چهارم چه زمانی رخ میده:
وضعیتی رو تصور کنید که دو تا سلکتور مستقل داریم  که دارن به یک عنصر مشترک استایل میدن. در این وضعیت کدوم استایل زورش بیشتره و اعمال میشه؟ دقیقا مثالی که تو قسمت origin زدیم و گفتیم تو قسمت specificity توضیحش میدیم رو اینجا میارم:

CSS
div p{
    color: red;
}

p{
   color: green;
} 
HTML
<div>
    <p>
        hello world!
    </p>
<div>     
اینجا دقیقا شرایطی که گفتیم برقراره: دو تا سلکتور مستقل داریم که به یک عنصر مشترک استایل میدن. حالا سوال اینه رنگ متن قرمز میشه یا سبز؟
برای پاسخ به این سوال ما باید یک  سیستم امتیاز دهی ساده تعریف کنیم. به شکل زیر که یک اسکرین شات از دوره آموزشی فرانتند هست دقت کنید:

برای هر استایل ما باید 4 رقم در کنار هم بذاریم که به امتیاز نهایی برسیم. ارقام رو از روی تصویر از چپ به راست توضیح میدم:

1- رقم هزارگان مشخص میکنه که آیا inline بودن استایل رو مشخص میکنه. مثلا در استایلی که در پایین تصویر میبینید نشون میده که به پاراگراف p داریم یک inline style میدیم پس رقم هزارگان رو باید یک بذاریم
(اگه به p به صورت اکسترنال یا اینترنال استایل داده بودیم رقم هزارگان صفر بود)

2- رقم صدگان تعداد آی‌دی‌های تعریف شده در سلکتور رو نشون میده.

3- رقم دهگان تعداد کلاس هایی که در سلکتور ظاهر شدن رو مشخص میکنه.

4- رقم یکان تعداد تگهایی که در سلکتور ظاهر شدن رو مشخص میکنه.

بیاید چند تا مثال بزنیم که این موارد رو بهتر متوجه بشیم. به کد زیر دقت کنید و بگید امتیاز این استایل چنده؟

 

div p { color:red; }
 
امتیاز کد بالا رو پیدا کنید و بعدش توضیحات من رو بخونید. (نکته سلکتور کد بالا div p است)

1-آیا این کد inline style؟ خیر پس رقم هزارگان صفره
2- آیا در سلکتور آی دی میبینید؟ خیر پس رقم صدگان هم صفره.
3- در سلکتور کلاسی هم تعریف نشده پس رقم دهگان هم صفره.
4- دو تا تگ html تو سلکتور داریم پس یکان میشه 2

در نتیجه امتیاز این کد میشه 2

 ممکنه این سوال پیش بیاد چه استفاده ای از این امتیاز ها میخواهیم کنیم. در جواب باید بگم ما دنبال این بودیم که اگر دو تا سلکتور مستقل داشتیم که روی یک عنصر مشترک اعمال میشدن کدوم استایل زورش بیشتره. درسته؟ امتیاز همینجا به دردمون میخوره یعنی استایلی برنده است که زورش بیشتر باشه. با این توضیح بیاید و بگید
متن پاراگراف ما در کد زیر قرمز رنگ میشه یا آبی؟
CSS
div #paragraph{
    color:red;
}

div.color p{
    color:blue;
} 
HTML
<div class="color">
    <p id="paragraph">
        lorem ipsum
    </p>
</div> 

با توجه به توضیحاتی که دادم امتیاز سلکتور div #paragraph میشه 101 و امتیاز سلکتور div.color p میشه 12. پس استایل اولی اصطلاحا برنده میشه و پاراگراف مد نظر قرمز رنگ میشه.

نتیجه گیری

در این مقاله با هم 4 تا قانون مهم در CSS رو با هم یاد گرفتیم:

Origin, Margin, Inheritance, Specificity

اگر این 4 قانون رو بلد باشید مشکلاتی که ممکنه در طراحی سر راهتون سبز بشه رو بهتر میتونید شناسایی کنید و رفعشون کنید.

دوست داری طراحی سایت رو اصولی یاد بگیری؟

اگر مطالب این مقاله برات مفید بود و دوست داری طراحی سایت رو اصولی و حرفه ای یاد بگیری میتونی این دوره آموزشی رو تهیه کنی. من تو این دوره همه مطالبی که تو این مقاله خوندی رو به همراه کلی سر فصل دیگه به ساده ترین شکل ممکن توضیح دادم. بد نیست روی دکمه پایین کلیک کنی و سرفصلهای دوره به همراه پیش‌نمایشهای دوره مشاهده کنی