Be KreaTief

[BHPPS] Image Thumbnails

Nach einer gefühlten Ewigkeit mal wieder ein neuer Style für die Startseite. Diesmal sind es Bild-Thumbnails, die beim hovern Titel und Snippet anzeigen.
Die Bilder haben ein fixiertes Seitenverhältnis von 1:1 und sind in Spalten angeordnet. Wenn man auf das Bild klickt, öffnet sich der Post wie gewohnt.
Ich mag diesen Style total, allerdings erfordert er, dass in jedem Post ein Bild vorkommt, ansonsten funktioniert das nicht wirklich. Es ist etwas anspruchsvoller als die letzten Styles, aber optisch der harmonischste, wenn ihr mich fragt.
Die Inspiration kam mir durch Codrops.

After quite some time a new style for the home page. This time it's image thumbnails which showcase title and snippet as soon as you hover above them. The images have a fixed aspect ratio of 1:1 and are ordered in collumns. If you click on the picture it'll open up the post just like it normally would.
I really like this style, but it does require an image in every post, otherwise it won't work. It is a little harder than the last ones, but the most harmonic looking if you aks me.
I got the inspiration for this look at Codrops.





Und damit ihr das noch seht mit dem hover-Effekt, habe ich eine Demoseite für euch, die ihr gleich hier unten sehen könnt.

And so you can see the hover-effect I built a demopage for you, which can just be seen underneath.



Basic Idea

Die Grundidee ist simpel. Wir haben einen Container, in dem wir ein span haben, der Titel sowie snippet enthält.

The basic idea is very simple. We have a container in which we place a span containing the title as well was the snippet.

<a href="POST_URL">
    <div>
        <span>
            <h3>Title</h3>
            <p>Snippet</p>
        </span>
    </div>
</a>

Was wir im Grunde tun, ist das Bild als Hintergrundbild für den div-Container zu definieren. Das gibt uns die Möglichkeit das Bild "zuzuschneiden", indem wir es als "cover"-Hintergrundbild definieren. Ganz so simpel ist es allerdings leider nicht, aber im Grunde ist es das, was wir machen werden.

What we basically do is set the image as background of the container. This gives us the ability to crop the image into the correct ratio, by setting it as a "cover"-background. It is not all that easy, but basically, that's what we are gonna do.

Five

Wie immer machen wir das Ganze mit Five. Ich habe dem ganzen noch Bootstrap-CSS hinzugefügt und ein paar Zeilen CSS geschrieben.

As allways we're gonna accomplish this look with five. I added bootstrap-css and a few lines of CSS.

Five | Bootstrap

Bei mir sieht das dann so aus:

That's what it looks like for me:



Als nächstes müssen wir jQuery einfügen, da wir ein Script werden verwenden müssen.
Dazu geht öffnet ihr die jQuery-Seite und scrollt ganz nach unten. Dort werdet ihr den Link für die aktuellste Version finden.

Next we have to add jQuery because we'll have to use a script.
Just open up the site and scroll all the way down. You'll find the access link to the most recent version.


jQuery

Sucht dann in eurem Blogger-Code nach dem schliessenden body-Tag (</body>) und fügt oberhalb davon den Link ein, der wie folgt aussieht:

Search in your code the closing body tag(</body>) and put the script just above it, like that:

<!-- jQuery -->
<script src='QUICK_ACCSESS_LINK'/>



Thumbnail Markup and Script

Okay, bevor ich das Script erkläre, werde ich kurz auf das Markup eingehen, das wir für die Thumbnails verwenden müssen. In Blogger gibt es eine Möglichkeit das erste Bild eines Posts in einem image-Tag einzufügen, allerdings nicht in der CSS. In der CSS kann man nur "reale" Links einfügen, die man hat. Wie also bekommen wir den Link in die CSS? Ich habe mir dafür eine Lösung ausgedacht und Oliver war dann so nett mir mit dem Script zu helfen (weil Myri ist unfähig mit jQ...) Das ist ein Punkt, der im neuen Markup Verwendung findet. Und dann natürlich noch die Sache, dass ich die Bilder responsive haben will. Ich habe lange gesucht, aber nach einer Weile habe ich eine Lösung in den Weiten des WWW gefunden, das die ultimative Lösung bringt. Ein Dummy! :D

Okay, before I go on explaining the script let me talk about the specific markup used for the thumbnails. In Blogger you have the possibility to add the url of the first image of your post in an image tag, but not into the CSS. In the CSS you can only add "real" links, you actually have. So how do you add the link into the CSS. I had an idea and Oliver was nice enough to help me write the script (because Myri and jQ are still not feeling really comfortable with eacht other...) That's one point we need to use. The second is responsiveness. I found a way on how to keep a fixed ratio, after a really long internet search, which is simple and absolutely genious. A dummy!

Fixed Aspect Ratio Responsive

Haben wir das, ergibt sich folgendes Markup:

Now we have the following markup:

<a expr:href='data:i.url' expr:title='data:i.title'>
    <div class='ar_container'>
        <div class='ar_dummy'/>
        <div class='ar_content'>
            <img class='img' expr:src='data:i.firstImageUrl'/>
            <span>
                <h3><data:i.title/></h3>
                <p><data:i.snippet/></p>
            </span>
        </div>
    </div>
</a>

Wie ihr seht, habe ich das erste Bild des Posts in unserem Hauptcontainer platziert. Was ich im Script mache, ist die URL des Bildes auszulesen und dem Container das Attribut background-image mit der Bild-URL zuzuordnen. Auf diese Weise haben wir für jeden Container das erste Bild des Posts als Hintergrund definiert.
Und so sieht das dann aus:

As you can see I added the first image of the post inside the main container. What I'm doing in the script is search for the url of the image and add it as the background-image of the main container with CSS.
That's how that looks:


<!-- Responsive 1:1 -->
<script type='text/javascript'>
    //<![CDATA[
    $(document).ready(function() {
        $('.ar_content').find('img').each(function(n, image){
            var image = $(image);
            var thisurl = $(this).attr('src');
            image.parents('.ar_content').css('background-image', 'url(' + thisurl + ')');
        });
    });
    //]]>
</script>

Dieses Script kopiert ihr unterhalb des eben hinzugefügten jQuery-Scripts.

You wanna paste this scrupt beneath the just added jQuery-Script.

Markup

Kommen wir zum Verändern des Codes. Seit der neue Editor die eingeklappten includes hat, ist es am einfachsten einfach die ganze Linie zu markieren und komplett zu ersetzen.
Wir verändern zwei includables. Einmal das main und einmal das post.

Now for the code replacement. Since the new editor does shorten the includables it is far easiert to replace it all in one step, because it's one line only. So we are just gonna replace two of the includables. the main and the post one.

main includable

ursprünglich:

original:
<b:includable id='main' var='top'>

    <!-- posts -->
    <b:loop values='data:posts' var='post'>      
        <b:include data='post' name='post'/>      
    </b:loop>

    <!-- navigation -->
    <b:include name='nextprev'/>

</b:includable>

neu:

new:

<b:includable id='main' var='top'>

    <!-- index: grid layout -->
    <b:if cond='data:blog.pageType == &quot;index&quot;'>           
        <div class='grid'>
            <b:loop values='data:posts' var='i'>
                <b:include data='i' name='post'/>
            </b:loop>
        </div>
    <b:else/>
    <!-- item/static page: normal layout -->
        <b:loop values='data:posts' var='i'>    
            <b:include data='i' name='post'/>
        </b:loop>
    </b:if>
    
    <!-- navigation -->
    <b:include name='nextprev'/>

</b:includable>

post includable

ursprünglich:

original:

<b:includable id='post' var='i'>
    <article>
        <div class='post' itemprop='blogPost' itemscope='itemscope' itemtype='http://schema.org/BlogPosting'>
            <b:if cond='data:post.firstImageUrl'>
                <meta expr:content='data:i.firstImageUrl' itemprop='image_url'/>
            </b:if>
            <meta expr:content='data:blog.blogId' itemprop='blogId'/>
            <meta expr:content='data:i.id' itemprop='postId'/>
            <a expr:name='data:i.id'/>
            <header>
                <div class='post-header'>
                    <b:if cond='data:i.title'>
                    
                        <!-- post-title -->
                        <div class='post-title'>
                            <h2 itemprop='name'>
                            <b:if cond='data:i.link'>
                                <a expr:href='data:i.link'><data:i.title/></a>
                            <b:else/>
                                <b:if cond='data:i.url'>
                                    <b:if cond='data:blog.url != data:post.url'>
                                        <a expr:href='data:i.url'><data:i.title/></a>
                                    <b:else/>
                                        <data:i.title/>
                                    </b:if>
                                <b:else/>
                                    <data:i.title/>
                                </b:if>
                            </b:if>
                            </h2>
                        </div>
                        <!-- post-title end -->
  
                        <!-- post-date-->
                        <b:if cond='data:i.dateHeader'>
                            <div class='post-date'> 
                                <h3 itemprop='date'>
                                    <span><data:i.dateHeader/></span>
                                </h3>
                            </div>
                        </b:if>
                        <!-- post-date end-->
  
                    </b:if>
 
                <!-- post-author -->
                    <div class='post-author'>    
                        <b:if cond='data:top.showAuthor'>
                            <span>
                                <data:top.authorLabel/>
                            </span>
                            <b:if cond='data:i.authorProfileUrl'>
                                <span class='fn' itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'>
                                    <meta expr:content='data:i.authorProfileUrl' itemprop='url'/>
                                    <a class='g-profile' expr:href='data:i.authorProfileUrl' rel='author' title='author profile'>
                                        <span itemprop='name'><data:i.author/></span>
                                    </a>
                                </span>
                            <b:else/>
                                <span class='fn' itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'>
                                    <span itemprop='name'><data:i.author/></span>
                                </span>
                            </b:if>
                        </b:if>
                    </div> 
                    <!-- post-author end -->
 
                </div>
            </header>

            <!-- post-body -->
            <b:if cond='data:blog.metaDescription == &quot;&quot;'>
                <div class='post-body' expr:id='&quot;post-body-&quot; + data:i.id' itemprop='description articleBody'>
                    <data:i.body/>
                </div>
            <b:else/>
                <div class='post-body' expr:id='&quot;post-body-&quot; + data:i.id' itemprop='articleBody'>
                    <data:i.body/>
                </div>
            </b:if>

            <b:if cond='data:i.hasJumpLink'>
                <div class='jump-link'>
                    <a expr:href='data:i.url + &quot;#more&quot;' expr:title='data:i.title'><data:i.jumpText/></a>
                </div>
            </b:if>
            <!-- post-body end -->

            <!-- G+ comments -->
            <b:if cond='data:blog.pageType == &quot;item&quot;'>
                <b:include data='i' name='iframe_comments'/>
            </b:if>
            <!-- G+ comments end -->

            <!-- social-buttons -->
            <b:if cond='data:blog.isMobile'>
            <b:else/>
                <b:if cond='data:blog.pageType != &quot;item&quot;'>
                    <b:if cond='data:blog.pageType != &quot;static_page&quot;'>
                        <div class='social-buttons'>
                            <span class='g-plusone' data-align='right' data-annotation='bubble' data-size='medium' data-width='300' expr:data-href='data:i.canonicalUrl'/>
                            <a class='twitter-share-button' data-lang='de' data-size='medium' expr:data-url='data:i.canonicalUrl' href='https://twitter.com/share'>Twittern</a>
                            <script>
                                //<![CDATA[
                                !function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');//]]>
                            </script>
                        </div>
                    </b:if> 
                </b:if>
            </b:if>
            <!-- social-buttons end-->

        </div>
    </article>
</b:includable>

neu:

new:

<b:includable id='post' var='i'>
    <article class='col'>
        <div class='post' itemprop='blogPost' itemscope='itemscope' itemtype='http://schema.org/BlogPosting'>
            <b:if cond='data:post.firstImageUrl'>
                <meta expr:content='data:i.firstImageUrl' itemprop='image_url'/>
            </b:if>
            <meta expr:content='data:blog.blogId' itemprop='blogId'/>
            <meta expr:content='data:i.id' itemprop='postId'/>
            <a expr:name='data:i.id'/>
            
            
            <b:if cond='data:blog.pageType == &quot;index&quot;'>
                <!-- Index Style -->
                <a expr:href='data:i.url' expr:title='data:i.title'>
                    <div class='ar_container'>
                        <div class='ar_dummy'/>
                        <div class='ar_content'>
                            <img class='img' expr:src='data:i.firstImageUrl'/>
                            <span>
                                <h3><data:i.title/></h3>
                                <p><data:i.snippet/></p>
                            </span>
                        </div>
                    </div>
                </a>
                
            <b:else/>
                
                <!-- Item/Static Page Style -->
                <header>
                    <div class='post-header'>
                        <b:if cond='data:i.title'>
                            
                            <!-- post-title -->
                            <div class='post-title'>
                                <h2 itemprop='name'>
                                    <b:if cond='data:i.link'>
                                        <a expr:href='data:i.link'><data:i.title/></a>
                                        <b:else/>
                                        <b:if cond='data:i.url'>
                                            <b:if cond='data:blog.url != data:post.url'>
                                                <a expr:href='data:i.url'><data:i.title/></a>
                                            <b:else/>
                                                <data:i.title/>
                                            </b:if>
                                        <b:else/>
                                            <data:i.title/>
                                        </b:if>
                                    </b:if>
                                </h2>
                            </div>
                            <!-- post-title end -->
                        
                            <!-- post-date-->
                            <b:if cond='data:i.dateHeader'>
                                <div class='post-date'> 
                                    <h3 itemprop='date'>
                                        <span><data:i.dateHeader/></span>
                                    </h3>
                                </div>
                            </b:if>
                            <!-- post-date end-->
                        
                        </b:if>
                    
                        <!-- post-author -->
                        <div class='post-author'>    
                            <b:if cond='data:top.showAuthor'>
                                <span>
                                    <data:top.authorLabel/>
                                </span>
                                <b:if cond='data:i.authorProfileUrl'>
                                    <span class='fn' itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'>
                                        <meta expr:content='data:i.authorProfileUrl' itemprop='url'/>
                                        <a class='g-profile' expr:href='data:i.authorProfileUrl' rel='author' title='author profile'>
                                            <span itemprop='name'><data:i.author/></span>
                                        </a>
                                    </span>
                                <b:else/>
                                    <span class='fn' itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'>
                                        <span itemprop='name'><data:i.author/></span>
                                    </span>
                                </b:if>
                            </b:if>
                        </div> 
                        <!-- post-author end -->
                        
                    </div>
                </header>
                
                <!-- post-body -->
                <b:if cond='data:blog.metaDescription == &quot;&quot;'>
                    <div class='post-body' expr:id='&quot;post-body-&quot; + data:i.id' itemprop='description articleBody'>
                        <data:i.body/>
                    </div>
                <b:else/>
                    <div class='post-body' expr:id='&quot;post-body-&quot; + data:i.id' itemprop='articleBody'>
                        <data:i.body/>
                    </div>
                </b:if>
                
                <b:if cond='data:i.hasJumpLink'>
                    <div class='jump-link'>
                        <a expr:href='data:i.url + &quot;#more&quot;' expr:title='data:i.title'><data:i.jumpText/></a>
                    </div>
                </b:if>
                <!-- post-body end -->
                
                <!-- classic comments -->
                <b:if cond='data:blog.pageType == &quot;item&quot;'>
                    <b:include data='i' name='comment_picker'/>
                </b:if>
                <!-- classic comments end -->
                
                <!-- social-buttons -->
                <b:if cond='data:blog.isMobile'>
                    <b:else/>
                    <b:if cond='data:blog.pageType != &quot;item&quot;'>
                        <b:if cond='data:blog.pageType != &quot;static_page&quot;'>
                            <div class='social-buttons'>
                                <span class='g-plusone' data-align='right' data-annotation='bubble' data-size='medium' data-width='300' expr:data-href='data:i.canonicalUrl'/>
                                <a class='twitter-share-button' data-lang='de' data-size='medium' expr:data-url='data:i.canonicalUrl' href='https://twitter.com/share'>Twittern</a>
                                <script>
                                    //<![CDATA[
                                    !function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');//]]>
                                </script>
                            </div>
                        </b:if> 
                    </b:if>
                </b:if>
                <!-- social-buttons end-->
            </b:if>
        </div>
    </article>
</b:includable>

CSS

Und jetzt kommt bloss noch die CSS.
Weil ich mich nicht entscheiden konnte, ob mir hell oder dunkel besser gefällt, habe ich sie einfach abwechselnd eingefügt. Wollt ihr nur einer der beiden Looks, entfernt einfach jeweils :nth-of-type(odd) bzw. :nth-of-type(even) des Looks den ihr haben wollt und den kompletten Teil des jeweils anderen Looks.

Now there's only the CSS left.
I couldn't decide if I liked light or dark better, so I just added them both alternating. If you just want one look remove either :nth-of-type(odd) or :nth-of-type(even) and the complete part of the other look.


.ar_dummy {
    margin-top: 100%;
}

.ar_content {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 2; 
}

.ar_container:hover, .ar_dummy:hover, .ar_dummy:hover{
    border: 0; 
}


.ar_container{
    display: inline-block;
    position: relative;
    overflow: hidden; 
    width: 100%;
}

.ar_content img{
    opacity: 0; 
}

.ar_content{
    background-size: cover;
    background-position: center; 
    width: 100%;
    height: 100%;
    transition: all 0.4s ease-in-out;
}

.ar_content span{
    position: absolute;
    top: 2%;
    left: 2%;
    right: 2%;
    bottom: 2%; 
    width: 96%;
    height: 96%; 
    opacity: 0; 
    transition: all 0.4s ease-in-out;
    transform: scale(0);
}

.ar_content span h3 {
    text-transform: uppercase;
    letter-spacing: 2px;
    font-size: 20px;
    margin: 0 3%;
    padding: 15% 0 0 0;
    font-family: 'Open Sans', Arial, sans-serif;
}

.ar_content span p{
    padding: 5% 5%;
    font-style: italic;
    margin: 0;
    font-size: 14px;
    opacity: 0; 
    transition: all .2s ease-in-out 0.4s;
    width: 100%; 
}

.ar_content:hover span{
    transform: scale(1);
    opacity: 1;
}

.ar_content:hover span p{
    opacity: 1;
}

article:nth-of-type(even) .ar_content{
    box-shadow: /* innerer Rahmen | inner border */
  inset 0 0 0 16px rgba(255, 255, 255, .6);
}

article:nth-of-type(even) .ar_content:hover{
    box-shadow: /* innerer Rahmen bei Hover | inner border while on hover */
        inset 0 0 0 1px rgba(255, 255, 255, .1);
}

article:nth-of-type(even) .ar_content span {
    background: rgba(255, 255, 255, .7); /* Hintergrund des Overlays | background of overlay */
}

article:nth-of-type(even) .ar_content span h3 {
 color: #2e2e2e;
}

article:nth-of-type(even) .ar_content span p {
 color: #2e2e2e;
    border-top: 1px solid rgba(0, 0, 0, .5);
}

article:nth-of-type(odd) .ar_content {
    box-shadow: /* innerer Rahmen | inner border */
  inset 0 0 0 16px rgba(0, 0, 0, .6);
}

article:nth-of-type(odd) .ar_content:hover {
    box-shadow: /* innerer Rahmen bei Hover | inner border while on hover */
        inset 0 0 0 1px rgba(0, 0, 0, .1);
}

article:nth-of-type(odd) .ar_content span {
    background: rgba(0, 0, 0, .7); /* Hintergrund des Overlays | background of overlay */
}

article:nth-of-type(odd) .ar_content span h3 {
 color: ivory;
}

article:nth-of-type(odd) .ar_content span p {
 color: ivory;
    border-top: 1px solid rgba(255, 255, 255, .5);
}

article{
    display: block;
}

.col {
    float: left;
    margin-left: 3.2%;
    margin-bottom: 30px;
}

.grid .col {
    width: 22.6%;
}

.grid .col:nth-of-type(4n+1) {
    margin-left: 0;
    clear: left;
}

Media Queries

Und für die Spalten braucht es wieder Media Queries.

And for the collumns we need media queries.

/* von 4 auf 3 Spalten | from 4 to 3 collumns */
@media screen and (max-width: 1220px) {
    .grid .col {
        width: 31.2%;
    }

    .grid .col:nth-of-type(4n+1) {
        margin-left: 3.2%;
        clear: none;
    }

    .grid .col:nth-of-type(3n+1) {
        margin-left: 0;
        clear: left;
    }
}

/* von 3 auf 2 Spalten | from 3 to 2 collumns */
@media screen and (max-width: 815px) {
    .grid .col {
        width: 48.4%;
    }

    .grid .col:nth-of-type(3n+1) {
        margin-left: 3.2%;
        clear: none;
    }

    .grid .col:nth-of-type(2n+1) {
        margin-left: 0;
        clear: left;
    }
}

/* von 2 auf 1 Spalten | from 2 to 1 collumns */
@media screen and (max-width: 545px) {
    .col {
        width: 100% !important;
        margin-left: 0 !important;
        clear: none !important;
    }
}

Done

Und dann war's das schon.
Ich hoffe ihr mögt diesen Look genauso wie ich und wenn ihr noch Fragen habt, einfach stellen. :)

And then you're done.
I hope you like it just as much as I do and if there are still any questions, feel free to ask. :)



More 'bout that

0. Magazine Look Without JavaScript
1. Looks Kinda Pinterest
2. Column Style
3. Current
edit

1 comment:

  1. liebe myri,
    auch wenn ich das alles hier in den grundzügen erst mal verstehe,
    es ist soooooooooooo klasse, gefällt mir sehr.
    kommt zeit kommt übung für mich ;-)

    danke dafür
    grüßle flo

    ReplyDelete

Fragen, Feedback oder anderes, was du loswerden willst?
Kommentiere über das alte Kommentarsystem (check wieder vorbei um zu sehen, ob ich geantwortet habe) oder G+

Questiosn, Feedback or something else you want to tell me?
Comment using the old system or G+ and make sure to check back to see if I answered