I'm working on a little electron.js project at the moment. I did not do any web development for a long time and have a lot of new things to learn. Here's a little report of my last experiment.
Context
I wanted to implement a kind of tab functionality in my application. I searched the web and found an elegant solution (imho) based on the ":target" pseudo class. As I had a long break from this project, I forgot my source... But it was something like this : https://www.sitepoint.com/css3-tabs-using-target-selector/
Here's is the current layout :
The behaviour is simple and well known : clicking on the little snippet at left top of the window switches the tab.
Note that I haven't worked on the UI yet (so it's basic and awful at the moment!!)
Code
HTML
The HTML code is basic:
<div class="tabs">
<div id="patientTab">
<a id="patientTabLink" href="#patientTab">Patients</a>
<div>The Patient Tab</div>
</div>
<div id="patientFileTab">
<a href="#patientFileTab">Medical file</a>
<div>The Patient medical file</div>
</div>
<div id="appointmentsTab">
<a href="#appointmentsTab">Appointments</a>
<div>The Appointments Tab</div>
</div>
</div>
There is a div container named "tabs". Inside we find 3 tabs : Patient, Patient File, and Appointments.
The tab selector is an anchor, and the tab content goes into another div. The anchor references the div you want to show.
CSS
div.tabs {
min-height: 7em;
position: relative;
line-height: 1;
z-index: 0;
height: calc(100% - var(--tabs-top-margin)) ;
margin-top: var(--tabs-top-margin);
}
div.tabs :target {
outline: none;
}
div.tabs > div:target > a {
border-bottom: 0.1em solid;
background: rgb(224, 224, 224);
}
div.tabs > div {
display: inline;
}
div.tabs > div > a {
color: black;
background: #CCC;
padding: 0.2em;
border: 0.1em outset;
border-bottom: 0.1em solid;
border-radius: 5px 5px 0px 0px;
text-decoration: none;
margin-right: -4px;
}
div.tabs > div:target > div {
position: absolute;
z-index: -1;
}
div.tabs > div:not(:target) > div {
position: absolute;
z-index: -3;
}
div.tabs > div > div {
background: #CCC;
left: 0;
top: 1.3em;
bottom: 0;
right: 0;
overflow: auto;
padding: 0.3em;
border: 0.1em outset ;
}
I won't dive into the details of each CSS definition. The trick here is to use the z-index property. The div.tabs > div:not(:target) > div is the default value, as you did not click a link yet, and sets the z-index at -3.
When you click on one of the tab selector, you activate the link. This activation sets the ":target" pseudo class on the div element.
The div.tabs > div:target > div takes over and set the z-index at -1, showing the right tab.
Set the "primary" tab
The first problem was that the last div was shown first.
I added this code to "force" a primary tab.
div.tabs > div#patientTab > div{
z-index: -2;
}
-2 is between ":target" (-1) and "not(:target)" (-3), giving a kind of priority to the tab of my choosing.
The reset problem
The second problem I met was that I could not find a way to reset the ":target" pseudo class easily.
When one chooses another patient, I want to display the first tab. But when I changed the content of the page, the focus stayed on the last selected tab.
I first choose this pure CSS solution to have the less javascript possible, but I finally came to the conclusion that javascript would be necessary in order to have some kind of control on the displayed tab.
I tried several things using JQuery, but I was unable to remove the ":target" pseudo class.
I was left with 2 possibilities :
- completely reload the page
- manage to simulate a click on the desired link
I chose the second solution with this very simple jQuery code :
function resetTarget(){
$('#patientTabLink')[0].click();
}
I struggled at first with the click() function not working but finally found a stackoverflow comment explaining that I needed to add the [0] in order to access to the DOM element, and not just the jQuery object. This gets the job done !
You can call the resetTarget() function where needed in your code when you want to reset the :target pseudo class.
That's it. I hope that this little trick will be helpful to some of you !