Начало · Справочники · Курсы · Разговоры

leechy.ru · Сайт почти придуман

Обрезание элементов в таблице

Только что написал статью про то, как заставить Firefox обрезать текст красиво точечками и понял, что существует еще проблема со свойством overflow — оно не работает во многих случаях, когда элемент находится внутри таблицы.

Представьте себе ситуацию, когда есть табличная верстка (да, я знаю, что большинство считают это чем-то плохим) и в одной из ячеек необходимо поставить очень широкую картинку так, чтобы картинка обрезалась, если не влезает.

Проблема в том, что во всех браузерах кроме Opera — и в Firefox, и в Internet Explorer, и в Safari — картинка не обрезается.

Пример 1: широкая картинка не обрезается
очень широкая картинка
Эта ячейка должна иметь такую-же ширину, что и ячейка рядом.
<table border="1" style="border-collapse: collapse; width: 100%;"> 
   <td style="width: 50%; padding: 0;">
      <div style="width: 100%; overflow: hidden;">
         <img src="wide-image.png" width="500" height="30" alt="очень широкая картинка" />
      </div>
   </td>
   <td style="width: 50%; padding: 0;">
      Эта ячейка должна иметь такую-же ширину, что и ячейка рядом.
   </td> 
</table> 

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

В чем дело и как исправить

Все дело в том, что браузер, рисуя таблицу не может уверен заранее какой у нее должен быть размер. И по-умолчанию, ячейки таблицы всегда растягиваются в зависимости от содержания, даже если внутри есть элементы, для которых явно указан overflow: hidden;. Просто сам oveflow не наступает, если указана ширина, скажем 100%.

Для того, чтобы решить эту задачу, необходимо просто перевести таблицу в режим, когда заданные размеры будут важнее, содержания. Для этого есть специальное значение в CSS — table-layout: fixed;

В этот момент, браузер начинает считать правильно ширину вложенных элементов и соответственно правильно их обрезает, если нужно.

Пример 2: широкая картинка обрезается правильно
очень широкая картинка
Эта ячейка должна иметь такую-же ширину, что и ячейка рядом.
<table border="1" style="table-layout: fixed; border-collapse: collapse; width: 100%;"> 
   <td style="width: 50%; padding: 0;">
      <div style="width: 100%; overflow: hidden;">
         <img src="wide-image.png" width="500" height="30" alt="очень широкая картинка" />
      </div>
   </td>
   <td style="width: 50%; padding: 0;">
      Эта ячейка должна иметь такую-же ширину, что и ячейка рядом.
   </td> 
</table> 

Чем плох table-layout: fixed

Ничем не плох, за исключением того, что таблица начинает себя вести не совсем как таблица. И собственно теряется часть смысла ее использования. Т. е. если вы используете таблицу для того, чтобы она задавала общую верстку сайта, но при этом, если это необходимо растягивалась в зависимости от контента, то не следует для нее указывать такое значение свойства.

При этом можно обойтись спокойно... вложенной таблицы из одной ячейки, для которой это свойство уже указано!

Пример 3: вложенная таблица решает проблему, когда внешную не хочется трогать
очень широкая картинка
Эта ячейка должна иметь такую-же ширину, что и ячейка рядом.
<table border="1" style="border-collapse: collapse; width: 100%;"> 
   <td style="width: 50%; padding: 0;">
      <table style="table-layout: fixed; width: 100%;"><td>
         <div style="width: 100%; overflow: hidden;">
            <img src="wide-image.png" width="500" height="30" alt="очень широкая картинка" />
         </div>
      </td></table>
   </td>
   <td style="width: 50%; padding: 0;">
      Эта ячейка должна иметь такую-же ширину, что и ячейка рядом.
   </td> 
</table> 

Я конечно понимаю, что это не самое изъящное решение и только даст пищу любителям поговорить о семантике, но это отличное решение проблемы, которая у вас может возникнуть, так что... пользуйтесь!