Tengo un sitio web de citas y muestro listas de usuarios con imágenes de perfil. Si el usuario no tiene una imagen de perfil, muestro una imagen específica. Aquí está el código:

@register.inclusion_tag(filename='accounts/profile_picture.html', takes_context=True)
def profile_picture(context, user, geometry, with_link=True, html_class=''):
    context = copy.copy(context)
    geometry_splitted = geometry.split('x')
    width = geometry_splitted[0]
    if (len(geometry_splitted) == 2):
        height = geometry_splitted[1]
    else:
        height = geometry_splitted[0]
    context.update({
        'user': user,
        'geometry': geometry,
        'width': width,
        'height': height,
        'with_link': with_link,
        'html_class': html_class,
    })
    return context

Profile_picture.html:

{% thumbnail user.photo.file geometry crop='center 20%' as image %}
    <img src="{{ image.url }}" alt="{{ user.name }}" width="{{ image.width }}" height="{{ image.height }}" class="img-fluid {{ html_class }}" />
{% empty %}
    <img src="{% static 'speedy-core/images/user.svg' %}" alt="" width="{{ width }}" height="{{ height }}" class="img-fluid {{ html_class }}" />
{% endthumbnail %}

Css:

.img-fluid {
  max-width: 100%;
  height: auto;
}

Pero el problema es que, debido a esto height: auto;, los usuarios sin una imagen de perfil tienen imágenes de perfil más altas que los usuarios con imágenes de perfil. Quiero mostrar a todos los usuarios con la misma altura y, si es necesario, mostrar un ancho más pequeño para los usuarios sin una imagen de perfil (que muestra speedy-core/images/user.svg como su foto de perfil). Si es posible, sin cambiar el archivo user.svg en sí mismo. ¿Cómo lo hago con CSS?

Editar: pensé en definir max-height para estas imágenes, pero no sé el valor exacto de max-height para definir que la altura de las imágenes sea la misma.

1
Speedy Match 4 may. 2020 a las 16:16

2 respuestas

La mejor respuesta

Incluí una sección Contexto adicional a continuación. Para los lectores primerizos, sugiero leer eso primero.

Solución

  • Creamos un placeholder-wrapper con el mismo aspect_ratio que geometry.
    Esto nos permite restringir al mismo height (resumen: el width está restringido por las columnas).
  • Centramos la imagen en placeholder-wrapper.

Profile_picture.html:

<!-- <img src="{% static 'speedy-core/images/user.svg' %}" alt="" width="{{ width }}" height="{{ height }}" class="img-fluid {{ html_class }}" /> -->
     <div class="placeholder-wrapper" style="padding-top: {{ aspect_ratio }}%;">
         <img src="{% static 'speedy-core/images/user.svg' %}" alt="" class="img-fluid {{ html_class }}" />
     </div>

User_tags.py:

def profile_picture(...):
    ...
    context.update({
        ...
        'width': width,
        'height': height,
        'aspect_ratio': float(height) / float(width) * 100,  # Add this
        ...
    })
    return context

CSS / speedy-core.css:

.profile-picture .placeholder-wrapper {
    position: relative;
}

.profile-picture .placeholder-wrapper > img {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translate(-50%, 0);
    width: auto;
    height: 100%;
}

Contexto adicional

  • Las imágenes de perfil se utilizan en <div class="col-sm-6 col-md-3 mb-0">.

    • Las capturas de pantalla a continuación muestran 4 columnas según col-md-3 pero la solución es receptiva.
    • width está restringido por las columnas; height: auto de Bootstrap's img-fluid.
  • Hay 2 tamaños intrínsecos (suposición: ancho ≥ alto).

    • Corregido - geometry (por ejemplo, 256x200) thumbnail de tamaño libre user.photo.file
    • Imagen de marcador de posición (32x32) user.svg

Antes:

before

Después:

after

1
aaron 7 may. 2020 a las 11:00

En lugar de utilizar height:auto mencione una altura específica como height:500px, hará todas las imágenes del mismo tamaño. Y puede usar consultas de medios para mencionar la altura en diferentes tamaños de pantalla.

1
Prateek Gupta 5 may. 2020 a las 04:44