Максим Покровский

— Привет, меня зовут Максим Покровский. Вы находитесь в моем рабочем кабинете. Поскольку я фрилансер, будем считать, что именно так он и выглядит. Здесь я пишу много интересных вещей, и если вы почувствовали, что я именно тот человек, который вам нужен, то я всегда открыт для контакта.

Сделал за последнее время:


  • Добавил в портфель около 48-и новых работ:

  • Сделал очень много всяких штук при работе над поддержкой сайтов.
    Как бы это теперь в портфель запихнуть?

Заказать мне работу
03.09

Убираем отступ у последнего элемента списка.

Комментарии (21) CSS

Возьмем обычное стандартное горизонтальное меню, между которыми будут отступы в 10px. Как правило, последний элемент списка прижимается к внутреннему краю либо окна, либо контейнера (в моем примере я, для наглядности, сделал контейнер) и вот тут частенько возникает загвоздка….

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

last-item1.gif

<div>
  <ul>
    <li>1.</li>
    <li>2.</li>
    <li>3.</li>
  </ul>
</div>
*{
  margin:0;
  padding:0;
  }

div{
  width:506px;
  border:solid 1px red;
  padding:10px 0 10px 50px;
  height:50px;
  }

ul{
  list-style:none;
  height:50px;
  }

  ul li{
    float:left;
    width:150px;
    height:20px;
    background:#eee;
    border:solid 1px #777;
    padding:0 0 0 10px;
    margin:0 10px 10px 0;
    font:normal 12px/20px Tahoma;
    }

Если вы вставите данный код, то обнаружите, что последний элемент переносится на другую строчку. Почему?

last-item2.gif

Все потому, что у последнего элемента тоже стоит margin-right:10px;
Первое что приходит на ум, это задать последнему li отдельный класс и прописать в нем

margin-right:0;

Это не самое удачное решение!

Во-первых, это некрасиво (да, я эстет :) ). Код должен быть максимально чистым (здесь я немного написал про это) и легко читаемым. А еще я очень не люблю (и знаю кучу солидарного со мной народу) пихать классы чуть ли не вовсе элементы (сия болезнь называется «классицизм»).

Во-вторых, и это основной довод, при интеграции верстки в CMS, с 90% вероятностью возникнет проблема с этим классом. Ведь в более-менее нормальных CMS меню генериться автоматом. То есть, имеется массив разделов, и циклом из него извлекаются их названия (есть и другие способы). В этом случае, придется писать дополнительную проверку на идентификацию последнего элемента. Оно кому-нибудь надо?

Я в этой ситуации поступаю так:

*{
  margin:0;
  padding:0;
  }

div{
  width:506px;
  border:solid 1px red;
  padding:10px 0 10px 50px;
  height:50px;
  overflow:hidden; /*это нужно чтобы наш макет не разъехался*/
  }

ul{
  list-style:none;
  margin:0 -10px 0 0; /* собственно лекарство */
  height:50px;
  }

  ul li{
    float:left;
    width:150px;
    height:20px;
    background:#eee;
    border:solid 1px #777;
    padding:0 0 0 10px;
    margin:0 10px 10px 0;
    font:normal 12px/20px Tahoma;
    }

Просто. Безупречно. Почти.

IE немного смазывает картину. Нужно чтобы ul облегал элементы «зафлоаченные» элементы списка. Здесь лекарства два – либо указываем ему float, либо жестко пишем height. (хитрость с height:1%; тут не катит).

В остальном я весьма доволен методом. Чуть не забыл, данный способ годиться и для вертикальных меню. Тут даже IE не капризничает.

Метки:

Комментарии

  1. 1
    Neutrino (03.09.2007) #

    Какая-то надуманная проблема. И решение нерациональное. ВО-первых не ясно зачем вобще div, если есть ul, который ничем не хуже и является блочным элементом-контейнером списка. Во-вторых, если надо чтобы элементы списка были прижаты вправо, то достаточно будет прописать для li{display:inline, margin: 0 0 10px 10px}, а для ul{text-align: center} и всего делов.

  2. 2
    Neutrino (03.09.2007) #

    Блин, для ul конечно же text-align: right;

  3. 3
    le`Mur (04.09.2007) #

    Пойдем по порядку. Проблема не надуманная, просто ты с ней не сталкивался. Однако и не я один с ней сталкивался. Во-вторых, речь не о том, как выстраивать пункты меню в горизонталь. Далее, при описанном тобой методе, к последнему элементу все равно будет добавляться отступ. Div же нужен, чтобы при отрицательном сдвиге, когда ul выйдет за пределы контейнера, верстка не разваливалась. Хотя в 90% случаев список и так находиться в контейнере.

  4. 4
    Роман Савельев (04.09.2007) #

    Neutrino, ты не прав, есть такая проблема. Вернее, даже не проблема, а заноза в заднице. Я программер, но к сожалению верстка у меня хромает на оба уха. Так что версткой у нас занимаются другие люди, но меня реально ЗАДОЛБАЛО, что у последних li всегда какой-то класс стоит. Теперь буду знать в чем дело.

    ЗЫ
    Пойду пну верстальщика, чтобы почитал все это.

  5. 5
    le`Mur (04.09.2007) #

    2Роман Савельев
    Собственно для этого и писалось.

    PS
    Верстальщка не пинай, примета плохая ;)

  6. 6
    Neutrino (04.09.2007) #

    Нет, ребята, все-таки проблема надуманная. Вернее это проблема только для начинающего верстальщика. Для того чтобы не бороться с “непонятными” отступами надо использовать обнуление дефолтных значений HTML-элементов или простым ластиком:

    * {margin: 0; padding: 0}
  7. 7
    Neutrino (04.09.2007) #

    А классы у последних элементов списка часто используют для оформления меню, когда надо отменить определенное свойства типа border или наоборот добавить :)

  8. 8
    le`Mur (04.09.2007) #

    2Neutrino
    В примере, “ластик” стоит в самом начале. Фишка в том, чтобы убрать отступ у последнего элемента li, не влезая в html-код.

  9. 9
    КольЯ (04.09.2007) #

    Пришел после пинка Романа ))
    Я конечно не начинающий, но добавляю обычно li.noPadding, чтобы отступы убрать. Попробуем теперь так…

  10. 10
    Neutrino (04.09.2007) #

    2le`Mur, да, ластик увидел, когда написал уже. я использую обнуление, на которое сослался, у меня ни разу не было подобной проблемы.

  11. 11
    Dafna (04.09.2007) #

    каюсь))) страдала классицизмом, в последнее время активно лечусь наследованием и применением такого рода хитростей, как написано в блоге, и вообщем-то очч полезный метод, но(!) хотелось бы кое-что прояснить – как можно реже стоит указывать жесткие параметры (высота, ширина) объекту, ибо потом измучаешься с кроссбраузностью, т.к., например, в ие7 , как я недавно убедилась, помимо устранения прежних глюков появилось много новых, особенно на больших разрешениях (1600*1200).
    P.S.: проблема актуальна, за решение: +1)))

  12. 12
    Дима (25.09.2007) #

    Я видел пару CMS, генерирующих массу всяких полезных классов. У ссылок есть класс current (active, selected), например. У списков соотв. есть first и last.

  13. 13
    le`Mur (25.09.2007) #

    Такие “фичи” в CMS нужны только для “корпоративных CMS” (не знаю как правильно назвать CMS, которую разработала какая-либо компания и использует только они для создания сайтов)А если подобные “приблуды” встречаются в распространненых CMS, то это большое зло. Мне может не нужен этот класс или нужен другой или двойной класс хочу, а там “first”

  14. 14
    Дима (25.09.2007) #

    Популярные CMS дорого платят за универсальность. Ничего не поделаешь, разным людям нужны разные фишки. А если ориентироваться на узкую группу, может не быть достаточного спроса.

    Избыточные CSS-классы – это совсем маленькое зло :)

  15. 15
    rmaksim (30.01.2008) #

    чтобы IE немного НЕ смазывал картину, сделать для всех li margin не справа с слева!! и соотв для контейнера padding слева меньше на эту же величину…

    p/s/ это для конкретного примера приведенного автором

  16. 16
    Максим Покровский (30.01.2008) #

    У контейнера нет padding. В том то и дело.

  17. 17
    rmaksim (30.01.2008) #

    эээ, я имел ввиду для конкретного примера для div{ padding:10px 0 10px 50px; }
    padding-left соотв. сделать 40
    а width тож на 10 больше = 516px;

  18. 18
    Dosha (04.06.2008) #

    Очень полезный блог, автор всегда (почти) описывает актальные темы. Спасибо.

  19. 19
    DreamLikeMe (30.06.2008) #

    Есть такая проблема, много раз с ней сталкивался, использовал как раз этот метод:),
    только там далеко не все так просто, ИЕ может сильно подпортить ситуацию, к примеру
    просто игнорировать отрицательный margin и приходится прибегать к разных дополнениям кода.

  20. 20
    Николай Громов (nicothin) (14.09.2008) #

    ужасен листинг последнего CSS-фрагмента – все в одну строку. :(

  21. 21
    Jman (09.07.2009) #

    Я очень удивился когда на хабре когда то давно проскочила статья такого типа… (а я думал все так делают)
    к чему я?

    5 ноября, 2006 (ого-го как давно) Юра (cssing.org.ua) писал как убирать разделители в меню. точно также можно было делать и с отступами.
    когда я не пользовался отрицательными отступами (не знал помолодости) я пользовался :first-child и expression для IE.

    PS. за first и last можно дизайнерам спасибо говорить, когда первый и последний пункты отличаются не только отступами. У программистов кстати проблемы с этим бывают только в том случае когда они по быстрому всё это пихают на какую то недоCMS . ведь па факту меню выводится в цикле из масива, и переписать немного компоненту отрисовывающую меню что-то типа class += (i == 0) ? ” first” : (i++ == array.length) ? ” last” : “” (извиняюсь за яваскрипт-подобный синтаксис, кто понимает тот поймёт) не ужели так сложно то ? для отступов, маргинов, бордеров это лишнее, для всего остального или пожертвуем немного процессорного времени сервера (два условия сравнить) или пожертвуем процессорным временем пользователя если у него IE, иначе – :first-child :last-child

Они читают меня, я читаю их

    — Мы можем делать дешево, быстро и качественно. Выбирайте два любых показателя!
    Фрилансерскиая хитрость

    Rambler's Top100