Подтвердить что ты не робот

Плавание изображения снизу справа с переводом текста вокруг

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

Ширина страницы является переменной (отзывчивой), но размеры изображения фиксированы. Можно ли это сделать в HTML и CSS (CSS3 в порядке)? Если нет, можно ли это сделать с минимальным количеством Javascript?

Вот схематический пример того, что я хочу выполнить:

Floating image to the bottom right

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

<section>
  <h2>...</h2>
  <p>... ...</p>
  <p>... ...</p>
  ...
  <img src="...">
</section>

Когда я устанавливаю float: right на изображении, он плавает вправо, но я не могу заставить его выравниваться в нижней части страницы. Предложения?

Изменить: ближайший я получил this...: -)

4b9b3361

Ответ 1

Создайте разделительный элемент с float: right и height, равным высоте содержимого минус высота изображения. Затем используйте float: right и clear: right на изображении:

<div class="spacer"></div>
<img class="bottomRight"></div>
<div class="content"></div>
.spacer {
    height: calc(100% - 200px);
    width: 0px;
    float: right;
}
.bottomRight {
    height: 200px;
    float: right;
    clear: right;
}

http://cssdesk.com/bLNWs

Моя демонстрация использует фиксированные размеры в элементе контейнера. Поскольку это редко бывает реалистичным, вероятно, имеет смысл использовать JavaScript для определения размера разделителя. Вызовите эту функцию, передав ссылку на элемент распорки, когда документ готов, и во время события window.onresize.

function sizeSpacer(spacer) {
    spacer.style.height = 0;
    var container = spacer.parentNode;
    var img = spacer.nextElementSibling || spacer.nextSibling;
    var lastContentNode = container.children[container.children.length - 1];
    var h = Math.max(0, container.clientHeight - img.clientHeight);
    spacer.style.height = h + "px";
    while (h > 0 && img.getBoundingClientRect().bottom > lastContentNode.getBoundingClientRect().bottom) {
        spacer.style.height = --h + "px";
    }
}

Эта функция работает (см. демонстрацию) и может быть переработана для jQuery или выбранной вами библиотеки. Он не предназначен для создания кода качества подключаемого модуля, но служит для иллюстрации концепции.

jsfiddle.net/n5RPV/9

Изменить: Я создал версию плагина jQuery ( github | jsFiddle demo), который поддерживает плавающие нижние левые или нижние правые. Он также поддерживает указание, какой элемент выравнивает нижний.

Кстати, я не стал пытаться поддерживать IE7.

Ответ 2

Я думаю, что будущий способ решения этой проблемы будет с Исключения CSS.

Исключения CSS расширяют понятие обложения содержимого ранее ограничено поплавками.... Элементы компонуют свой встроенный контент в своей области содержимого и обертывают области исключения в связанном контексте переноса (--excerpts from спецификация)

Эта статья msdn также объясняет исключения

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

Как ни странно, на сегодняшний день это работает только в IE10 (посмотрите на wrap-flow: здесь)

Отметьте эту скрипту в IE10 +

Вот как выглядит код:

 <div class="container">
    <div class="exclusion">
        Exclusion positioned at bottom right hand side of text.
    </div>
    <div class="dummy_text">
        <p>text here</p>
    </div>
</div> 

CSS

.container {
    font-size: small;
    background: aqua;
    position: relative;
}

.exclusion {

    -ms-wrap-flow: both;
    -ms-wrap-margin: 10px;
    z-index: 1;
    position:absolute;
    right:0;
    bottom:0; /* try fiddling with this. For some reason bottom: -10px (or the like) works better here */
    width: 150px;
    height: 100px;
    background: url(http://placehold.it/150x100) no-repeat;
}

Итак, как вы можете видеть - хотя исключение позиционируется абсолютно - оно все равно действует как float - в этом случае: float bottom right.

Что касается поддержки браузера:

Откажитесь от этого сайта, который показывает, какие свойства поддерживаются браузерами (на сегодняшний день: только IE10 + поддерживает wrap-flow:both)

PS: Последние обновления, касающиеся исключений CSS (и других модулей simlar, таких как области CSS и CSS-формы), можно найти в Adobe Блог команды веб-платформы

Ответ 3

Возможное решение для CSS: (проверено только в хроме)

Похоже, что это может работать с использованием свойств CSS3 flex box и комбинации свойств background-image. Я смог получить его довольно близко, используя только CSS. (Он работает, но нуждается в небольшой настройке). Кроме того, это может быть не идеальной причиной, потому что мне пришлось немного изменить разметку, чтобы сделать эту работу. Но его, вероятно, стоит сделать, если вы ищете чистое решение CSS.

Вот демон → http://jsfiddle.net/ADSH2/

Новая разметка: (не сильно отличается)

<section >
  <h2>Some Heading:</h2>
  <p>...</p>
  <p class="last">
     <span class="image"></span>
  </p>
</section>

CSS

.last {
    display:inline-flex;
    flex-direction:row;
}
.image {
    padding:5px 0 0 5px;
    width:100%;
    background-image:url("http://dribbble.s3.amazonaws.com/users/200359/screenshots/758731/stackoverflow_logo.png");
    background-size:100%;
    background-repeat:no-repeat;
    background-position:bottom right;
}

Ресурсы:

Ответ 4

Я работал над решением на основе jQuery — вероятно, не такой элегантный, как тот, который был отправлен gilly3, хотя;), и он также медленнее и немного вздулся...

Мой трюк состоит в том, чтобы добавить в раздел два <div>, которые перемещаются влево и скрытая ширина шириной 0. Один из div, назначенный элемент-призрак, который будет иметь такое же измерение, как и изображение, будет быть расположенным ниже другого div, который является назначенным разделителем высоты. script использует цикл while, чтобы установить, достиг ли элемент призрака в нижней части элемента родительского раздела. Если этого не произошло, оно увеличит высоту проставки высоты на 1, пока условие не будет выполнено.

Разметка, которую я использовал, следующая. Я использую атрибут HTML5 data-bottom-image, чтобы идентифицировать разделы, в которых у вас есть изображение, которое будет отображаться внизу. Конечно, это невозможно, в зависимости от того, как вы хотите выбрать правильный элемент раздела.

<section id="c1" data-bottom-image>
    <h2>...</h2>
    <p>...</p>
    <img src="http://placehold.it/250x100" />
</section>

И jQuery script:

$(function () {
    $("section > img:last-child").each(function () {
        // Offset image based on the bottom and right padding of parent
        var $par = $(this).parent();
        $(this).css({
            bottom: $par.css('padding-bottom'),
            right: $par.css('padding-right')
        });
    });

    // Function: adjust height of height-spacer, pixel by pixel
    function adjustHeightSpacer($par, $hs, $is) {
        // Stretch height spacer
        $hs.height(0);
        $hs.css({
            height: $par.find("img").position().top - parseInt($par.css('padding-top'))
        });

        // Adjust height spacer
        while($par.height() - $is.height() > $is.position().top - parseInt($par.css('padding-top'))) {
            $hs.height("+=1");
        }

        while($par.height() - $is.height() < $is.position().top - parseInt($par.css('padding-top'))) {
            $hs.height("-=1");
        }        
    };

    $("section[data-bottom-image]").each(function() {
        // Append two spacers:
        $(this).prepend('<div class="ghost height-spacer" /><div class="ghost image-spacer" />')

        var $hs = $(this).find(".height-spacer"),
            $is = $(this).find(".image-spacer");

        // Adjust image spacer dimension
        $is.css({
            height: $(this).find("img").height(),
            width: $(this).find("img").width()
        });

        // Adjust height spacer
        adjustHeightSpacer($(this), $hs, $is);
    });

    $(window).resize($.debounce(250,function() {
        $("section[data-bottom-image]").each(function() {
            // Adjust height spacer
            adjustHeightSpacer($(this), $(this).find(".height-spacer"), $(this).find(".image-spacer"));
        });
    }));
});

И вот рабочий скрипт: http://jsfiddle.net/teddyrised/xmkAP/5/

Ответ 5

Я думаю, он решил. Он работает!

С небольшим количеством JavaScript и CSS я сделал это так:

http://jsfiddle.net/stichoza/aSScx/

Одна простая функция floatify().

  • Адаптивный.
  • Изменение размера окна не нарушит его.
  • Любая ширина/высота изображения.
  • Поместите столько текста, который вы хотите.

Идея, вдохновленная: http://www.csstextwrap.com/

Ответ 6

Решение только для CSS.

Используя медиа-запросы, вы можете выполнить этот макет.

HTML

<section>
  <h2>...</h2>
  <p>... ...</p>
  <p>... ...</p>
  <img src="..." class="show-medium">
  ...
  <img src="..." class="show-small">
</section>

CSS

html, body {
  height: 100%;
  width: 100%;
}

img {
  display: none;
  float: right;
  clear: right;
}

@media (max-width: Xpx), (max-height: Xpx) {
  /* show img for small screens */
  .show-small { display:block; }
}
@media (min-width: Xpx) and (max-width: Xpx) and (min-height:Xpx) and (max-height: Xpx) { 
 /* show img for medium screens */
 .show-medium { display:block; }
}

@media (min-width: Xpx) and (min-height: Xpx) {
  /* show img as body background for large screens */
  body {
    background: url("http://placehold.it/200x300") no-repeat fixed right bottom transparent;
  }
}

Он хорошо воспроизводится при разных разрешениях экрана. См. демонстрацию.

Нужно воспроизводить/настраивать запросы на медиафайлы CSS, а также позицию изображений в разметке, чтобы заставить ее работать.

Поддержка CSS-запросов CSS поддерживается в Firefox 3.5+, Opera 7+, Safari 3+, Chrome и IE9+. Для более старых версий IE вы можете использовать это исправление: http://code.google.com/p/css3-mediaqueries-js/

Ответ 7

используйте это:

<section class="post">
  <h2>...</h2>
  <p>... ...</p>
  <p>... ...</p>
  ...
  <img src="...">
</section>

<style>
.post img {float:right;margin-top:80%}

</style>

измените 80%, чтобы получить лучший результат.

Удачи.

Ответ 8

Здесь легкое решение с немного jQuery:

http://jsfiddle.net/isherwood/6BvC2/

<section class="flagpole">
    <div class="pole"></div>
    <img class="flag" src="..." />
    <p>Paragraphs...</p>
</section>

.pole, .flag {
    float: right;
    clear: right;
}
.pole {
    width: 0.1px
}


function setFlag() {
    $('section.flagpole').each(function () {
        var poleHeight = $(this).height() - $(this).find('.flag').height();
        $(this).find('.pole').height(poleHeight);
    });
}

setFlag();

$(window).on('resize', function () {
    setFlag();
});

Чтобы развеять любые опасения по поводу плагиата, это решение основано на другом подобном ответе Я предоставил некоторое время назад.