پیاده‌سازی استایل‌های قبلی در CSS Module (پایان فصل سوم)

Implement Previous Styles in the CSS Module

23 بهمن 1399
پیاده سازی استایل های قبلی در CSS Module (پایان فصل سوم)

اضافه کردن pseudo-selector و Media Query در CSS Modules

حالا که با CSS Modules آشنا شدیم باید نحوه اضافه کردن pseudo-selector ها و media query ها را نیز یاد بگیریم. از آنجایی که دیگر استایل هایمان به شکل inline نخواهند بود تمام استایل های inline را از App.js پاک کنید. یعنی:

style.backgroundColor = 'red';
const style = {
      backgroundColor: 'green',
      color: 'white',
      font: 'inherit',
      border: '1px solid blue',
      padding: '8px',
      cursor: 'pointer'
};

همچنین خصوصیت style را از روی دکمه بردارید:

<button
          style={style}
          onClick={this.togglePersonsHandler}>Toggle Persons
</button>

حالا به فایل App.css می رویم و استایل های خود را اضافه می کنیم:

.App button {
  border: 1px solid blue;
  padding: 16px;
  background-color: green;
  font: inherit;
  color: white;
  cursor: pointer;
}

سلکتور ما می گوید درون کلاس App هر دکمه ای را به این شکل استایل دهی کن. اگر قبل از CSS Module ها چنین کاری را انجام می دادیم این استایل ها به صورت سراسری و برای تمام کامپوننت های ما اعمال می شد اما در حال حاضر استایل هایمان Scope دارند و فقط روی همین کامپوننت اعمال می شوند. در واقع هر جایی که شیء classes را import کنیم به این استایل ها دسترسی خواهیم داشت و دیگر نام کامپوننت مهم نخواهد بود.

حالا به راحتی می توانیم از pseudo-selector دلخواهمان (hover) استفاده کنیم و مانند CSS عادی دکمه را استایل دهی کنیم:

.App button:hover {
  background-color: lightgreen;
  color: black;
}

در آخر می توانیم استایل های کلاس red را نیز اضافه کنیم:

.App button.Red {
  background-color: red;
}

.App button.Red:hover {
  background-color: salmon;
  color: black;
}

تمام اینها کدهای CSS عادی هستند که شما باید با آن ها آشنا باشید. حالا باید تعیین کنیم که در حالتی خاص کلاس red به دکمه اضافه شود. بنابراین به App.js برمی گردیم و درون تابع render (قبل از return) یک متغیر جدید به نام btnClass تعریف می کنیم:

    let persons = null;
    let btnClass = '';

حالا داخل بلوک if که افراد را نمایش می دهیم (با شرط this.state.showPersons) کد زیر را اضافه می کنیم:

btnClass = classes.Red;

یعنی شرط if بدین صورت می شود:

    if (this.state.showPersons) {
      persons = (
        <div>
          {this.state.persons.map((person, index) => {
            return <Person
              click={() => this.deletePersonHandler(index)}
              name={person.name}
              age={person.age}
              key={person.id}
              changed={(event) => this.nameChangedHandler(event, person.id)}
            />
          })}
        </div>
      );

      btnClass = classes.Red; 
    }

حالا در قسمت return باید نام کلاس را روی btnClass تنظیم کنیم:

    return (
      <div className={classes.App}>
        <h1>Hi, I'm a React App</h1>
        <p className={assignedClasses.join(' ')}>This is really working!</p>
        <button
          className={btnClass}
          onClick={this.togglePersonsHandler}>Toggle Persons
        </button>
        {persons}
      </div>
    );

سوال: آیا کلاس های HTML و CSS نباید فقط یک رشته باشند؟ پس چطور این کلاس را که از شیء جاوا اسکریپتی classes گرفته ایم به آن می دهیم؟

پاسخ: بله، کلاس ها باید رشته ای باشند اما خود webpack محتویات درون شیء classes را به صورت رشته ای (string) قرار می دهد. بنابراین classes.Red نیز رشته خواهد بود.

حالا می توانیم آن را در مرورگر تست کنیم. نباید مشکلی وجود داشته باشد و همه چیز به طور صحیح کار می کند.

حالا نوبت اضافه کردن Media Query ها است. میخواهم این کار را برای Person.js انجام دهم. اگر به فایل Person.js بروید و به کدهای JSX آن نگاه کنید:

return (
        <div className={classes.Person}>
            <p onClick={props.click}>I'm {props.name} and I am {props.age} years old!</p>
            <p>{props.children}</p>
            <input type="text" onChange={props.changed} value={props.name} />
        </div>
)

می بینیم که با استفاده از classes.Person کلاس آن را مشخص کرده ایم. بنابراین به فایل Person.css می رویم و علاوه بر استایل های خودمان یک Media Query ایجاد می کنیم:

.Person {
    width: 60%;
    margin: 16px auto;
    border: 1px solid #eee;
    box-shadow: 0 2px 3px #ccc;
    padding: 16px;
    text-align: center;
}

@media (min-width: 500px) {
    .Person {
        width: 450px;
    }
}

اگر فایل را ذخیره کرده و عرض پنجره مرورگر را تغییر دهید، متوجه تغییر سایز افراد می شوید.

جمع بندی نکات این فصل

در این فصل یاد گرفتیم که چطور کامپوننت ها و عناصر مختلف را در react استایل دهی کنیم و به طور مفصل در مورد مشکلات و راه حل های موجود صحبت کردیم. از آنجایی که این فصل به غیر از مواردی ساده فقط کدنویسی CSS بود تمرین خاصی برایتان آماده نکرده ام چرا که نیازی به تمرین CSS ندیده ام. توجه داشته باشید که HTML و CSS و جاوا اسکریپت از پیش نیازهای این دوره بودند.

با نکات مهمی در این فصل آشنا شدیم که مهم ترین آن ها عبارت اند از:

  • استایل دهی عناصر در react به دو صورت inline و یا استفاده از فایل های css (استایل دهی external) است.
  • هر دو روش دارای مشکلات خودشان هستند؛ در استایل های inline نمی توان از pseudo-selector ها (مثل hover) یا media query ها استفاده کرد و در فایل های CSS نیز استایل هایمان scope خود را از دست داده و روی تمام پروژه اعمال می شوند.
  • راه حل برای استایل های inline استفاده از کتابخانه هایی مثل Radium بوده و راه حل استفاده از فایل های CSS نیز استفاده از یک پکیج (مربوط به webpack) به نام CSS Loader است که در مورد هر دوی آن ها به صورت مفصل صحبت کردیم.
  • حتما توجه کنید که در ورژن های جدید create-react-app نیازی به eject کردن پروژه و ایجاد تغییرات در پیکربندی نیست. تیم توسعه دهنده قابلیت استفاده از CSS Modules را به صورت عادی فراهم کرده است. برای مطالعه بیشتر می توانید به این صفحه GitHub مراجعه کرده و از انواع مثال های آن دیدن کنید.

با پایان این فصل باید توانایی کامل در استایل دهی عناصر react را یاد گرفته باشید.

دانلود کدهای این فصل

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری دوره جامع آموزش ری اکت توصیه می‌کند:
نویسنده شوید
دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.