51 votes

Flottant une image en bas à droite avec l'habillage de texte autour

J'ai un conteneur de texte avec des paragraphes et des titres. Au bas de la page, je veux flotter une image à droite de la page, tandis que le texte s'enroule autour de l'image. Le bas de l'image doit être aligné avec le bas de le dernier paragraphe.

La largeur de la page est variable (responsive), mais les dimensions de l'image sont fixes. Est-il possible de réaliser cela en HTML et CSS (CSS3 est très bien)? Si non, peut-il être fait avec un minimum de Javascript?

Voici un exemple schématique de ce que je veux accomplir:

Floating image to the bottom right

Le HTML actuellement ressemble à quelque chose comme ça, mais il peut être modifié si nécessaire. Je n'ai pas particulièrement de soins où, dans le document, l'image est situé. En utilisant des images d'arrière-plan au lieu de cela serait bien aussi.

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

Lorsque j'ai mis en float: right sur l'image, il flotte à droite mais je n'arrive pas à aligner vers le bas de la page. Des Suggestions?

Edit: le plus proche que j'ai est cela... :-)

58voto

gilly3 Points 33285

Créer une entretoise élément avec float: right et height égale à la hauteur du contenu moins la hauteur de l'image. Ensuite, utilisez float: right et clear: right sur l'image:

<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

Mon démo utilise fixe les dimensions de l'élément conteneur. Car c'est rarement réaliste cas, il a probablement fait plus de sens d'utiliser le JavaScript pour la taille de l'entretoise. Appelez cette fonction, passer une référence à l'élément entretoise lorsque le document est prêt et au cours de l' window.onresize événement.

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";
    }
}

Cette fonction fonctionne (voir la démo), et peut être retravaillé pour jQuery ou votre bibliothèque de son choix. Il n'est pas censé être le plug-in de la qualité du code, mais sert à illustrer le concept.

jsfiddle.net/n5RPV/9

Edit: j'ai créé un plugin jQuery version (github | jsFiddle démo) qui prend en charge flottante en bas à gauche ou en bas à droite. Il prend également en charge la spécification de l'élément d'aligner le bas avec.

En passant, je n'ai pas la peine d'essayer de soutenir IE7.

7voto

Danield Points 17720

Je pense que l'avenir de la manière d'aborder ce problème avec CSS Exclusions.

CSS Exclusions étendre la notion de contenu d'emballage précédemment limité à flotteurs. ... Éléments de mise en page de leur contenu en ligne dans leur zone de contenu et les enrouler autour des zones d'exclusion dans leur emballage contexte (--extraits de la spec)

Cet article msdn explique également les exclusions

...les auteurs de sites web peut maintenant renvoyer le texte afin qu'il entoure complètement éléments, et d'éviter ainsi les limitations traditionnelles de chars. Au lieu de limiter les éléments flottants, soit à gauche ou à droite par rapport à leur position dans le flux de documents, CSS Exclusions peuvent être positionné à une distance spécifiée par le haut, le bas, la gauche ou la à droite d'un bloc contenant, tandis que la partie restante de la flux de documents.

Ironie du sort, à ce jour, cela ne fonctionne que dans IE10 (cherchez wrap-débit:à la fois ici)

Découvrez ce violon dans IE10+

C'est ce à quoi ressemble le code:

 <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;
}

Donc, comme vous pouvez le voir - même si l'exclusion est en position absolue - il agit encore comme un float - dans ce cas: flotteur en bas à droite.

Concernant la prise en charge du navigateur:

Découvrez ce site qui montre les propriétés sont prises en charge par les navigateurs (à ce jour: seulement IE10+ prend en charge l' wrap-flow:both )

PS: les Dernières mises à jour concernant les CSS exclusions (et d'autres simlar modules comme les régions du CSS et CSS Shapes) peut être trouvé à l'Adobe Web de la Plateforme de Blog de l'Équipe

3voto

Kris Hollenbeck Points 5132

Possible CSS Solution: (testé uniquement dans chrome)

Il ressemble à cela pourrait fonctionner à l'aide de CSS3 du flex propriétés de la zone et une combinaison des background-image propriétés. J'ai été en mesure d'obtenir à peu près en utilisant uniquement CSS. (Il fonctionne mais a besoin d'un peu de peaufinage) Aussi, c'est peut-être pas idéal parce que je n'ai changer que le balisage un peu pour faire ce travail. Mais c'est probablement vaut le coup si vous êtes à la recherche pour un pur CSS solution.

Voici une Démo -> http://jsfiddle.net/ADSH2/

Nouvelle balise: (pas très différentes)

<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;
}

Ressources:

  1. http://css-tricks.com/snippets/css/a-guide-to-flexbox/
  2. http://dev.w3.org/csswg/css-flexbox-1/

2voto

Terry Points 7657

J'ai travaillé sur un jQuery-solution à base d' — probablement pas aussi élégant que celui posté par gilly3 bien ;) et c'est aussi plus lent et un peu gonflé...

Mon astuce consiste à ajouter deux <div>s de la section, qui se trouve à gauche et cachés de la largeur d'une largeur de 0. L'un des div, un fantôme élément qui auront la même dimension que l'image, sera positionné en dessous d'un autre div qui est la hauteur de l'entretoise. Le script utilise une boucle while pour établir si le fantôme de l'élément a atteint le fond de la section parent de l'élément. Si cela n'est pas arrivé, il augmente la hauteur de la hauteur de l'entretoise de 1, jusqu'à ce que la condition est satisfaite.

Le balisage j'ai utilisé est le suivant. Je suis en utilisant le HTML5, l'attribut data-bottom-image afin d'identifier les articles que vous avez l'image flottait vers le bas. Bien sûr, il n'est pas indispensable, selon la façon dont vous souhaitez sélectionner le bon élément de section.

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

Et le script jQuery:

$(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"));
        });
    }));
});

Et voici le travail de Violon: http://jsfiddle.net/teddyrised/xmkAP/5/

2voto

Stichoza Points 1279

Je suppose que c'est résolu. Il fonctionne!

Avec un peu de JavaScript et de CSS, je l'ai fait comme ceci:

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

Un simple floatify() fonction.

  • Réactive.
  • Redimensionnement de la fenêtre ne sera pas le casser.
  • Toute la largeur de l'image/de la hauteur.
  • Mettre autant de texte que vous voulez.

Idée inspirée par: http://www.csstextwrap.com/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X