Реализовать этот макет с помощью CSS float: left и float: right или с помощью CSS margin-left и position: absolute?

Я хочу разместить некоторые аннотации слева от темы, используя HTML и CSS (например, аннотации "статус" и "автор", показанные в следующем макете/изображении):

example of desired layout

Я предпочитаю CSS вместо табличного макета.

Аннотации должны отображаться до (слева от) заголовка, как показано выше.

В HTML аннотации должны быть расположены после соответствующего заголовка, например. следующим образом (поскольку информация/содержимое, связанное с темой, обычно происходит после заголовка темы):

<h1>This is a section title</h1>
<div class="status">approved</div>
<div class="author">chris</div>
<p>This is some text. Lorem ipsum.</p>
<p>Lorem ipsum.</p>
<h1>Different section title</h1>
<div class="status">rejected</div>
<p>Lorem ipsum.</p>

Есть (по крайней мере) две возможности:

Какой из них (или любой другой ответ) является лучшим способом реализации этого макета и почему?

Ответ 1

Используйте решение с поплавками. Абсолютное позиционирование не должно использоваться здесь, поскольку текст размещается, а макет зависит от размера текста. Если ваш пользователь изменит свой браузер, чтобы увеличить размер текста, макет будет искажен. Вам нужно особенно осознавать это, если вы разрабатываете страницы для доступности (подумайте об использовании% вместо px для этого размера), но в целом используйте абсолютное позиционирование только тогда, когда это единственный способ сделать то, что вы хотите.

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

Ответ 2

Нет необходимости в position:absolute. float:left будет работать лучше всего для этой ситуации. float:right также не требуется. Это решение совместимо с кросс-браузером. Он будет работать во всех браузерах, включая режим quirks. Дайте мне знать, как это работает для вас или вам нужны какие-либо изменения.

Проверьте рабочий пример на http://jsfiddle.net/PyHGy/9

Если для вас важна последовательность HTML, где должны появляться аннотации после соответствующего заголовка, нам нужно добавить position:absolute в .statusContainer, а затем отрегулировать маржу в .titleContainer. Это также совместимое с кросс-браузером решение.

Проверьте рабочий пример на http://jsfiddle.net/PyHGy/8/

Ответ 3

Да, вы можете добиться того, что ищете с помощью css, т.е.: floats. Однако вам потребуется указать ширину для ваших элементов блока.

Играйте с ним. На своем самом простом уровне установите ширину в 50% (возможно, меньше в зависимости от заполнения) и добавьте float: left и float: там, где это применимо.

Ответ 4

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

HTML:

<div class="section">
  <h1>This is a section title</h1>
  <div class="info">
     <div class="status">approved</div>
     <div class="author">chris</div>
  </div>
  <div class="body">
    <p>This is some text. Lorem ipsum.</p>
    <p>Lorem ipsum.</p>
  </div>
</div>

CSS

.section {
  overflow: auto; /* so that the height and width calculate floats properly, otherwise the height will be nothing since all elements are floating */
  width: 700px; /* or total width */
}

/* this could be simplified if you didn't want the <h1> right near the .info, by putting the <h1> inside .body and removing the .section h1 from this */
.section h1, .section .body {
  float: right; 
  width: 500px; /* whatever */
}

.section .info {
  float: left;
  width: 200px; /* whatever */
}

Ответ 5

Я считаю, что здесь нет целостного "правильного" ответа. В этом посте есть много хороших комментариев и примеров, а также плюсы и минусы между поплавком и позицией.

Я предлагаю рабочий пример, основанный на наследовании CSS (и float). Это делает HTML-разметку очень аккуратной, удобной для доступа и очень легко читается после запуска, когда происходят изменения/ревизии. HTML следует:

<div class="author">
    <h3>This is a section title</h3>
    <span class="status">
        <p>(status: approved)</p>
        <p>(author: chris)</p>
    </span>
    <p>This is some text. Lorem ipsum. Lorem ipsum.</p>
</div>

Рабочий код здесь: http://jsfiddle.net/kz8dG/4/.

Ответ 6

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

Я предлагаю вам использовать жидкую компоновку для этого, не устанавливая ширину сечения на константу px: http://jsfiddle.net/9j5jd/

Преимущества этого решения:

  • В разделах используется 100%-(width of status text) ширина контейнера
  • Порядок элементов html не изменяется

Вы можете установить ширину статуса %, или em, я использовал 150px. Я не устанавливал постоянную высоту для разделов, вы можете сделать это, если хотите.

Коды (такие же, как jsfiddle): HTML:

<div class="section">
    <div class="header"><h1>This is a section title</h1></div>
    <div class="status">approved</div>
    <div class="author">chris</div>
    <div class="content"><div class="inner">
        <p>This is some text. Lorem ipsum.This is some text. Lorem ipsum.This is some text. Lorem ipsum.This is some text. Lorem ipsum.This is some text. Lorem ipsum.This is some text. Lorem ipsum.</p>
        <p>Lorem ipsum.</p>
        </div></div>
</div>
<div class="section">
    <div class="header"><h1>Different section title</h1></div>
    <div class="status">rejected</div>
    <div class="content"><div class="inner">
        <p>Lorem ipsum.</p>
        </div></div>
</div>

CSS

/* Position */
.header, .content {
    float: right;
    width: 100%;
    margin-left: -150px;
}
h1, .inner {
    margin-left: 150px;
}
h1 {
    clear: both; 
}
.status, .author {
    float: left;
    width: 130px;  
    clear: left;
    text-align: right;
    padding-right: 20px;
}

/* Decoration */
h1 {
    color: #365F91;
    font-size: 1.2em;
    margin-bottom: 0.3em;
    font-weight: bold;
}
.status, .author {
    font-size: 0.8em; 
}
.status:before {
    content:"(status: ";
}
.author:before {
    content:"(author: ";    
}
.status:after, .author:after {
    content:")";
}
.section {
    float: left;
    margin-top: 0.5em; 
}

Ответ 7

Вот решение, основанное на агаронном ответе. Это небольшое уточнение, которое:

  • Использует селектор дочерних элементов .section > *, чтобы плавать все правильно (что устраняет необходимость явно ссылаться на элемент заголовка .section h1 [s] и .section .body div)

  • Удаляет <div class="body"> из HTML

  • Добавляет .section > *:first-child { margin-top: 0 }, чтобы заголовок и .info имели одинаковое значение margin-top (любой такой марж должен применяться к .section, а не только к заголовку)

Здесь код:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <style type="text/css">
    .section
        {   overflow: auto; }
    .section > *
        {
            float: right;
            width: 80%; /* whatever */
        }
    .section > *:first-child 
        {
            margin-top: 0
        }
    .section .info
        {   float: left;   width: 20%; /* whatever */ }
    </style>
</head>
<body>
<div class="section">
    <h1>This is a section title</h1>
    <div class="info">
        <div class="status">approved</div>
        <div class="author">chris</div>
    </div>
    <p>This is some text. Lorem ipsum.</p>
    <p>Lorem ipsum.</p>
</div>
<div class="section">
    <h1>Next section title</h1>
    <div class="info">
        <div class="status">rejected</div>
    </div>
    <p>This is some text. Lorem ipsum.</p>
    <p>Lorem ipsum.</p>
</div>
</body>
</html>

Или используйте абсолютную ширину, как показано в ответе ахарона, вместо относительной ширины.

Ответ 8

К сожалению, использование float для перемещения большей части содержимого вправо, как показано в других ответах, имеет нежелательный побочный эффект: он предотвращает обычный "крах поля", который происходит с элементами, которые находятся в нормальном потоке, но которые не происходят с плавающими элементами.

Альтернатива такова:

Создайте большой размер с помощью margin-left (не используйте left, потому что это приведет к слишком большому блоку, переполнению края с правой стороны, тогда как увеличение поля делает соответствующее уменьшение к область содержимого). И, укажите relative позиционирование (с нулевым смещением влево/вправо/верхнее/нижнее) для создания/запуска нового контекста стекирования, так что .section .info будет располагаться относительно каждого .section:

.section
    {
        overflow: visible;
        position: relative;
        margin-left: 200px;
    }

Используйте позиционирование absolute, чтобы поместить .section .info влево и вверху своего содержащего блока:

.section .info
    {
        position: absolute;
        top: 0px;
        left: -200px;
        width: 180px;
        height: 100%
        text-align: right;
        font-size: smaller;
    }

Абсолютное позиционирование .section .info выводит его из нормального потока, а поля обрываются между <h1> и <p>.

Вот полный пример:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <link rel="stylesheet" type="text/css" href="./user.css" /> 
    <style type="text/css">
    .section
        {
            overflow: visible;
            position: relative;
            margin-left: 200px;
        }
    .section > *:first-child 
        {
            margin-top: 0
        }
    .section .info
        {
            position: absolute;
            top: 0px;
            left: -200px;
            width: 180px;
            height: 100%
            text-align: right;
            font-size: smaller;
        }
    </style>
</head>
<body>
<div class="section">
    <h1>1st section title</h1>
    <div class="info">
        <div class="status">approved</div>
        <div class="author">chris</div>
    </div>
    <p>This is some text. Lorem ipsum.</p>
    <p>Lorem ipsum.</p>
    <p>Lorem ipsum.</p>
    <p>Lorem ipsum.</p>
</div>
</body>
</html>