Border-radius и position — всего 2 свойства позволят нам сделать смайлик с зубом )

В предыдущем уроке мы собрали настоящий макет:

 

table_maket1

 

Здесь у нас была кнопка Read more, поговорим для начала о ней.

Раз мы хотим быть модными и красивыми, то нужно дате ей скругленные углы, вот так:

b

Вы не представляете, как мы мучались до появления CSS3!!! Эти скругленные углы были одним большим NOPE (НЕТ!) для любого фронт-ендера при виде дизайна. Приходилось нарезать эти уголки из макета как отдельные картинки, верстать кнопку как 6-ячеечную таблицу, чтобы угловые td содержали картинки уголков. И каждый верстальщик сидел и плакал — ну ПОЧЕМУ нет такого элементарного свойства, как border-radius!?!

Так как спецификации HTML и CSS являются открытыми для всех желающих, то есть — буквально — пишутся людьми всей планеты, то наконец-то мольбы были услышаны и воплощены в жизнь.

Теперь у нас есть свойство border-radius — радиус рамки. Причем сам border может отсутствовать, скругление углов все равно будет работать.

То есть для своей кнопочки мы пишем:

border-radius: 10px;

Новое свойство CSS3 породило целый веер удивительных изобретений кодеров! Самое явное — это появление в вебе КРУГОВ. Вы же заметили, как соцсети и одностраничники перешли на круглые аватарки и картинки в массовом порядке. Отсюда сделайте вывод — тренды в веб-дизайне диктуются не фантазией дизайнеров, а новыми технологиями.

Итак, чтобы сделать круг, достаточно дать радиус скругления БОЛЬШЕ ширины и высоты объекта. Объект при этом должен быть квадратным (одинаковые высота и ширина).

Ближе к делу, мы сейчас напишем через хтмл и цсс такой вот смайлик с зубом:

smile2

 

Для начала выучим свойство CSS — position. Position переводится как позиция (не сложно догадаться). Позиция у элемента может иметь 4 значения:

absolute (абсолютная);

relative (относительная);

static (статичная);

fixed (фиксированная);

 

По умолчанию все элементы имеют позицию static.

Пожалуйста, сразу запомните, чтобы управлять элементом, нужно задать ему какую-то другую позицию вместо статичной. Например, z-index, который позволяет обращаться с элементами в вебе также как со слоями в Фотошопе (!), НЕ работает с  position: static;. Достаточно указать relative, физически элемент никуда не переместится, но станет работать с z-index-ом.

Есть два, на первый взгляд, похожих стиля — absolute и fixed. Для обоих стилей положение объекта задают через координаты top, left, right, bottom (сверху, слева, справа, снизу — сколько дать пикселей или процентов).

Если вы просто поставите элемент на пустой странице и зададите ему position: absolute или  position: fixed, дадите координаты, то при смене absolute на fixed и наоборот — ничего не изменится. Элемент будет стоять там, куда вы его поставили. Разница появляется при отношении этого элемента к другим, то есть — все в мире относительно, а в вебе — относительно друг друга.

Самое элементарное отличие — fixed будет зафиксирован где угодно относительно ОКНА. Он может стоять поперек любого объекта, как раз тут и нужен  z-index, который указывает, стоит этот элемент ПОВЕРХ других или ПОД ними. Чем выше z-index, тем выше «слой» объекта, тем он выше в иерархии. Например, для всплывающих меню стаят  z-index: 10000 или 9999, чтобы уж наверняка они были НАД любыми объектами страницы.

Absolute же более гибкий. Если он стоит внутри объекта с позицией relative, то он будет иметь любую позицию (как fixed), но уже ОТНОСИТЕЛЬНО содержащего ЭЛЕМЕНТА. Лучше всего разобрать это на примере.

 

Разобъем смайлик на объекты, что мы тут видим — голову, которая содержит все элементы, глаз > зрачок, глаз.правый > зрачок, рот и зуб.

Рисуем лицо:

<div class="face">

</div>

В листе стилей пишем:

.face{
background-color: #FFCC00;
width: 400px;
height: 400px;
position: relative;
margin: 50px;
border-radius: 400px;
}

Вот он наш position: relative. Его мы прописываем, чтобы все внутренние объекты с position: absolute выстраивались относительно лица, а не окна.

Заходим внутрь face, отбиваем Tab, чтобы дать отступ слева, и пишем глаз:

<div class="eye left">

</div>

Теперь войдем в глаз и напишем зрачок (pupil):

<div class="pupil">
</div>

 

Таким образом получаем лесенку:

<div class="face">
   <div class="eye left">
       <div class="pupil">
       </div>
   </div>
</div>

Чтобы отбить строку или даже целый кусок кода назад — убрать лишние отступы, выделите эту строку или блок кода и жмите Shift+Tab!

Благодаря лесенкам мы сразу визуально отделяем, какой элемент что содержит.

В общем-то я бы сразу написала и второй глаз:

<div class="face">
   <div class="eye left">
       <div class="pupil">
       </div>
   </div>
   <div class="eye right">
       <div class="pupil">
       </div>
   </div>
</div>

Идем в стили и пишем:

.eye{
background-color: #fff;
width: 100px;
height: 100px;
position: absolute;
top: 100px;
left: 50px;
border-radius: 100px;
}

 

Фон — белый, ширина и высота по 100 пикселей, позиция — абсолютная (!), сверху — 100px, слева — 50px. Ну и радиус скругления — 100px. Сохраните, откройте свой файл .html и посмотрите, что получилось — вуаля — желтый блин с белком внутри!

Наш правый глаз точно такой же, но находится правее, а значит, нам нужно для него указать только координаты:

.eye.right{
right: 50px;
left: auto;
}

Обратите внимание — див класса eye повторяется в хтмл-коде 2 раза, то есть оба элемента наследуют стили для eye. И чтобы выделить правый и дать ему уточнение (другую координату справа), достаточно подцепить его в листе стилей через второй класс right:

.eye.right

Внимание — тут нет пробела, так как классы находятся на одном уровне — принадлежат одному и тому же объекту.

Теперь напишем стили для зрачка:

.pupil{
background-color: #000;
width: 30px;
height: 30px;
position: absolute;
top: 50%;
left: 50%;
border-radius: 100px;
}

Фон — черный, ширина и высота по 30px, позиция абсолютная (!), сверху и слева по 50%. Как вы опять видите, из-за того, что зрачок находится ВНУТРИ глаза, то и отступы он считает ОТНОСИТЕЛЬНО ГЛАЗА. Почему же зрачок съехал внутрь? Потому что координаты top и left задаются для ВЕРХНЕГО ЛЕВОГО УГЛА воображаемого квадрата (если убрать border-radius: 100px; то зрачок станет квадратным). Соответственно — координаты bottom и right задаются для НИЖНЕГО ПРАВОГО УГЛА воображаемого квадрата.

Что нам делать со вторым зрачком? Он смотрит тоже вправо, а я хочу скосить его внутрь. Воспользуемся предыдущим приемом — подцепим зрачок через дополнительный класс right:

.eye.right .pupil{
left: 20%;
}

 

То есть вы понимаете, насколько гибкий CSS? Совершенно необязательно писать и дублировать стили для каждого элемента. Мы можем задать одному объекту сколько угодно классов, для каждого класса в CSS — свои свойства, и просто присваивать эти свойства по мере надобности. Очень важно освоить эту технику, так как с помощью ява-скриптов динамика добавляется именно так — мы динамично присваиваем или вырезаем классы у объектов, заставляя их выглядеть по-разному в зависимости от действий пользователя. Например — все меню серое, а на клик выделенный пункт становится зеленым с пупырышками — это все засчет динамичного добавления ему класса .зеленый_с_пупырышками.

 

Дальше — рисуем рот. Тут интересный и полезный способ выровнять абсолютно-позиционированный элемент по центру содержащего контейнера:

.mouth{
background-color: red;
position: absolute;
width: 200px;
height: 100px;
top: 60%;
left: 50%;
}

 

Посмотрите теперь на нашу кривую рожу ))). Что мы наделали?!?

Мы дали рту отступ left: 50%, благодаря чему рот съехал вправо, так как 50% (то есть — центр лица) — начало координат для левого верхнего угла рта. Чтобы выровнять его по центру, нужно дать ему отрицательный margin слева на ПОЛОВИНУ ШИРИНЫ рта. Благо, ширина эта у нас есть — width: 200px. То есть, отступ у нас должен быть margin-left: -100px;

.mouth{
background-color: red;
position: absolute;
width: 200px;
height: 100px;
top: 60%;
left: 50%;
margin-left: -100px;
}

 

Окей, выровняли, как же заставить его улыбаться? Если дать border-radius, то рот станет просто круглым. Но ведь должен быть способ скруглить только два нижних угла? И он есть!

border-bottom-left-radius: 100px;
border-bottom-right-radius: 100px;

Вставляем код в .mouth{

Аллилуйя! Смайлик стал смайликом, а не страшным человеком.

Ну, я думаю, зуб ему вставить для вас теперь плевое дело. Это задание на дом! В следующем уроке мы заставим зубы расти и уменьшаться c помощью простеньких ява-скриптов.

 

Это ответ на вопрос в комментарии:

smile3



5 thoughts on “Border-radius и position — всего 2 свойства позволят нам сделать смайлик с зубом )”

  • А не проще во рту прост прописать маргин-лефт:100пх. то же самое же? Зачем два значения? и проценты и пиксели… непаняятна. туда-сюда какое-то.
    И еще непонятно, по какому принципу эти отступы все делаются. Ну вот с глазами не понимаю. Вот два глаза с одинаковым значением лефт, но каким образом правый глаз правее левого? короче, я не врубаюсь, в какой координате по умолчанию располагается объект внутри объекта, и от каких «стен» он начинает свой отступ? Надеюсь, понятно, что я имею в виду

    • Объясняю. Если «в голую» поставить один див в другой, то по умолчанию у них будут значения left:0, top: 0; То есть — как написано в уроке — по умолчанию объект выравнивается по левому верхнему углу (если объект круглый — то по воображаемому верхнему левому углу, как если бы вы круг вставили в квадрат (см. картинку сверху) — если border-radius сделать равным 0, то как раз и будет квадрат вместо круга).

      Два глаза у нас НЕ с одинаковым оступом слева. eye.right имеет значения:

      right: 50px;
      left: auto;

      То есть — СПРАВА 50 пкс, а слева АВТО — то есть автоматически оставшееся значение. Это необходимо указывать, чтобы объект не занимал все пространство слева направо, АВТО очищает отступ слева.

      Про стены. Внешний объект, который содержит все внутренние — это face. Если опять же убрать для лица border-radius, то мы получим КВАДРАТ. Вот стенки этого квадрата и являются стенами, от которых отталкиваются все внутренние.

      Далее, почему не маргины, а координаты top, left. right, bottom. Потому что для абсолютных и фиксированных объектов по умолчанию используются координаты. Маргины используются для другого. Как раз случай этот описан в случае РТА. Сначала мы ставим для него left: 50%. И он уезжает вправо, так как это координата для верхнего левого угла рта. Чтобы выровнять ровно по центру, мы берем ширину рта (200 пкс), делим пополам, получаем 100 пкс — и на это значение делаем отрицательный отступ. Тянем его назад влево на 100 пкс. Почему не написать просто отступ слева 100пкс? Потому что ширина лица может поменяться. Предположим, наше лицо должно ВСЕГДА занимать 100% ширины экрана. Экраны всегда разные (от компьютеров до телефонов), значит лицо будет всегда иметь плавающее значение — от 1900 пкс в ширину (на десктопе) до 320 пкс (на мобильниках). А рот всегда будет иметь отступ слева 100 пкс. Что мы получим? Что рот на десктопе будет съехавшим влево, а на мобильнике — вправо и даже за пределы экрана. Вот поэтому мы и даем значение в процентах (от ширины лица) и тащим влево на половину ширины рта в пискелях.

    • а, ты неправильно приписала классы. Если ты хочешь, чтобы оба зуба приняли одни и те же стили, то называешь оба tooth, то есть
      <div class=»tooth»>
      </div>
      <div class=»tooth»>
      </div>

      Они оба станут абсолютно позиционированы, короче оба зуба сначала станут одинаковыми. Потом, чтобы задать второму зубу собственные параметры, то пишешь не tooth1, а tooth tooth1 например, потом tooth tooth2. То есть добавляешь к классу зуб еще 1 класс — зуб1, зуб2 и т.п. И стили пишешь в цсс уже для
      .tooth.tooth1 {

      }
      .tooth.tooth2{

      }

      Класс, который указан последним, переисывает значения первого, то есть tooth1 частично перепишет tooth

      И проверяй все в инспекторе, там же сразу видно, что у тебя ко второму зубу вообще нет никаких стилей. Стоило добавить в <div class=»tooth»>…</div> tooth1, чтобы получилось
      <div class=»tooth tooth1″>
      </div>
      как сразу зубик появился! )