طراحی ریسپانسیو با CSS

Learn Responsive Web Design with CSS

11 اردیبهشت 1401
learn-resposive-web-design-with-css

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

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

با گذشت زمان، صفحه نمایش های در اندازه های مختلف برای دستگاه های مختلف در دسترس قرار گرفتند. از آن زمان به بعد مفهوم طراحی وب واکنشگرا (RWD) به وجود آمد. RWD مجموعه ای از روش هایی است که به صفحه های وب اجازه می دهد تا طرح و ظاهر خود را مطابق با اندازه صفحه نمایش های مختلف تغییر دهند. این روش برای وقتی است که وب سایت ما قرار ما باشد در دستگاه های مختلف با اندازه های مختلف نمایش داده شود. پس از گفته ها بالا می توان نتیجه گرفت که طراحی واکنش گرا یعنی این که وب سایت به تغییر اندازه صفحه نمایش واکنش دهد و متناسب با آن چیدمان اجزای سایت تغییر کند.

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

  1. شما می توانستید یک سایت روان ایجاد کنید که همه فضای پنجره مرورگر را پر کند.
  2. یک سایت ثابت بسازید.

این دو رویکرد تنها باعث می شد که  وب سایت طراحی شده تنها در دستگاه برنامه نویس به بهترین شکل به نظر برسد و در دستگاه های دیگر ظاهر خوبی نداشته باشد.

سایت های روان (liquid) سایت های هستند که در دستگاه های کوچک ظاهری به هم ریخته و در دستگاه های بزرگ در خطوط طولانی غیرقابل خواندن ظاهر می شوند.

سایت روان
سایت روان

توجه: برای روشن شدن مطلب این لینک را ببینید. هنگام مشاهده مثال، پنجره مرورگر خود را به داخل و خارج بکشید و آن را تغییر سایز دهید تا ببینید در اندازه های مختلف چگونه به نظر می رسد. سورس کد آن را می توانید در این لینک ببینید.

همان طور که در زیر مشاهده می کند در یک سایت با عرض ثابت، یک نوار اسکرول افقی روی صفحه نمایش های کوچک تر از طول سایت ایجاد می شود. در صفحه های بزرگ تر فضای سفید زیادی در لبه های صفحه به وجود می آید.

سایت ثابت
سایت ثابت

توجه: این لینک را ببینید. با تغییر اندازه پنجره مرورگر، دوباره نتیجه را مشاهده کنید.

توجه: اسکرین شات های بالا با استفاده از Responsive Design Mode در ابزار توسعه فایرفاکس گرفته شده اند.

در گذشته شرکت هایی که تمایل داشتند خدمات خود را از طریق تلفن همراه ارائه دهند معمولا یک نسخه ویژه از سایت خود را با URL متفاوتی ایجاد می کردند مانند m.example.com یا example.mobi. این به این معنی بود که دو نسخه جداگانه باید از سایت ساخته و به روز می شد.

یک مثال از طراحی واکنش گرا را در کد زیر می بینید:

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
* {
  box-sizing: border-box;
}

.row::after {
  content: "";
  clear: both;
  display: table;
}

[class*="col-"] {
  float: left;
  padding: 15px;
}

html {
  font-family: "Lucida Sans", sans-serif;
}

.header {
  background-color: #9933cc;
  color: #ffffff;
  padding: 15px;
}

.menu ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
}

.menu li {
  padding: 8px;
  margin-bottom: 7px;
  background-color: #33b5e5;
  color: #ffffff;
  box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
}

.menu li:hover {
  background-color: #0099cc;
}

.aside {
  background-color: #33b5e5;
  padding: 15px;
  color: #ffffff;
  text-align: center;
  font-size: 14px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
}

.footer {
  background-color: #0099cc;
  color: #ffffff;
  text-align: center;
  font-size: 12px;
  padding: 15px;
}

/* For mobile phones: */
[class*="col-"] {
  width: 100%;
}

@media only screen and (min-width: 600px) {
  /* For tablets: */
  .col-s-1 {width: 8.33%;}
  .col-s-2 {width: 16.66%;}
  .col-s-3 {width: 25%;}
  .col-s-4 {width: 33.33%;}
  .col-s-5 {width: 41.66%;}
  .col-s-6 {width: 50%;}
  .col-s-7 {width: 58.33%;}
  .col-s-8 {width: 66.66%;}
  .col-s-9 {width: 75%;}
  .col-s-10 {width: 83.33%;}
  .col-s-11 {width: 91.66%;}
  .col-s-12 {width: 100%;}
}
@media only screen and (min-width: 768px) {
  /* For desktop: */
  .col-1 {width: 8.33%;}
  .col-2 {width: 16.66%;}
  .col-3 {width: 25%;}
  .col-4 {width: 33.33%;}
  .col-5 {width: 41.66%;}
  .col-6 {width: 50%;}
  .col-7 {width: 58.33%;}
  .col-8 {width: 66.66%;}
  .col-9 {width: 75%;}
  .col-10 {width: 83.33%;}
  .col-11 {width: 91.66%;}
  .col-12 {width: 100%;}
}
</style>
</head>
<body>

<div class="header">
  <h1>Chania</h1>
</div>

<div class="row">
  <div class="col-3 col-s-3 menu">
    <ul>
      <li>The Flight</li>
      <li>The City</li>
      <li>The Island</li>
      <li>The Food</li>
    </ul>
  </div>

  <div class="col-6 col-s-9">
    <h1>The City</h1>
    <p>Chania is the capital of the Chania region on the island of Crete. The city can be divided in two parts, the old town and the modern city.</p>
  </div>

  <div class="col-3 col-s-12">
    <div class="aside">
      <h2>What?</h2>
      <p>Chania is a city on the island of Crete.</p>
      <h2>Where?</h2>
      <p>Crete is a Greek island in the Mediterranean Sea.</p>
      <h2>How?</h2>
      <p>You can reach Chania airport from all over Europe.</p>
    </div>
  </div>
</div>

<div class="footer">
  <p>Resize the browser window to see how the content respond to the resizing.</p>
</div>

</body>
</html>

مشاهده خروجی در JSBin

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

طراحی واکنش گرا (Responsive Design)

اصطلاح طراحی واکنش گرا توسط «ایتان مارکوت» در سال 2010 ابداع شد و استفاده از سه روش ترکیبی را در مطرح کرد.

  1. اولین روش ایده fluid grids (شبکه های روان) است. می‌توان آن را در مقاله Fluid Grids که در سال 2009 منتشر شده است خواند.
  2. روش دوم ایده fluid images (تصاویر روان) بود. با استفاده از یک تکنیک بسیار ساده برای تنظیم ویژگی max-width روی 100٪، اگر اندازه ستونی که حاوی تصویرها است از اندازه واقعی تصویر کم تر شود، تصاویر کوچک تر می شوند، ولی بزرگتر نمی شوند. این کار باعث می‌شود یک تصویر کوچک شود تا در یک ستون قرار بگیرد و از آن بیرون نزند. اگر ستون از تصویر عریض‌تر شود تصویر بزرگ‌ و پیکسلی نمی شود.
  3. سومین روش استفاده از media query بود. media query، نوع طرح‌بندی را که کامرون آدامز قبلا با استفاده از جاوا اسکریپت و فقط با استفاده از CSS بررسی کرده بود، فعال می‌کند. به جای داشتن یک طرح برای همه اندازه‌های صفحه، طرح‌بندی را می‌توان تغییر داد. نوارهای کناری را می توان برای صفحه کوچک تر تغییر مکان داد، یا می توان navigation را به کار برد.

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

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

viewport چیست؟

viewport قسمتی از صفحه است که کاربر آن را می بیند. ممکن است با خودتان بگویید مگر کاربر تمام صفحه را نمیبیند؟ منظور ما صفحه وب است نه صفحه نمایشگر! به تصویر زیر نگاه کنید:

viewport
viewport

همان طور که می بینید هر دستگاه بر اساس سایز صفحه خودش، قسمتی از صفحه وب را می بیند. به طور مثال دستگاه سمت راست قسمتی از تصویر منظره در صفحه ما را نمی بیند. بنابراین به قسمتی که دیده می شود viewport می گوییم.

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

خوشبختانه در HTML5 توسعه دهندگان اجازه کنترل viewport را دارند. برای این کار باید با یکی از تگ های <meta> کار کنیم:

<meta name="viewport" content="width=device-width, initial-scale=1.0">

این تگ متا به شما اجازه می دهد که نحوه بزرگنمایی و ابعاد صفحه را کنترل کنید. قسمت width=device-width یعنی طول صفحه مطابق با طول نمایشگر کاربر باشد (یعنی بر اساس سایز صفحه تغییر کند). قسمت initial-scale=1.0 نیز برای تعیین بزرگنمایی اولیه است. اگر این مقدار بیشتر از 1 باشد، پس از آن که مرورگر صفحه وب را بارگذاری کرد به همان نسبت در صفحه زوم می کند.

در قسمت زیر دو مثال آورده ایم و در یکی از آن ها تگ meta را قرار داده ایم. تفاوت آن ها را ببینید:

مثال اول - بدون تگ viewport

<!DOCTYPE html>
<html>
<body>
<p><b>To understand this example, you should open this page on a phone or a tablet.</b></p>

<img src="https://www.w3schools.com/css/img_chania.jpg" alt="Chania" width="460" height="345">

<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum.
Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum.
</p>

</body>
</html>

مشاهده خروجی در JSBin

برای درک تفاوت بین این دو مثال باید به صفحه خروجی این دو کد رفته و با کوچک و بزرگ کردن صفحه متوجه تغییر تصاویر بشوید.

Media Query

طراحی واکنش گرا تنها به خاطر media query بود که توانست به وجود آید. media query ها به ما اجازه می‌دهند تا مجموعه‌ای از آزمایش‌ها را اجرا کنیم و CSS را به‌ طور انتخابی اعمال کنیم تا به این ترتیب صفحه متناسب با نیازهای کاربر استایل دهی شود.

به عنوان نمونه، media query زیر بررسی می کند که آیا صفحه وب فعلی به عنوان screen نمایش داده می شود و viewport حداقل 800 پیکسل طول دارد. CSS برای container فقط در صورتی اعمال می‌شود که این دو شرط درست باشند یعنی صفحه وب screen و viewport حداقل 800 پیکسل طول داشته باشد.

@media screen and (min-width: 800px) {
  .container {
    margin: 1em 2em;
  }
}

می‌توان چندین media query را در یک صفحه به کار برد. می توانید کل طرح‌ یا بخش‌هایی از آن را برای اندازه‌های مختلف صفحه تغییر دهید. نقاطی که media query در آن ها تعریف می شود و طرح در آن ها تغییر می کند، به عنوان breakpoints (نقاط شکست) شناخته می شوند.

یک رویکرد رایج هنگام استفاده از Media Query ها این است که ابتدا یک تک ستون ساده برای دستگاه‌هایی با صفحه نمایش باریک (مثلا تلفن‌های همراه) ایجاد کنید، سپس برای صفحه‌های بزرگ‌ تر Media Query را بررسی و اعمال کنید و زمانی که مطمئن شویم طول کافی داریم، سراغ طرح چند ستونی می رویم.

Gridهای انعطاف پذیر

سایت‌های واکنش‌گرا فقط از نقاط شکست برای تغییر استایل خود استفاده نمی کنند، بلکه بر اساس grid های انعطاف‌پذیر نیز ساخته شده‌اند. یک grid انعطاف پذیر به این معنی است که شما نیازی به تنظیم اندازه برای دستگاه مختلف ندارید، تا یک طرح پیکسلی عالی برای آن بسازید. با توجه به تعداد زیاد دستگاه‌ها با اندازه‌های مختلف و این واقعیت که حداقل در دسکتاپ، افراد همیشه پنجره مرورگر خود را به حداکثر نمی‌رسانند، این رویکرد غیرممکن خواهد بود.

با استفاده از یک grid انعطاف پذیر، فقط باید یک (break-point) اضافه کنید و طراحی را در نقطه ای که محتوا شروع به بد به نظر رسیدن می کند، تغییر دهید. به عنوان مثال، اگر با افزایش اندازه صفحه، طول خطوط به طور غیرقابل خواندن طولانی شود و غیره.

در نخستین روزهای طراحی واکنشگرا، تنها گزینه ما برای اجرای چیدمان استفاده از float ها بود. طرح‌بندی‌های float انعطاف‌پذیر با افزودن درصد به width هر عنصر و اطمینان از این که کل طرح‌بندی بیش از 100 درصد نباشد، به دست آمده اند.

به عنوان مثال، اگر اندازه ستون مورد نظر ما 60 پیکسل باشد، و context یا container آن 960 پیکسل باشد، 60 را بر 960 تقسیم می کنیم تا مقداری را که می خواهیم در CSS خود استفاده کنیم، به دست آوریم. سپس ممیز را دو نقطه به راست انتقال می دهیم.

.col {
  width: 6.25%; /* 60 / 960 = 0.0625 */
}

مثال زیر یک طراحی ساده responsive را با استفاده از Media Query ها و یک grid انعطاف پذیر نشان می دهد. تصویر زیر در صفحه‌های باریک، طرح‌بندی کادرهایی را که روی هم چیده شده‌اند نشان می‌دهد:

Media Query و grid
Media Query و grid

در صفحات بزرگ تر، آن ها به دو ستون تبدیل می شوند:

multi-col
multi-col

کد کامل مثال بالا را می توانید در نشانی ببینید. اجرای زنده تصویر بالا را می توانید در لینک ببینید.

فناوری های layout (چیدمان) مدرن

روش های چیدمان مدرن مانند طرح چند ستونی (Multiple-column layoutFlexbox و Grid به طور پیش فرض واکنش گرا هستند. همه آن ها تصور می کنند که شما در حال ایجاد یک grid انعطاف پذیر هستید و راه های آسان تری برای این کار به شما ارائه می دهند.

چند ستونه (Multicol)

قدیمی‌ترین روش طرح‌بندی وب روش چند ستونه است.وقتی column-count را مشخص می‌کنید، نشان می‌دهد که می‌خواهید محتوای شما به چند ستون تقسیم شود. سپس مرورگر اندازه آن ها را تعیین می کند، اندازه ای که با توجه به اندازه صفحه نمایش تغییر می کند.

.container {
  column-count: 3;
}

اگر column-width را مشخص کنید، شما حداقل اندازه width را مشخص کرده اید. مرورگر به تعداد width ستون‌ ایجاد می‌کند و به این ترتیب به راحتی در container قرار می‌گیرند، سپس فضای باقی‌مانده را بین تمام ستون‌ها به اشتراک می‌گذارد. بنابراین تعداد ستون ها با توجه به فضای موجود تغییر می کند.

.container {
  column-width: 10em;
}

Flexbox

در Flexbox، آیتم های flex فضا را بین المنت ها، با توجه به فضای موجود در کانتینر کوچک و تقسیم می کنند.با تغییر مقادیر flex-grow و flex-shrink می‌توانید نشان دهید که در هنگام مواجهه با فضای کمتر یا بیشتر در صفحه چگونه رفتار کند. در مثال زیر، آیتم‌های flex، هر کدام فضای برابر را در کانتینر flex با استفاده از کد flex: 1 اشغال می‌کنند.

.container {
  display: flex;
}

.item {
  flex: 1;
}

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

CSS grid

در طراحی با استفاده از CSS Grid واحد fr امکان تقسیم کردن فضای موجود در مسیرهای شبکه یا grid را نشان می دهد. مثال بعدی یک کانتینر grid با سه مسیر به اندازه 1fr ایجاد می کند. این مثال سه ستون را ایجاد می کند که هر کدام یک قسمت از فضای موجود در کانتینر را اشغال می کنند. برای به دست آوردن اطلاعات بیشتر در این مورد می توانید این مقاله را بخوانید.

.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}

برای یادگیری بیش تر می توانید این کد یا این مثال را ببینید.

تصاویر واکنش گرا (ریسپانسیو)

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

img {
  max-width: 100%;
}

این رویکرد معایبی نیز دارد. تصویر ممکن است بسیار کوچک تر از اندازه واقعی آن نمایش داده شود، که باعث اتلاف پهنای باند می شود.با استفاده از این روش یک کاربر تلفن همراه ممکن است تصویری را که چندین برابر اندازه واقعی آن است دانلود کند. علاوه بر این، ممکن است نسبت تصویری را که در موبایل به آن نیاز داریم در دسکتاپ نیازی به  آن نداشته باشیم. برای مثال، ممکن است بهتر باشد که برای موبایل یک تصویر مربعی داشته باشیم، ولی برای دسکتاپ بهتر است که همان تصویر را به صورت یک تصویر افقی نشان دهیم. این چیزها را نمی توان با scale کردن یک تصویر به دست آورد.

تصاویر واکنش‌گرا با استفاده از المنت های picture و img و ویژگی‌های srcset و sizes هر دو این مشکلات را حل می‌کنند. می‌توانید چندین اندازه را همراه با hint ها ارائه کنید (داده‌های متا که اندازه صفحه‌نمایش و وضوح تصویر را توصیف می‌کند) و مرورگر مناسب‌ترین تصویر را برای هر دستگاه انتخاب می‌کند و اطمینان می‌دهد که کاربر تصویر را با اندازه مناسب دانلود می‌کند.

می‌توانید راهنمای دقیقی برای تصاویر واکنش‌گرا را در MDN پیدا کنید.

تایپوگرافی (شکل نگاری) ریسپانسیو

یکی از عناصر طراحی واکنشگرا که در کارهای قبلی پوشش داده نشده بود، ایده تایپوگرافی واکنشگرا بود. تغییر اندازه فونت در media query ها برای نشان دادن مقادیر کمتر یا بیشتر از اندازه واقعی صفحه نمایش، توصیف می شود.

در مثال زیر، می‌خواهیم h1 موجود در media query خود را برابر 4rem  قرار بدهیم، یعنی چهار برابر اندازه فونت پایه باشد. این heading واقعا بزرگ است. این heading  با این اندازه بزرگ را تنها در صفحه نمایش های بزرگ می‌خواهیم نمایش دهیم، بنابراین ابتدا یک heading کوچک‌تر ایجاد می‌کنیم، سپس از media query ها برای بازنویسی آن با اندازه بزرگ‌تر استفاده می‌کنیم. اگر بدانیم صفحه نمایش دارای اندازه حداقل 1200 پیکسل است این media query اجرا می شود.

html {
  font-size: 1em;
}

h1 {
  font-size: 2rem;
}

@media (min-width: 1200px) {
  h1 {
    font-size: 4rem;
  }
}

در تلفن همراه تصویر بالا به صورت زیر به نظر می رسد:

تایپوگرافی رسپانسیو
تایپوگرافی ریسپانسیو

در دسکتاپ تصویر زیر را خواهیم دید که اندازه heading در آن بزرگ تر می شود.

تایپوگرافی در دسکتاپ
تایپوگرافی در دسکتاپ

توجه: می توانید کد و این مثال را در عمل ببینید.

استفاده از viewport برای تایپوگرافی ریسپانسیو

یک رویکرد جالب این است که از یکی از واحدهای viewport به نام vw برای فعال کردن تایپوگرافی ریسپانسیو استفاده کنید. 1vw برابر با یک درصد از width ویوپورت است، به این معنی که اگر اندازه فونت خود را با استفاده از vw تنظیم کنید، همیشه با اندازه ویوپورت مرتبط خواهد شد یا به عبارت دیگر به اندازه آن وابسته می شود.

h1 {
  font-size: 6vw;
}

مشکل کد بالا این است که کاربر توانایی بزرگنمایی هر متنی را با استفاده از واحد vw از دست می دهد، زیرا اندازه آن متن همیشه به اندازه ویوپورت مربوط می شود. بنابراین هرگز نباید متن را تنها با استفاده از واحدهای viewport تنظیم کنید.

راه حل این مشکل استفاده از ()calc است. اگر واحد vw را با استفاده از اندازه ثابتی مانند ems یا rems به مجموعه مقادیر اضافه کنید، متن هم چنان قابل بزرگنمایی خواهد بود. واحد vw به این مقدار اضافه می شود:

h1 {
  font-size: calc(1.5rem + 3vw);
}

این به این معنی است که فقط یک بار باید اندازه فونت را برای heading  مشخص کنیم، نه این که دوباره آن را درmedia query تعریف کنیم. سپس با افزایش اندازه ویوپورت، فونت به تدریج افزایش می یابد.

توجه: نمونه ای از این مثال را در عمل ببینید. کد دراین لینک موجود است.

متا تگ viewport

اگر به کد HTML یک صفحه ریسپانسیو نگاه کنید، معمولا تگ meta زیر را در تگ head  خواهید دید.

<meta name="viewport" content="width=device-width,initial-scale=1">

این متا تگ به مرورگرهای تلفن همراه می‌گوید که طول viewport را باید براساس طول دستگاه تنظیم کنند و document را تا 100% اندازه مورد نظر خود scale کنند، که document را در اندازه بهینه‌سازی شده برای موبایل که مد نظر شماست نشان می‌دهد.

این متا تگ به این دلیل وجود دارد که وقتی آیفون اصلی وارد بازار شد و مردم شروع به دیدن وب‌سایت‌ها بر روی یک صفحه تلفن کوچک کردند، بیش تر این سایت‌ها برای موبایل بهینه‌سازی نشده بودند. بنابراین، مرورگر تلفن همراه، طول viewport را روی 960 پیکسل تنظیم می‌کند، صفحه را برای آن طول نمایش می دهد و نتیجه را به‌عنوان یک نسخه کوچک‌شده از دسک‌تاپ نشان می‌دهد. سایر مرورگرهای تلفن همراه مانند Google Android  همین کار را انجام می دهند.

مشکل این است که طراحی ریسپانسیو شما با breakpoint ها و media query ها آن طور که در نظر گرفته شده در مرورگرهای تلفن همراه کار نمی کند. اگر صفحه نمایش باریکی دارید که دارای طول ویوپورت 480 پیکسل یا کمتر است، و ویوپورت سایت در 960 پیکسل تنظیم شده است، صفحه وب را در تلفن همراه نخواهید دید. با تنظیم width=device-width، طول پیش‌فرض Apple که 960px است را لغو می‌کنید، و media query های شما همان طور که در نظر گرفته شده است کار خواهند کرد.

تنظیمات دیگری وجود دارد که می توانید با متا تگ viewport استفاده کنید، اما معمولا خط بالا را استفاده خواهیم کرد.

  • initial-scale: بزرگنمایی (zoom) اولیه صفحه را تنظیم می کند.
  • height: ارتفاع مشخصی را برای viewport تعیین می کند.
  • minimum-scale: حداقل میزانzoom  را تنظیم می کند.
  • maximum-scale: حداکثر میزانzoom  را تنظیم می کند.
  • user-scalable: اگر با no مقداردهی شود از بزرگنمایی جلوگیری می کند.

شما باید از استفاده از minimum-scale، maximum-scale، و به ویژه مقداردهی user-scalable با no خودداری کنید. باید به کاربران اجازه داده شود تا به همان اندازه که نیاز دارند بزرگنمایی کنند. جلوگیری از این امر باعث مشکلات دسترسی می شود.

برخی از قوانین طراحی واکنش گرا

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

قوانین دیگر در طراحی واکنش گرا به طور خلاصه عبارت اند از:

  • از عناصر بزرگ با عرض ثابت استفاده نکنید: به طور مثال اگر تصویری بزرگ تر از viewport باشد باعث می شود صفحه ما اسکرول افقی بخورد بنابراین همیشه عرض عناصر خود را تنظیم کنید.
  • عناصر را وابسته به Viewport نکنید: وابستگی عناصر به viewport برای نمایش صحیح کار بسیار اشتباهی است. از آن جا که سایز صفحات و تعداد پیکسل های آن ها بین دستگاه های مختلف اختلاف شدیدی دارد نباید نمایش صحیح عناصر خود را وابسته به Viewport خاصی کنیم، بلکه باید هر عنصری برای هر صفحه ای نمایش داده شود.
  • از Media Query ها برای ایجاد استایل های متفاوت در عرض های متفاوت استفاده کنید: قبلا در مورد Media Query ها صحبت کرده ایم. اگر در این مورد اطلاعی ندارید به قسمت قبل مراجعه کنید.
  • به جای استفاده از واحدهای ثابت از واحدهای نسبی استفاده کنید: واحد های نسبی مانند درصد (%) به انعطاف پذیری صفحات شما کمک می کنند، مخصوصا زمانی که مربوط به موقعیت دهی (positioning) باشند.

یادگیری با پروژه

برای یادگیری بیش تر بهتر است که یک پروژه کوچک را با یکدیگر پیاده کنیم. در این پروژه یک لاگین فرم ریسپانسیو خواهیم ساخت.تصویر پروژه در زیر آمده است:

طراحی رسپانسیو
طراحی ریسپانسیو

ساختار پروژه

ابتدا یک پوشه با نام responsive-desgin ایجاد خواهیم کرد.برای شروع تنها به دو فایل index.html و style.css و یک پوشه img نیاز داریم. نیاز داریم.پس آن ها را خواهیم ساخت:

ساختار پروژه
ساختار پروژه

در پوشه img تصاویر زیر را داریم:

تصاویر پروژه
تصاویر پروژه

تصاویر استفاده شده در این پروژه را می توانید از این نشانی دانلود کنید.

فایل index.html

فایل کامل index.html در زیر آمده است:

<!DOCTYPE html>
<html>
<head>
    <title>Animated Login Form</title>
    <link rel="stylesheet" type="text/css" href="style.css">
    <link href="https://fonts.googleapis.com/css?family=Poppins:600&display=swap" rel="stylesheet">
    <script src="https://kit.fontawesome.com/a81368914c.js"></script>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
    <img class="wave" src="img/wave.png">
    <div class="container">
        <div class="img">
            <img src="img/bg.svg">
        </div>
        <div class="login-content">
            <form action="index.html">
                <img src="img/avatar.svg">
                <h2 class="title">Welcome</h2>
           		<div class="input-div one">
           		   <div class="i">
           		   		<i class="fas fa-user"></i>
           		   </div>
           		   <div class="div">
           		   		<h5>Username</h5>
           		   		<input type="text" class="input">
           		   </div>
           		</div>
           		<div class="input-div pass">
           		   <div class="i"> 
           		    	<i class="fas fa-lock"></i>
           		   </div>
           		   <div class="div">
           		    	<h5>Password</h5>
           		    	<input type="password" class="input">
            	   </div>
            	</div>
            	<a href="#">Forgot Password?</a>
            	<input type="submit" class="btn" value="Login">
            </form>
        </div>
    </div>
</body>
</html>

برای یک طراحی واکنش گرا در تگ head از تگ meta زیر استفاده کرده ایم:

<meta name="viewport" content="width=device-width, initial-scale=1">

Viewport ناحیه قابل مشاهده کاربر از یک صفحه وب است. Viewport بسته به دستگاه متفاوت است و در تلفن همراه کوچک تر از صفحه نمایش رایانه خواهد بود.

HTML5 روشی را معرفی کرد که به طراحان وب اجازه می‌دهد از طریق تگ meta کنترل Viewport را در دست بگیرند.این تگ به مرورگر دستورالعمل هایی در مورد نحوه کنترل ابعاد و مقیاس صفحه می دهد.قسمت width=device-width طول صفحه را طوری تنظیم می کند که از طول صفحه دستگاه پیروی کند (که بسته به دستگاه متفاوت است).

زمانی که صفحه برای اولین بار توسط مرورگر بارگیری می شود، قسمت initial-scale=1.0 میزان بزرگنمایی اولیه را تعیین می کند.در ادامه قسمت body تگ img با کلاس wave و تگ div با کلاس container را داریم.در تگ div فرم خود را می سازیم و کلاس های مناسب را برای آن در نظر می گیریم.

تگ div با کلاس container خود از دو تگ div با دیگر تشکیل شده است.کلاس تگ اول img و کلاس تگ دوم loign-content است.

اکنون سراغ فایل style.css می رویم.

فایل style.css

فایل کامل style.css در زیر آمده است:

*{
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}

body{
    font-family: 'Poppins', sans-serif;
    overflow: hidden;
}

.wave{
    position: fixed;
    bottom: 0;
    left: 0;
    height: 100%;
    z-index: -1;
}

.container{
    width: 100vw;
    height: 100vh;
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    grid-gap :7rem;
    padding: 0 2rem;
}

.img{
    display: flex;
    justify-content: flex-end;
    align-items: center;
}

.login-content{
    display: flex;
    justify-content: flex-start;
    align-items: center;
    text-align: center;
}

.img img{
    width: 500px;
}

form{
    width: 360px;
}

.login-content img{
    height: 100px;
}

.login-content h2{
    margin: 15px 0;
    color: #333;
    text-transform: uppercase;
    font-size: 2.9rem;
}

.login-content .input-div{
    position: relative;
    display: grid;
    grid-template-columns: 7% 93%;
    margin: 25px 0;
    padding: 5px 0;
    border-bottom: 2px solid #d9d9d9;
}

.login-content .input-div.one{
    margin-top: 0;
}

.i{
    color: #d9d9d9;
    display: flex;
    justify-content: center;
    align-items: center;
}

.i i{
    transition: .3s;
}

.input-div > div{
    position: relative;
    height: 45px;
}

.input-div > div > h5{
    position: absolute;
    left: 10px;
    top: 50%;
    transform: translateY(-50%);
    color: #999;
    font-size: 18px;
    transition: .3s;
}

.input-div:before, .input-div:after{
    content: '';
    position: absolute;
    bottom: -2px;
    width: 0%;
    height: 2px;
    background-color: #38d39f;
    transition: .4s;
}

.input-div:before{
    right: 50%;
}

.input-div:after{
    left: 50%;
}

.input-div.focus:before, .input-div.focus:after{
    width: 50%;
}

.input-div.focus > div > h5{
    top: -5px;
    font-size: 15px;
}

.input-div.focus > .i > i{
    color: #38d39f;
}

.input-div > div > input{
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    border: none;
    outline: none;
    background: none;
    padding: 0.5rem 0.7rem;
    font-size: 1.2rem;
    color: #555;
    font-family: 'poppins', sans-serif;
}

.input-div.pass{
    margin-bottom: 4px;
}

a{
    display: block;
    text-align: right;
    text-decoration: none;
    color: #999;
    font-size: 0.9rem;
    transition: .3s;
}

a:hover{
    color: #38d39f;
}

.btn{
    display: block;
    width: 100%;
    height: 50px;
    border-radius: 25px;
    outline: none;
    border: none;
    background-image: linear-gradient(to right, #32be8f, #38d39f, #32be8f);
    background-size: 200%;
    font-size: 1.2rem;
    color: #fff;
    font-family: 'Poppins', sans-serif;
    text-transform: uppercase;
    margin: 1rem 0;
    cursor: pointer;
    transition: .5s;
}
.btn:hover{
    background-position: right;
}


@media screen and (max-width: 1050px){
    .container{
        grid-gap: 5rem;
    }
}

@media screen and (max-width: 1000px){
    form{
        width: 290px;
    }

    .login-content h2{
        font-size: 2.4rem;
        margin: 8px 0;
    }

    .img img{
        width: 400px;
    }
}

@media screen and (max-width: 900px){
    .container{
        grid-template-columns: 1fr;
    }

    .img{
        display: none;
    }

    .wave{
        display: none;
    }

    .login-content{
        justify-content: center;
    }
}

در فایل بالا استایل برنامه خود را تعریف می کنیم.اولین media query خود را به صورت زیر تعریف می کنیم.

@media screen and (max-width: 1050px){
    .container{
        grid-gap: 5rem;
    }
}

در این media query دو شرط بررسی می شود. screen برای بررسی این که آیا صفحه نمایش کامپیوتر، تبلت، تلفن های هوشمند و غیره است، استفاده می شود. شرط دوم بررسی می کند آیا اندازه صفحه نمایش حداکثر 1050px است یا نه. اگر این دو شرط برقرار بودند آن گاه کد مربوط به media query اجرا می شود. اگر حداکثر اندازه صفحه نمایش 1050px یا کم تر باشد (یا بیش تر از 1050px باشد) تصویر نمایش داده می شود.

دومین media query خود را به صورت زیر تعریف می کنیم.

@media screen and (max-width: 1000px){
    form{
        width: 290px;
    }

    .login-content h2{
        font-size: 2.4rem;
        margin: 8px 0;
    }

    .img img{
        width: 400px;
    }
}

در media query بالا دوباره دو شرط گذشته بررسی می شود. شرط screen همان شرط پیشین خواهد بود ولی شرط دوم بررسی می کند آیا اندازه صفحه نمایش حداکثر 1000px است یا نه.اگر این دو شرط برقرار بودند آن گاه کد مربوط به media query اجرا می شود.اگر حداکثر اندازه صفحه نمایش 1000px یا کمتر باشد (ولی بزرگتر از 900px باشد) تصویر نمایش داده می شود.

سومین media query خود را به صورت زیر تعریف می کنیم.

@media screen and (max-width: 900px){
    .container{
        grid-template-columns: 1fr;
    }

    .img{
        display: none;
    }

    .wave{
        display: none;
    }

    .login-content{
        justify-content: center;
    }
}

در media query آخر نیز دو شرط بررسی می شود. screen مانند شرط های بالا است.شرط دوم بررسی می کند آیا اندازه صفحه نمایش حداکثر 900px است یا نه.اگر این دو شرط برقرار بودند آن گاه کد مربوط به media query اجرا می شود.اگر حداکثر اندازه صفحه نمایش 900px یا کمتر باشد تصویر زیر نمایش داده می شود.

media-query-3

 

با استفاده از dev tool کروم می توانید وب سایت خود را در دستگاه های مختلف ببینید.


منبع: وب سایت mozilla

نویسنده شوید
دیدگاه‌های شما

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