How to select a selector when a class does not exists - html

I have a doubt about the "sibling selectors" for CSS.
This is the situation:
if in some countries we can show the header but in other countries must not show the header, for example:
<!-- USA page -->
<div class="body">
<div class="header">HEADER</div> <!-- it exists -->
<div class="wrapper">BODY</div>
</div>
<hr>
<!-- Canada page --> <!-- does not have header -->
<div class="body">
<div class="wrapper">BODY</div> <!-- I want to modify this wrapper -->
</div>
I am not sure if it's possible because I can't create a new style for the <div class="wrapper">BODY</div> only for Canada because it's one template for all countries.
it's a twig template
<div class="body">
{% if show-header %} <!-- if true show -->
<div class="header">HEADER</div>
{% endif %}
<div class="wrapper">BODY</div>
</div>
so...I need a purely CSS solution... How I can have a specific style to apply for <div class="wrapper">BODY</div> if the <div class="header">HEADER</div> does not exist in Canada. let's say to change the color of the BODY but not for USA.
I thought that with selector to the :not() pseudo-class like so:
:not(.printable) {
/* Styles */
}
but, what is the approach?

I'm not a pro in twig, but you can play around with conditional classes:
<div class="body">
{% if show-header %} <!-- if true show -->
<div class="header">HEADER</div>
{% endif %}
<div class="{{ country == 'Canada' ? 'wrapper-canada' : 'wrapper-usa' }}">BODY</div>
</div>
Or even use function where you will identify country and return corresponding class name.

If I understand your question, a sibling selector would still work for you. Your sibling selector (the presence of .header) would be an override.
So something like this:
.body .wrapper {
color: red; // Default color
}
.body .header + .wrapper {
color: blue; // Override default color when sibling exists
}
JSFiddle: https://jsfiddle.net/fch3drve/

Related

Setting only categories to be view on homepage/set amount of images

<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Gallery</title>
<!-- CSS only -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.1/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-iYQeCzEYFbKjA/T2uDLTpkwGzCiq6soy8tYaI1GyVh/UjpbCx/TYkiZhlZB6+fzT" crossorigin="anonymous">
<style>
.image-thumbnail {
height: 200px;
object-fit: cover;
}
.container {
margin-left: 1;
}
.h1 {
text-align: center;
}
.list-group-item a {
text-decoration: none;
color: black;
}
</style>
</head>
<h1 class="text-center m-5 p-3 mb-2 bg-light text-secondary">CHARLIES LIFE</h1>
<body class="m-5">
<div class="container">
<div class="row">
<div class="col-md-3 mt-2">
<div class="card">
<div class="card-header">
Categories
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item">
All
</li>
{% for category in categories %}
<li class="list-group-item">
<a href="{% url 'gallery' %}?category={{category.name}}">{{category.name}}
</a>
</li>
{% endfor %}
Add Photo
</ul>
</div>
</div>
<div class=" col-md-9">
<div class="row">
{% for photo in photos %}
<div class="col-md-4">
<div class="card my-2">
<img class="image-thumbnail" src="{{photo.image.url}}" class="card-img-cap"
alt="...">
<div class="card-body">
<p class="card-text text-center">{{photo.category.name}}</p>
</div>
<div class="d-grid gap-2">
<a href="{% url 'photo' photo.id %}" class="btn btn-dark m-1"
type="button">View</a>
</div>
</div>
</div>
{% empty %}
<h3> No Photos...</h3>
{% endfor %}
</body>
</html>
Hi, I'm currently trying to make a photo blog to record the life of my son with photos as he grows. The above is my code for the "home" page (name as gallery).
So at the moment I have a for loop which adds a "card" class to my gallery page every time I upload an image.
Ideally I'd like to make it so it only showed each category I create with only one picture from that category rather than showing every picture I upload to the website. I just didn't think a head on how many photos I would upload and the home page will just turn into a HUGE photo dump.
If any one has any ideas how I could accomplish this or any other recommendations it would be greatly appreciated.
TYIA
Correct me if i'm wrong, but what i think you're trying to accomplish is to have different section i.e. 'young', 'teenager', 'adult' or something like that, and only show images in those sections with the section name as a tag in the image itself? If that is the case, you can do something like this:
{% for photo in photos %}
{% if photo.tag == young %}
<h1>Show young images here</h1>
{% elif photo.tag == teenager %}
<h1>Show teenage images here</h1>
{% elif photo.tag == adult %}
<h1>Show adult images here</h1>
{% else %}
<h1>No photo's yet</h1>
{% endif %}
{% endfor %}
alternatively, you can do this in your views and serve different images to different templates if you wish to do so.
It would look something like this:
def teenageImages(request):
teenageImage = Image.objects.raw("SELECT * FROM
photos WHERE tag = 'teenager' ")
template = loader.get_template('teenager_photos.html')
context = {
'photos': teenageImage
}
return HttpResponse(template.render(context, request))
You can also go a different route and use filter, more information on filter can be found here.
EDIT for bootstrap cards
Here is an example Github Repo on bootstrap cards with image (without a link) my webpage repo
You can clone this repo and look around in it, that way maybe you can get some inspiration / ideas on how to do certain things.
Alternatively, you can use something like Wagtail for this, I have also made a Github repo regarding that, which can be found here
I suggest that you look at the RoutablePageMixin of the Wagtail CMS (Django based), see documentation here. With it you could make your home page accept the category as a variable like the following URL is representing: davidsonsblog.com/category/foobar
Than you could define a queryset filtered by category and ordered randomly (e.g. by the queryset method .order_by('?')). If you only want to show one image of it, add the .first() method to the queryset.
The menu would generate the links accordingly.

Hightlight buttons on click with CSS

I have a multiple selection and would like to be able to click on it to manage the answers on a /getmatch page. At the moment I have no visual cue that I have selected things:
[]]1
So how to make the selection of multiple items responsive?
Here is the code from the page that gives these buttons:
{% extends "todo/base.html" %}
{% block content %}
<style>
.elements {
display: block;
}
ul.items {
display: flex;
margin: 0;
padding: 0;
list-style: none;
}
li.item {
flex: 1 0 20%;
padding: 8px;
margin: 2px;
border-radius: 8px;
border: 1px solid rgba(61, 86, 233, 0.3);
text-align: center;
}
.col {
display: flex;
flex-direction: column;
align-items: center;
}
</style>
<!-- Header -->
<header class="intro-header">
<div class="container">
<div class="col-lg-5 mr-auto order-lg-2">
<h3><br>Tell me something about you... </h3>
</div>
</div>
</header>
<!-- Page Content -->
<section class="content-section-a">
<div class="container">
<dt>
<span>Pick the keywords you want to express when wearing perfume</span>
</dt>
<form action = "/getmatch" method="POST">
{% for keyword in keywords %}
<div class="elements">
<ul class="items ">
<li class="item col-xs-6 col-sm-3 col-md-3 col-lg-3">
<div class="box">
<div data-toogle="buttons" class="col">
<span>{{ keyword.title }}</span>
</div>
</div>
</li>
</ul>
</div>
{% endfor %}
{% csrf_token %}
<button type="submit">Envoyer</button>
</form>
</div>
</section>
<!-- Bootstrap core JavaScript -->
<script src="static/vendor/jquery/jquery.min.js"></script>
<script src="static/vendor/popper/popper.min.js"></script>
<script src="static/vendor/bootstrap/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/flexboxgrid/6.3.1/flexboxgrid.min.css" type="text/css" >
{% endblock %}
I tried to add things in the balisa .
button:hover{background-color:orange;}
button:focus{background-color:red;}
But it didn't modified anything
I can't add a comment since i don't have the required rep points (new to stack overflow, sorry if this isn't allowed), but I am not sure what you're trying to do, if you want to give a visual cue that a button has been selected for more than one button at a time, you need to grab the list of buttons, add an event listener on click that toggles a class on/off, then add styling to that class, so that when the item has that class it has a specific style.
Edit on how to do that:
P.S i've never used Django, but i think you should do this, since the way you're doing it is generating a ul for each keyword
<form action = "/getmatch" method="POST">
<div class="elements">
<ul class="items ">
{% for keyword in keywords %}
<li class="item col-xs-6 col-sm-3 col-md-3 col-lg-3">
<div class="box">
<div data-toogle="buttons" class="col">
<span>{{ keyword.title }}</span>
</div>
</div>
</li>
{% endfor %}
</ul>
</div>
{% csrf_token %}
<button type="submit">Envoyer</button>
</form>
Now you need to select the list elements, an easier way to do this would be something called event delegation https://javascript.info/event-delegation
so create a script tag/or file and import it, inside your script you neeed the following :
//Select the UL list
const myItemsList = document.querySelector(".items");
//function passed to event listener as callback, toggles the selected class if the target is a list
const toggleListClass = (event) => {
let target = event.target;
if (target.tagName !== "li") return;
target.classList.toggle("highlight");
};
//Add an event listener to the ul list
myItemsList.addEventListener("click", toggleListClass);
Now in your css add a selector for class hightlight
.hightlight {
color: whatever
}

How to exclude an item from the search?

I have a search for items. The block in which the value is searched consists of several elements. I need to exclude the last item from the search. Those. so that this element is not affected, except for the rest.
I tried like this
$('.blog_content_item').not('.last').each(function() {...});
and
$(".blog_content_item:not('.last')").each(function() {...});
Does not help. Both that and that is not true on syntax. Please tell me how to exclude the "last" element from the search. Thank.
$('.blog_content_item').each(function() {
if($(this).text().toLowerCase().indexOf(value) === -1) {
...
return;
} else {
...
}
});
<div class="blog_content_item">
<div class="first">
<div class="middle">
<div class="last">
</div>
This might do the trick for you
Sample HTML
<div class="blog_content_item">
<div class="first">First</div>
<div class="middle">Middle</div>
<div class="last">Last</div>
</div>
Script
$('.blog_content_item >div:not(:last-child)').each(function () {
// your awesome stuffs here
console.log($(this).text());
})
Using :not() filter with descendant selector
https://api.jquery.com/descendant-selector/
A descendant of an element could be a child, grandchild,
great-grandchild, and so on, of that element.
console.log($('.blog_content_item :not(.last)').get())
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="blog_content_item">
<div class="first"></div>
<div class="middle"></div>
<div class="last"></div>
</div>

Unexpected behavior with the :hover CSS selector (Angular)

I've got a menu with 3 levels of deepness. It starts with the categories, then the subcategories, and after all, the final links. Some of these links are already in the second or even the first level, but that's not a problem. The menu is working fine.
The problem is that I'm trying to make it look fancy, so I added to each div a class that designates the menu level. You can see the full Angular template here. Mind that these classes are the "lvl0", "lvl1", "lvl2":
<div class="menu-container">
<div class="row header">
<img class="logo" src="../../../assets/menu-header.PNG">
</div>
<div class="row menu-btn">
<div class="inner-menu-btn" (click)="openMenu()">
<span class="menu-span" [#menuStringAnim]="active">MENU</span>
<i class="fa fa-bars menu-icon" [#menuIconAnim]="active"></i>
</div>
</div>
</div>
<div class="menu-list" [#menuListAnim]="active">
<div class="row row-fix lvl0" *ngFor="let category of getCategories()" (click)="openCategory(category)">
<div class="little-menu-bar-toplvl" *ngIf="categoriesNavigator.lvl0 == category.key"></div>
<span class="menu-top-level">{{ category?.title?.toUpperCase() }} </span>
<div *ngIf="categoriesNavigator.lvl0 == category.key">
<br>
<div class="row row-fix lvl1" *ngFor="let subcategory of getSubcategories(category.key)" (click)="openSubcategory(subcategory)">
<div class="little-menu-bar-midlvl"></div>
<span class="menu-second-level">{{ subcategory?.title?.toUpperCase() }} </span>
<div *ngIf="categoriesNavigator.lvl1 == subcategory.key">
<br>
<div class="row row-fix lvl2" *ngFor="let thirdLevel of getThirdLevel(category.key, subcategory.key)" (click)="openUrl(thirdLevel)">
<div class="little-menu-bar-lowlvl" *ngIf="categoriesNavigator.lvl0 == category.key"></div>
<span class="menu-third-level">{{ thirdLevel?.title?.toUpperCase() }} </span>
</div>
</div>
</div>
</div>
</div>
</div>
So these classes are very simple. I'm not very good at CSS (I prefer designing logic rather than designing), and maybe I'm doing some stupid thing here:
.lvl0 :hover{
color: orange;
}
.lvl1 :hover{
color: orange;
}
.lvl2 :hover{
color: orange;
clear: both;
}
So the behavior works nice for first level, but as you can see, all the rows with the second level get highlighted instead of just the one I'm hovering on:
Same happens with the third level.
Do you have any idea on what I'm doing wrong? I'm adding the Angular tag just in case it has something to do with my template code. Thank you!
The problem is that you have applied the style to your div and as the divs are nested, the styles will cascade and turn everything inside it the colour - you can try to apply the styles directly to the spans to avoid this. Also I have removed the space before your hover colon
.lvl0:hover>span { /* leave hover on div but style the span */
color: orange;
}
.lvl1:hover>span {
color: red;
}
.lvl2:hover>span {
color: green;
}
<div class="lvl0">
<span>test 0</span>
<div class="lvl1">
<span>test 1</span>
<div class="lvl2">
<span>test 2</span>
</div>
</div>
</div>
The :hover is basically propagating down to other levels. Do not use CSS on the parent directly. Instead, use it on something like span etc.
Check pen here to solve your issue. In your case, you can have <div> tag too instead of the span which closes there and is basically a sibling of next level.
.lvl:hover {
//common for all
color: orange;
}

Make a div-row collapse in html/css/django

I have recently designed a really small django template looking like this :
The html code looks like this :
{% for category in categories %}
<div class="row">
<div class="column">
<h3>{{ category }}</h3>
<ul>
{% for elem in elems %}
<li><a href=...>{{ elem }}</a></li>
{% endfor %}
</ul>
</div>
</div>
{% endfor %}
And the CSS code :
.row:before,
.row:after {
content: " ";
display: table;
}
.row:after {
clear: both;
}
.column{
width: 50%;
}
I would like to have the rows to collapse if there is enough space.
In my example, I would like the Test column to go just behind the Pet one (only separated by the padding).
Is there any css property which could help me achieving this ? Or should I change my approach ?
Thanks !
The divs have no defined width. They will take up the entire page such that there is no horizontal room left. What you want is a responsive design that changes that width based on the size of the boxes, and the size of the screen.
Using the #media selector to limit a specific style to the size of the current browser window will allow the size of the divs to respond as you desire:
#media screen and (max-width : 600px) {
.box {
width: 50%;
}
}
#media screen and (min-width : 601px) {
.box {
width: 33.3%;
}
}
JS Fiddle
Hope that helps!
EDIT: Having read your comments I now see what you mean. Saying collapse confused me and I assumed you were asking for something dynamic.
The best way to solve this is to prioritise columns over rows. It's not a true table so they aren't even rows exactly.
<div class="column">
<div class="row">
<h3>Drinks</h3>
<ul><li>item 1</li><li>item 2</li></ul>
</div>
<div class="row">
<h3>Food</h3>
<ul><li>item 1</li><li>item 2</li></ul>
</div>
</div>
<div class="column">
<div class="row">
<h3>Pet</h3>
<ul><li>item 1</li></ul>
</div>
<div class="row">
<h3>Test</h3>
<ul><li>item 1</li><li>item 2</li></ul>
</div>
</div>
Using the following CSS will give the desired result.
.column {
width:50%;
float:left;
}
Using your code this would equate to:
{% for category in categories %}
<div class="column">
<div class="row">
<h3>{{ category }}</h3>
<ul> {% for elem in elems %}<li><a href=...> {{ elem }}</a></li>{% endfor %}</ul>
</div>
</div>
{% endfor %}
This answer has gotten quite long, I apologise!
New JS FIddle