چطور با float و clear در CSS کار کنیم؟

08 اردیبهشت 1398
درسنامه درس 18 از سری صفر تا صد CSS
CSS-float-clear

خاصیت float

float در لغت به معنی «شناور شدن/بودن» است. از این خاصیت برای موقعیت دهی به عناصر مختلف صفحه استفاده می شود و یکی از مقادیر زیر را می گیرد:

  • left: در این حالت عنصر مورد نظر به سمت چپ نگه دارنده اش1 (container) می رود یا به قولی در سمت چپ شناور می شود
  • right: در این حالت عنصر مورد نظر به سمت راست نگه دارنده اش (container) می رود یا به قولی در سمت راست شناور می شود
  • none: در این حالت عنصر مورد نظر اصلا شناور نمی شود و همان جایی که هست می ماند (حالت پیش فرض همین مورد است)
  • inherit: در این حالت عنصر مورد نظر مقدار float را از عنصر پدرش به ارث می برد.

1- منظور از container یا نگه دارنده، همان پدر عنصر است. اگر عنصر x درون عنصرِ y قرار داشته باشد آنگاه عنصر y نگه دارنده یا پدر عنصر x محسوب می شود.

بیایید از هر کدام مثالی بزنیم!

مثال هایی از float

 float: right 

در این مثال می خواهیم به تصویرمان بگوییم که به سمت راست متن برود:

<!DOCTYPE html>
<html>
<head>
<style>
img {
  float: right;
}
</style>
</head>
<body>

<p>In this example, the image will float to the right in the paragraph, and the text in the paragraph will wrap around the image.</p>

<p><img src="https://www.w3schools.com/css/pineapple.jpg" alt="Pineapple" style="width:170px;height:170px;margin-left:15px;">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas odio, vitae scelerisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Mauris ante ligula, facilisis sed ornare eu, lobortis in odio. Praesent convallis urna a lacus interdum ut hendrerit risus congue. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida venenatis. Integer fringilla congue eros non fermentum. Sed dapibus pulvinar nibh tempor porta. Cras ac leo purus. Mauris quis diam velit.</p>

</body>
</html>

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

 float: left 

در این مثال می خواهیم به تصویرمان بگوییم که به سمت چپ متن برود:

<!DOCTYPE html>
<html>
<head>
<style>
img {
  float: left;
}
</style>
</head>
<body>

<p>In this example, the image will float to the left in the paragraph, and the text in the paragraph will wrap around the image.</p>

<p><img src="https://www.w3schools.com/css/pineapple.jpg" alt="Pineapple" style="width:170px;height:170px;margin-right:15px;">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas odio, vitae scelerisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Mauris ante ligula, facilisis sed ornare eu, lobortis in odio. Praesent convallis urna a lacus interdum ut hendrerit risus congue. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida venenatis. Integer fringilla congue eros non fermentum. Sed dapibus pulvinar nibh tempor porta. Cras ac leo purus. Mauris quis diam velit.</p>

</body>
</html>

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

 float: none 

در این مثال به تصویر هیچ دستوری نمی دهیم و می گذاریم به حالت عادی در هر جایی خواست قرار بگیرد. این حالت همان حالت پیش فرض است:

<!DOCTYPE html>
<html>
<head>
<style>
img {
  float: none;
}
</style>
</head>
<body>

<p>In this example, the image will be displayed just where it occurs in the text (float: none;).</p>

<p><img src="https://www.w3schools.com/css/pineapple.jpg" alt="Pineapple" style="width:170px;height:170px;">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas odio, vitae scelerisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Mauris ante ligula, facilisis sed ornare eu, lobortis in odio. Praesent convallis urna a lacus interdum ut hendrerit risus congue. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida venenatis. Integer fringilla congue eros non fermentum. Sed dapibus pulvinar nibh tempor porta. Cras ac leo purus. Mauris quis diam velit.</p>

</body>
</html>

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

خصوصیت clear و مشکل معروف clearfix

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

  • none: عنصری که این مقدار را بگیرد به بقیه ی عناصر اجازه میدهد در کنارش شناور شوند. حالت پیش فرض همین است
  • left: عنصری که این مقدار را بگیرد به بقیه ی عناصر اجازه میدهد تنها در سمت چپ اش شناور شوند
  • right: عنصری که این مقدار را بگیرد به بقیه ی عناصر اجازه میدهد تنها در سمت راست اش شناور شوند
  • both: عنصری که این مقدار را بگیرد به هیچ عنصری در هیچ سمتی اجازه ی شناور شدن نمی دهد
  • inherit: عنصر مورد نظر مقدار clear را از پدرش به ارث می برد

در واقع clear در لغت به معنی «پاک کردن» است. حالا متوجه شدید؟ اگر به عنصری clear بدهیم یعنی می خواهیم اطراف آن را از عناصر شناور پاکسازی کنیم!

ما می توانیم از مقدار clear در موقعیت های مختلفی استفاده کنیم اما شایع ترین استفاده ی آن بعد از دستور float است. کار شما این است که مقدار float را با مقدار clear یکی کنید؛ به طور مثال اگر به float مقدار right داده اید باید به clear هم right بدهید.

<!DOCTYPE html>
<html>
<head>
<style>
.div1 {
  float: left;
  width: 100px;
  height: 50px;
  margin: 10px;
  border: 3px solid #73AD21;
}

.div2 {
  border: 1px solid red;
}

.div3 {
  float: left;
  width: 100px;
  height: 50px;
  margin: 10px;
  border: 3px solid #73AD21;
}

.div4 {
  border: 1px solid red;
  clear: left;
}
</style>
</head>
<body dir='rtl'>

<h2>بدون استفاده از clear</h2>
<div class="div1">div1</div>
<div class="div2">div2 - دقت کنید که در سورس کد HTML عنصر div2 بعد از عنصر div1 آمده است.
اما از آنجایی که div1 به سمت چپ شناور می شود
متن div2 در کنار عنصر div1 قرار می گیرد و مشکلی ندارد.
</div>
<br><br>

<h2>با استفاده از clear</h2>
<div class="div3">div3</div>
<div class="div4">div4 - در این قسمت clear: left را داریم و به همین دلیل

div4 پایین تر از div3 قرار می گیرد. مقدار left برای خاصیت clear بدین معناست که عناصر شناور از سمت چپ را پاک سازی می کند 
به همین دلیل نوشته های این div نمی  توانند کنار نوشته های div3 باشند و به خط بعد منتقل می شوند.
 </div>

</body>
</html>

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

حتما به صفحه ی خروجی این مثال بروید؛ در آنجا توضیحاتی خدمتتان ارائه کرده ام.

تا اینجای کار مشکلی نیست و درک آن ساده است اما حتما مشکل معروف clearfix را شنیده اید! تعریف ساده ی این مشکل در مثال زیر قرار دارد: اگر عنصری از عنصر نگه دارنده (پدرش) بلند تر باشد (از نظر ارتفاع) و همچنین شناور (floated) هم باشد، از عنصر نگه دارنده بیرون می زند. به این تصویر نگاه کنید:

مشکل معروف clearfix - در این مثال عنصر پدر یا نگه دارنده کوچک تر از عنصر فرزند است بنابراین عنصر فرزند از نگه دارنده اش بیرون می زند
مشکل معروف clearfix - در این مثال عنصر پدر یا نگه دارنده کوچک تر از عنصر فرزند است بنابراین عنصر فرزند از نگه دارنده اش بیرون می زند

برای حل این مشکل می توانیم از ;overflow: auto استفاده کنیم. به این مثال توجه کنید:

<!DOCTYPE html>
<html>
<head>
<style>
div {
  border: 3px solid #4CAF50;
  padding: 5px;
}

.img1 {
  float: right;
}

.clearfix {
  overflow: auto;
}

.img2 {
  float: right;
}
</style>
</head>
<body>

<p>In this example, the image is taller than the element containing it, and it is floated, so it overflows outside of its container:</p>

<div>
  <img class="img1" src="https://www.w3schools.com/css/pineapple.jpg" alt="Pineapple" width="170" height="170">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum...
</div>

<p style="clear:right">Add a clearfix class with overflow: auto; to the containing element, to fix this problem:</p>

<div class="clearfix">
  <img class="img2" src="https://www.w3schools.com/css/pineapple.jpg" alt="Pineapple" width="170" height="170">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum...
</div>

</body>
</html>

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

تصحیح این مشکل با استفاده از ;overflow: auto راه حل خوبی است، البته تا زمانی که بتوانید اندازه ی margin و padding هایتان را کنترل کنید. اگر نتوانید این دو را کنترل کنید، صفحه تان اسکرول بار میگیرد و ظاهر زشتی پیدا می کند. به همین خاطر این روش دیگر قدیمی شده است و کسی از آن استفاده نمی کند. به نظر شما راه حل مدرن چیست؟

راه حل مدرن همان clearfix است. به کد زیر نگاهی بیندازید:

<!DOCTYPE html>
<html>
<head>
<style>
div {
  border: 3px solid #4CAF50;
  padding: 5px;
}

.img1 {
  float: right;
}

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

.img2 {
  float: right;
}
</style>
</head>
<body>

<p>In this example, the image is taller than the element containing it, and it is floated, so it overflows outside of its container:</p>

<div>
  <h2>Without Clearfix</h2>
  <img class="img1" src="https://www.w3schools.com/css/pineapple.jpg" alt="Pineapple" width="170" height="170">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum...
</div>

<p style="clear:right">Add the clearfix hack to the containing element, to fix this problem:</p>

<div class="clearfix">
  <h2>With Clearfix</h2>
  <img class="img2" src="https://www.w3schools.com/css/pineapple.jpg" alt="Pineapple" width="170" height="170">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum...
</div>

</body>
</html>

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

در مورد شبه‌عنصرِ after:: در جلسات بعد صحبت خواهیم کرد اما بدانید که راه حل همین است و شما می توانید بدون اینکه دانشی در مورد  after:: داشته باشید از این کد به همین صورتی که در مثال بالا آمده است استفاده کنید.

قابلیت های بیشتر float

با استفاده از خاصیت float می توانیم چندین قسمت مختلف از محتوا را دقیقا کنار هم قرار دهیم و قسمت های هم عرض را به وجود بیاوریم:

<!DOCTYPE html>
<html>
<head>
<style>
* {
  box-sizing: border-box;
}

.box {
  float: left;
  width: 33.33%;
  padding: 50px;
}

.clearfix::after {
  content: "";
  clear: both;
  display: table;
}
</style>
</head>
<body>

<h2>Grid of Boxes</h2>
<p>Float boxes side by side:</p>

<div class="clearfix">
  <div class="box" style="background-color:#bbb">
  <p>Some text inside the box.</p>
  </div>
  <div class="box" style="background-color:#ccc">
  <p>Some text inside the box.</p>
  </div>
  <div class="box" style="background-color:#ddd">
  <p>Some text inside the box.</p>
  </div>
</div>

<p dir='rtl'>

اگر به کدها دقت کنید متوجه خواهید شد که ما از راه حل clearfix استفاده کرده ایم و همچنین از box-sizing نیز بهره گرفته ایم تا مطمئن شویم اندازه ی این قسمت های مختلف و مربعی شکل به خاطر padding و اینطور خصوصیت ها بهم نمیریزد. برای مشاهده ی اثر آنها، می توانید این دو دستور را از کدها حذف کنید.

</p>

</body>
</html>

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

اگر به کدها دقت کنید متوجه خواهید شد که ما از راه حل clearfix استفاده کرده ایم و همچنین از box-sizing نیز بهره گرفته ایم تا مطمئن شویم اندازه ی این قسمت های مختلف و مربعی شکل به خاطر padding و چنین خصوصیت هایی بهم نمیریزد. برای مشاهده ی اثر آنها و تفاوت‌شان با حالت عادی، می توانید این دو دستور را از کدها حذف کنید.

یکی از استفاده های عملی این دستور کنار هم قرار دادن تصاویر مختلف در سایت ها است که حتما آن را در سایت های مختلف مشاهده کرده اید:

<!DOCTYPE html>
<html>
<head>
<style>
* {
  box-sizing: border-box;
}

.img-container {
  float: left;
  width: 33.33%;
  padding: 5px;
}

.clearfix::after {
  content: "";
  clear: both;
  display: table;
}
</style>
</head>
<body>

<h2>Images Side by Side</h2>
<p>Float images side by side:</p>

<div class="clearfix">
  <div class="img-container">
  <img src="https://www.w3schools.com/css/img_5terre.jpg" alt="Italy" style="width:100%">
  </div>
  <div class="img-container">
  <img src="https://www.w3schools.com/css/img_forest.jpg" alt="Forest" style="width:100%">
  </div>
  <div class="img-container">
  <img src="https://www.w3schools.com/css/img_mountains.jpg" alt="Mountains" style="width:100%">
  </div>
</div>

</body>
</html>

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

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

<!DOCTYPE html>
<html>
<head>
<style>
* {
  box-sizing: border-box;
}

.box {
  float: left;
  width: 50%;
  padding: 50px;
  height: 300px;
}

.clearfix::after {
  content: "";
  clear: both;
  display: table;
}
</style>
</head>
<body>

<h2>Equal Height Boxes</h2>
<p>Floating boxes with equal heights:</p>

<div class="clearfix">
  <div class="box" style="background-color:#bbb">
  <h2>Box 1</h2>
  <p>Some content, some content, some content</p>
  </div>
  <div class="box" style="background-color:#ccc">
  <h2>Box 2</h2>
  <p>Some content, some content, some content</p>
  <p>Some content, some content, some content</p>
  <p>Some content, some content, some content</p>
  </div>
</div>

<p dir='rtl'>

این روش اصلا روش خوبی نیست. این راه حل تنها زمانی کار می کند که ما بتوانیم تضمین کنیم که اندازه ی این قسمت ها هیچ گاه تغییر نخواهد کرد. در دنیای واقعی نمی توانیم چنین تضمینی داشته باشیم. به طور مثال اگر کاربری با گوشی موبایل از سایت شما بازدید کند ظاهر سایت به هم خواهد ریخت. برای تست، اندازه ی مرورگر خود را کوچک کنید تا ببینید که محتوای box 2 از محدوده اش بیرون می زند و ظاهر زشتی پیدا می کند.

</p>

</body>
</html>

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

روش بسیار بهتری برای حل این مشکل وجود دارد و آن استفاده از Flexbox است:

<!DOCTYPE html>
<html>
<head>
<style>
.flex-container {
  display: flex;
  flex-wrap: nowrap;
  background-color: DodgerBlue;
}

.flex-container .box {
  background-color: #f1f1f1;
  width: 50%;
  margin: 10px;
  text-align: center;
  line-height: 75px;
  font-size: 30px;
}
</style>
</head>
<body>
<h1>Flexible Boxes</h1>

<div class="flex-container">
  <div class="box">Box 1 - This is some text to make sure that the content gets really tall. This is some text to make sure that the content gets really tall.</div>
  <div class="box">Box 2 - My height will follow Box 1.</div>
</div>

<p>Try to resize the browser window to see the flexible layout.</p>
<p><strong>Note:</strong> Flexbox is not supported in Internet Explorer 10 or earlier versions.</p>

</body>
</html>

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

تنها مشکل Flexbox این است که در مرورگر Internet Explorer 10 و نسخه های قبل تر از آن کار نمی کند چرا که نسبتا جدید بوده و یکی از ویژگی های CSS3 محسوب می شود.

راه حل دیگر استفاده از کتابخانه های Grid در CSS می باشد که می توانید به سادگی با جست و جو در اینترنت آن ها را پیدا کنید.

کمی خلاق تر

با کمی خلاقیت بیشتر می توانیم کار های زیبایی با float انجام دهیم. یکی از آن ها ایجاد منوی سایت ها است:

<!DOCTYPE html>
<html>
<head>
<style>
ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
  overflow: hidden;
  background-color: #333;
}

li {
  float: left;
}

li a {
  display: inline-block;
  color: white;
  text-align: center;
  padding: 14px 16px;
  text-decoration: none;
}

li a:hover {
  background-color: #111;
}

.active {
  background-color: red;
}
</style>
</head>
<body>

<ul>
  <li><a href="#home" class="active">خانه</a></li>
  <li><a href="#news">اخبار</a></li>
  <li><a href="#contact">تماس با ما</a></li>
  <li><a href="#about">درباره ی ما</a></li>
</ul>

</body>
</html>

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

همچنین می توانید طرح کلی یک سایت را با آن پیاده سازی کنید:

<!DOCTYPE html>
<html>
<head>
<style>
* {
  box-sizing: border-box;
}

.header, .footer {
  background-color: grey;
  color: white;
  padding: 15px;
}

.column {
  float: left;
  padding: 15px;
}

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

.menu {
  width: 25%;
}

.content {
  width: 75%;
}

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

.menu li {
  padding: 8px;
  margin-bottom: 8px;
  background-color: #33b5e5;
  color: #ffffff;
}

.menu li:hover {
  background-color: #0099cc;
}
</style>
</head>
<body>

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

<div class="clearfix">
  <div class="column menu">
    <ul>
      <li>The Flight</li>
      <li>The City</li>
      <li>The Island</li>
      <li>The Food</li>
    </ul>
  </div>

  <div class="column content">
    <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>
    <p>You will learn more about web layout and responsive web pages in a later chapter.</p>
  </div>
</div>

<div class="footer">
  <p>Footer Text</p>
</div>

</body>
</html>

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

به همین راحتی و با استفاده از خاصیت float می توانیم انواع نقشه ها را در صفحات وب خودمان پیاده سازی کنیم. امیدوارم از این قسمت لذت برده باشید.

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

دیدگاه‌های شما (3 دیدگاه)

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

علی
14 تیر 1399
سلام فکر کنم توضیحات clear رو اشتباه نوشتید لطفا اصلاح کنید. clear : left یعنی فقط به عناصر اجازه میده در سمت راستش قرار بگیرند نه سمت چپش برعکسش هم همینه

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

FRT
09 آذر 1398
خیلی خوبهههه واقعا ممنون قابل فهم و روان توضیح داده شده ، مخصوصا اون قطعه کدهای جالبی که معمولا اخر آموزش میزارید خیلی جالبه فقط ای کاش این آموزش ها رو به صورت Pdf هم بزارید که بتونیم هربار که لازم شد(درصورت نبود اینترنت) ازش استفاده کنیم

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

امیر زوارمی
13 آذر 1398
سلام دوست عزیز شما می تونید با ابزار هایی مثل وب سایت های زیر یا افزونه هاشون، صفحات وب سایت ها رو به pdf تبدیل کنین و راحت به صورت offline داشته باشید: https://webpagetopdf.com/ https://www.web2pdfconvert.com/ https://www.pdfconvertonline.com/web-to-pdf-online.html بازم من سعی می کنم از این به بعد برای آموزش هایی که مطالبشون زیاده از فایل pdf هم استفاده کنم.

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

شایان
10 اردیبهشت 1398
آقا دمت گرم من کلی دنبال این clearfix بودم پیدا نمیشد از خدا بی خبر :)

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

امیر زوارمی
12 اردیبهشت 1398
سلام دوست عزیز، خوشحالم که بهتون کمک کرده!

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