I am working on a Django blog application and I have run into a problem with image alignment using Bootstrap 5. I am new at CSS and none of the solutions I see in SO are helping. My problem is I want the text under my images to always line up regardless of the height of the image itself. Here is a partial screen shot:
Here is the HTML code I developed:
{% extends 'base.html' %}
{% load static %}
{% block title %}Post List{% endblock title %}
{% block content %}
<div class="container">
<div class="row">
<!-- Latest Posts -->
<main class="posts-listing col-lg-8">
{% if page_obj %}
<div class="container">
<div class="row">
<!-- posts -->
{% for post in page_obj %}
<div class="post col-xl-6">
<div class="card">
<a href="{{post.get_absolute_url}}">
<img src="{{post.thumbnail.url}}" alt="..." class="img-fluid"></a>
</div>
<div class="card-body">
<div class="post-meta d-flex justify-content-between">
{% comment "" %}<div class="date meta-last"></div>{% endcomment %}
<div class="category">
{% for cat in post.categories.all %}
{{cat.title}}
{% endfor %}
</div>
</div>
<a href={{post.get_absolute_url}}>
<h3 class="h4">{{post.title}}</h3>
</a>
<p class="text-muted">{{post.content|safe | truncatechars:256 }}</p>
<footer class="post-footer d-flex align-items-center">
<a href="{% url 'show-user-profile' post.author.user.id %}" class="profile d-flex align-items-center flex-wrap">
<div class="avatar"><img src="{{post.author.profile_picture.url}}" alt="..." class="img-fluid"></div>
<div class="title"><span>{{post.author.user.username}}</span></div>
</a>
<div class="date"><i class="icon-clock"></i>{{post.timestamp | timesince}} ago</div>
<div class="comments meta-last"><i class="icon-comment"></i>{{post.comment_count}}</div>
</footer>
</div>
</div>
{% endfor %}
</div>
</div>
{% else %}
<p class="text-big">No Posts in this category</p>
{% endif %}
</main>
{% include 'sidebar.html' with most_recent=most_recent category_count=category_count %}
</div>
</div>
{% endblock content %}
The comments I am getting make it seem like what I am trying to do is impossible, and perhaps it is. Here is a screenshot from Adobe Lightroom that shows the concept - all the photos are placed in identically sized boxes regardless of aspect ratio. No distortion, just different size margins to fill in unused space. Now Lightroom isn't HTML but can't this be done? As I mentioned, all of the sample galleries I see use photos with the same aspect ratio, but that should not be a requirement of a gallery.
I would appreciate some help. Thanks
Related
I'd like to list the cards as down below:
This is the code so far. My cards are listed one by one vertically. How can I achieve this?
{% extends 'base_content.html' %}
{% block content %}
{% for item in CATEGORY_CHOICES %}
<div class="row" style="justify-content: center;">
<div class="col-sm-3">
<div class="card">
<div class="card-body">
<h5 class="card-title">{{ item.1 }}</h5>
</div>
</div>
</div>
</div>
{% endfor %}
{% endblock %}
The loop currently creates a new row for each item, which is why every card is stacking. It should only loop col, not row.
col-sm-3 means "use 3/12 space per column at sm and above" which means 4 columns (not 3) at the sm breakpoint and above. Use col-sm-4 to display 3 cards per row at sm and above, or just col-4 if you want 3 cards per row at all times.
{% extends 'base_content.html' %}
{% block content %}
<!-- don't loop here -->
<div class="row justify-content-center">
<!-- only loop the columns -->
{% for item in CATEGORY_CHOICES %}
<div class="col-sm-4"> <!-- not "col-sm-3" -->
<div class="card">
<div class="card-body">
<h5 class="card-title">{{ item.1 }}</h5>
</div>
</div>
</div>
{% endfor %}
</div>
{% endblock %}
I am currently working on a django blog. However, I am experiencing some difficulties with the size of the post thumbnails. Here's a picture:
What I marked in yellow is how the image should be filling the space. The width is fine, but the heigh isn't working well as you can see.
Here's the code:
{% extends 'base.html' %}
{% load static %}
{% block content %}
<style>
img {
height: 100%;
width: 100%;
}
</style>
<!-- Post-->
{% for obj in object_list %}
<div class="row d-flex align-items-stretch">
{% if not forloop.first and not forloop.last %}
<div class="image col-lg-5"><img src="{{ obj.thumbnail.url }}" alt="..."></div> #Here's the image
{% endif %}
<div class="text col-lg-7">
<div class="text-inner d-flex align-items-center">
<div class="content">
<header class="post-header">
<div class="category">
{% for cat in obj.categories.all %}
{{ cat }}
{% endfor %}
</div>
<a href="{{ obj.get_absolute_url }}">
<h2 class="h4">{{ obj.title }}</h2>
</a>
</header>
<p>{{ obj.overview|linebreaks|truncatechars:200 }}</p>
<footer class="post-footer d-flex align-items-center"><a href="#" class="author d-flex align-items-center flex-wrap">
<div class="avatar"><img src="{{ obj.author.profile_picture.url }}" alt="..." class="img-fluid"></div>
<div class="title"><span>{{ obj.author }}</span></div></a>
<div class="date"><i class="icon-clock"></i> {{ obj.timestamp|timesince }} ago</div>
<div class="comments"><i class="icon-comment"></i>{{ obj.comment_count }}</div>
</footer>
</div>
</div>
</div>
{% if forloop.first or forloop.last %}
<div class="image col-lg-5"><img src="{{ obj.thumbnail.url }}" alt="..."></div> #Here's the image
{% endif %}
</div>
{% endfor %}
</div>
</section>
It is <img>'s default behaivor to fill the whole width and height, often losing its aspect ratio.
The fact that it did not happen in your case, most likely is because you set object-fit: contain somewhere in your css.
You either remove object-fit: contain setting, or you can use
img {
height: 100%;
width: 100%;
object-fit: fill !important; # fill is the default value.
}
In one of the HTML files of my Django project, I have a div that contains a col-6 for an image and a col-6 for a text.
{% if automotives %}
{% for automotive in automotives %}
<div class="row">
<div class="col-6 mb-4 mb-md-0 my-5 pl-5">
<h3 class="font-weight-bold">{{ automotive.title }}</h3>
<p class="text-muted">{{ automotive.description|safe }}</p>
</div>
<div class="col-6 mb-4 mb-md-0 my-5 pr-5">
<div class=" overlay z-depth-1-half">
<img src="{{ automotive.cover.url }}" class="img-fluid" alt="cover">
</div>
</div>
</div>
{% endfor %}
{% endif %}
I read title and description and cover from the database.
I want to periodically change the order of image and text in each row.
I have no idea how to do it. and I don't know much about js or jquery.
any help is appreciated.
You can achieve this with flex, but I see that your question is django/jinja2 related so, this is how I would approach this problem:
Build a partial template like this
{% if image_right %}
<div class="row">
<div class="col-6 mb-4 mb-md-0 my-5 pl-5">
<h3 class="font-weight-bold">{{ automotive.title }}</h3>
<p class="text-muted">{{ automotive.description|safe }}</p>
</div>
<div class="col-6 mb-4 mb-md-0 my-5 pr-5">
<div class=" overlay z-depth-1-half">
<img src="{{ automotive.cover.url }}" class="img-fluid" alt="cover">
</div>
</div>
</div>
{% else %}
<div class="row">
<div class="col-6 mb-4 mb-md-0 my-5 pr-5">
<div class=" overlay z-depth-1-half">
<img src="{{ automotive.cover.url }}" class="img-fluid" alt="cover">
</div>
</div>
<div class="col-6 mb-4 mb-md-0 my-5 pl-5">
<h3 class="font-weight-bold">{{ automotive.title }}</h3>
<p class="text-muted">{{ automotive.description|safe }}</p>
</div>
</div>
{% endif %}
You can name this something like image_text.html.
This template contains a bit of duplicate code, but it is simple to understand.
If image_right variable is True (or set to any non null value), it will show the row with the image on the right.
If image_right variable is False, (or 0 or any other null value), it will show the image left (so, image on the left is the the default behavior in this case).
Then, in your main template, you can use this partial template you just built (image_text.html) like this, for example, if you want to switch image on left and right on each row:
{% if automotives %}
{% for automotive in automotives %}
{% include 'image_text.html' with automotive=automotive image_right=forloop.counter|divisibleby:2 %}
{% endfor %}
{% endif %}
forloop.counter is the index of your for loop (it starts from 1, user forloop.counter0 if you want a counter that starts from 0).
When forloop.counter is even, image_right in your partial template will be True, so it will show image on the right.
When forloop.counter is odd, image_right in your partial template will be False, so it will show image on the left.
Hope it helps. This may need some tweaks though.
I'm having a very hard time trying to solve this. I got a back-end working but problem is html and css. I'm trying to make it like this here;
picture on the far left, user name on top and text below the user name and next to picture which is also the style youtube use. Here's my try.
as you can see when text isn't too long it kinda works but when it gets big it alters the form. Also as for the reply comment, the whole thing is a mess. I moved things around but still won't do the job.
Here's my full code(I'm using django template language here as well) and you can see simplified version here https://jsfiddle.net/n9h7gy54/ (it might be better to see the one here because my full code is very messy)
<table class='table'>
{% for comment in comments %}
<tr>
<td>
<div class="wholeComment" style="width:100%; margin:auto; font-size:14px;">
<div class="profileImage" style="float:left;">
<img src="{{ comment.user.get_mugshot_url }}" height='48' width='48' />
</div>
<div class="comment_header" style="float:left;">
<div class="commentInfo">
{{ comment.user.user }}| <small>{{ comment.timestamp|timesince }} </small>
</div>
<div class="aboutComment">
<span style="margin:5px; word-break: break-all;">
{{ comment.get_comment }}</span>
</div>
<div class="comment_bottom" style="padding:3px;">
{% if user.is_authenticated %}
<div class="make_reply">
<a href='#' class='reply_btn'>reply</a>
<div class='reply_comment'>
<form method="POST" action='{% url "comment_create" %}'>{% csrf_token %}
<input type='hidden' name='post_id' id='post_id' value='{% url "comment_create" %}'/>
<input type='hidden' name='origin_path' id='origin_path' value='{{ comment.get_origin }}'/>
<input type='hidden' name='parent_id' id='parent_id' value='{{ comment.id }}' />
{% crispy comment_form comment_form.helper %}
</form>
</div>
</div>
{% endif %}
<div class="replyInfo">
{% if not comment.is_child %}
<div class="wholeReply">
{% if comment.comment_count %}
<a href='#' class='replies'>
view{{comment.comment_count}}reply</a>
{% endif %}
<div class="got_replies">
<ul style="list-style-type: none;">
{% for child in comment.get_children %}
<hr>
<li>
<div style="float:left;">
<img src="{{ child.user.get_mugshot_url }}" height='48' width='48'/> {{ child.user.user }}
</div>
<div style="word-break: break-all; ">
{{ child.get_comment }}</div>
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
{% endif %}
</td></tr>
{% endfor %}
</table>
If I understand you correctly, you're looking for
<div class="row">
<div class="col-xs-1">
<img src="{{ comment.user.get_mugshot_url }}"/>
</div>
<div class="col-xs-11">
<div class="row">
<div class="col-xs-12">
<p>
{{ comment.user.user }}
</p>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<small>{{ comment.timestamp|timesince }} </small>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<span>{{ comment.get_comment }}</span>
</div>
</div>
{% for child in comment.get_children %}
{% include 'commentrow.html' comment=child %}
{% endfor %}
</div>
</div>
You can save this snippet as a template called commentrow.html and it will work recursively for children, including it in your template the same way
{% for comment in comments %}
{% include 'commentrow.html' comment=comment %}
{% endfor %}
JSFiddle
The important part is the col-xs tags, since this will mean the columns don't wrap regardless of screensize.
I have been trying to adopt a single set of column styles that are used across my website, but the Liquid assign tag isn't working properly.
I only have one template so far, called default.html:
---
---
<!DOCTYPE html>
<html>
{% include header.html %}
<body>
{% include navbar.html %}
<div class="container">
<div class="row">
{% assign __align__col = col-sm-6 col-sm-offset-2 col-md-4 col-md-offset-4 %}
<p>Using align {{ __align__col }}</p>
<div class="{{ __align__col }}">
<div class="panel panel-default">
{% if page.title %}
<div class="panel-heading">
<h3 class="panel-title">{{ page.title }}</h3>
</div>
{% endif %}
<div class="panel-body">
{{ content }}
</div>
</div>
</div>
</div>
<div class="row">
<div class="{{ __align__col }}">
{% include footer.html %}
</div>
</div>
</div>
</body>
</html>
The problem resides in the {% assign __align__col = col-sm-6 col-sm-offset-2 col-md-4 col-md-offset-4 %} line, it doesn't seem to set the __align__col variable. I looked at the source, and it doesn't show up in the class attribute or in the <p> tag.
I have Bootstrap running to do the UI stuff, and it's hosted over here at GitHub Pages. Actual website is here.
I think I misunderstood the assign tag. It probably needs to be a string in there, like {% assign __align__col = "col-sm-6 col-sm-offset-2 col-md-4 col-md-offset-4" %}. I'm not using this anyways, so this is probably the best answer I have for this.