Utilizing CSS3 Pseudo Elements for Styling a Graph

I'm struggling to achieve the desired look of my ancestor chart using an unordered list format. Initially, I borrowed code from CSS3 Family Tree, but found it to be more like an organizational chart rather than a family tree.

For testing purposes, here's a snippet of my HTML and CSS:

.tree ul {
  padding-top: 20px;
  position: relative;
}
.tree li {
  display: inline-block;
  white-space: nowrap;
  vertical-align: top;
  margin: 0 -2px 0 -2px;
  text-align: center;
  list-style-type: none;
  position: relative;
  padding: 20px 5px 0 5px;
}
/*We will use ::before and ::after to draw the connectors*/

<!-- Remaining CSS styles are omitted for brevity -->

<div class="tree">
  <ul>
    <!-- List items continue here -->
</div>

The provided CSS is based on CSS3 Family Tree, resulting in a chart that looks like this:

https://i.sstatic.net/7fUbN.jpg

However, I need it to be displayed upside down, with "Self" at the bottom and the earliest generation at the top.

I managed to reverse the box order by tweaking the list structure, but I'm struggling to adjust the CSS to get the connectors aligned correctly as shown in this example:

https://i.sstatic.net/hdVEI.jpg

Does anyone know how I can modify the ::before and ::after pseudo elements to achieve my desired layout? Or should I approach this problem differently?

(Alternatively, placing "Self" on the left and the earliest generation on the right might be a viable solution if it yields better results.)

Answer №1

To achieve the desired arrangement, it is possible to restructure the HTML and apply some adjustments in the css code (such as changing padding positions, adjusting border-radius to fit the new layout, and switching top & bottom positions). By doing so, the layout can be successfully modified:

.tree ul {
  padding: 0 0 20px;
  position: relative;
}

.tree li {
  display: inline-block;
  white-space: nowrap;
  vertical-align: bottom;
  margin: 0 -2px 0 -2px;
  text-align: center;
  list-style-type: none;
  position: relative;
  padding: 0 5px 20px 5px;
}


/*Utilizing ::before and ::after for creating connectors*/

.tree li::before,
.tree li::after {
  content: '';
  position: absolute;
  bottom: 0;
  right: 50%;
  border-bottom: 1px solid #ccc;
  width: 50%;
  height: 20px;
}

.tree li::after {
  right: auto;
  left: 50%;
  border-left: 1px solid #ccc;
}


/*Removing left-right connectors from elements with no siblings*/

.tree li:only-child::after,
.tree li:only-child::before {
  display: none;
}


/*Eliminating space above single children nodes*/

.tree li:only-child {
  padding: 0;
}


/*Removing left connector from first child and 
right connector from last child*/

.tree li:first-child::before,
.tree li:last-child::after {
  border: 0 none;
}


/*Reintroducing vertical connector to the last nodes*/

.tree li:last-child::before {
  border-right: 1px solid #ccc;
  border-radius: 0 0 5px 0;
  -webkit-border-radius: 0 0 5px 0;
  -moz-border-radius: 0 0 5px 0;
}

.tree li:first-child::after {
  border-radius: 0 0 0 5px;
  -webkit-border-radius: 0 0 0 5px;
  -moz-border-radius: 0 0 0 5px;
}


/*Adding downward connectors from parent nodes*/

.tree ul ul::before {
  content: '';
  position: absolute;
  bottom: 0;
  left: 50%;
  border-left: 1px solid #ccc;
  width: 0;
  height: 20px;
}

.tree li a {
  border: 1px solid #ccc;
  padding: 5px 10px;
  text-decoration: none;
  color: #666;
  font-family: arial, verdana, tahoma;
  font-size: 11px;
  display: inline-block;
  border-radius: 5px;
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
}
<div class="tree">
  <ul>
    <li>
      <ul>
        <li>
          <ul>
            <li><a href="#">Grandfather</a></li>
            <li><a href="#">Grandmother</a></li>
          </ul>
          <a href="#">Father</a>
        </li>
        <li>
          <ul>
            <li><a href="#">Grandfather</a></li>
            <li><a href="#">Grandmother</a></li>
          </ul>
          <a href="#">Mother</a>
        </li>
      </ul>
      <a href="#">Self</a>
    </li>
  </ul>
</div>

You can also view a visual representation of the modified tree structure in this jsfiddle link.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Create a stylish design with Bootstrap 3.0 featuring a full-width color background and compact columns perfectly centered on the

As I ventured into creating a business theme with stripes, akin to the one developed by W3Schools and accessible here, I encountered a particular challenge. The layout consisted of horizontal sections with varying background colors. My main concern was th ...

Ruling out the use of jQuery script within a dynamic framework

I have a unique jQuery script to create a "Back to Top" functionality: <script type="text/javascript"> $(document).ready(function(){ // Initially hide the #TopButton $("#TopButton").hide(); // Fade in the #TopButton on scrolling $(function () { ...

Assistance required: The database is not found upon page reload. How can this be resolved?

My HTML5 code has created a database with create, add, delete, and print operations. However, the ObjectStore is re-created every time I load the page, and the additional values stored are not present upon reloading the page. What could be wrong with my ...

Detecting unutilized space in a collection of divs with varying sizes using JavaScript and CSS

To better understand my issue, I created a StackBlitz demo: https://stackblitz.com/edit/angular-aqmahw?file=src/app/tiles-example.css Screenshot My tiles can have four different widths (25%, 50%, 75%, 100%). The tiles must fit on only two lines, so if a ...

What is a method to raise the height when scrolling down without reducing it when scrolling up?

For my One Page project, I want a DIV element to increase in height when scrolling down, but maintain that increased height when scrolling up. Currently, I am utilizing JQuery with the code snippet below: $(function(){ $(window).scroll(function() { ...

Adjusting the image to fit the container based on its shorter side, regardless of the image's orientation

I have a square container with a predetermined size. I want to place an image inside the container so that its smaller side fits perfectly with the parent container, while the larger side extends beyond the edges of the container without distorting the ima ...

Removing the Shadow from Material UI's Dialog Box

I am currently struggling with the Material UI dialog component that displays information about a location marker. My issue is with disabling the unattractive box shadow that surrounds the component. Despite setting box-shadow: none and trying different so ...

The Three JS on the website is error-free, yet it fails to function properly

I've been attempting to replicate the example three.js page on my own website, complete with a canvas for the 3D animation. However, I'm encountering an issue where nothing is displayed, despite no errors appearing. I've tried troubleshootin ...

Challenges with basic contact form

Apologies in advance for any beginner mistakes, as I am venturing into creating an HTML/PHP contact form for the first time. Despite researching similar problems faced by others, I have not come across a solution. The main issue is that the email is not b ...

Hide panel when button is clicked - bootstrap

Is it possible to make a panel collapse by clicking a regular bootstrap button? Below is the code snippet: <div class="panel panel-primary" style="border-color: #464646;"> <div class="panel-heading" style="border-color: #BBBBBB; height: 35px; ...

Unable to establish proper functionality of username variables in Node.js chat application

For my latest project, I am developing a chat application in node.js following a tutorial from socket.io. The main objective of the app is to allow users to input their username along with a message, which will then be displayed as "username: message" in t ...

Adding a border in jQuery or Javascript to highlight empty form fields

After making the decision to dive into the world of Javascript, I've been dedicated to perfecting a script that will encase empty elements with a border right before the user submits a form. My ultimate goal is to implement live validation in the form ...

Setting variables in AngularJS services without encountering JavaScript undefined errors

After developing an AngularJS module, I attempted to link a service and use it to share variables across the application. While most things are functioning properly, I encountered an issue when trying to set submenu[1] to an object. The error message sta ...

What is the process for customizing the color of the focused label in Material UI through styling?

Recently, I delved into the world of JSS for styling and ran into an intriguing issue. My goal was to modify the color of a label in an InputLabel component when it is in focus state. After some tinkering, I managed to achieve this using the code snippet b ...

Tips on positioning a dropdown item to the far right of the page

I need help moving the language switcher and its items to the right side of the page. I tried using ml-auto but it didn't work for me. Whenever I try to adjust the position with padding-left, all the items end up in the center of the page. Any suggest ...

The functionality of dropdown menus in the Bootstrap 5 navbar is currently experiencing issues

I recently updated my Bootstrap from v5.2.2 to v5.2.3 and now the dropdown menus in my navbar are not working properly. They do not drop down as they should, instead, they remain stationary. Can someone please help me figure out what I am doing wrong? & ...

Accessing a specific segment of HTML using Java

Attempting to navigate through a bunch of HTML, I'm aiming to isolate specific sections. I'm specifically looking to retrieve 'THISISTHEBITIWANT' from the following HTML code. <li class="aClass"> <a href="example/THISISTHEB ...

Fixed header in a div, allowing content to scroll when hovering over the header

How can I ensure that the header remains fixed at the top while allowing the content to scroll when hovered over? The current issue is that when a user hovers over the header and tries to scroll, the content does not move. body { margin: 0; ...

What is the method for displaying the word '<head>' within a <p> element in HTML code?

My HTML page contains a simple <p> tag. Within this tag, I am attempting to display some text in the following manner: Insert this code snippet into the website header, between <head> and </head>, to activate the functionality notice. ...

Is it possible to utilize X-Y coordinates as repositories for values beyond just X-Y coordinates themselves?

I am in the process of creating a tile-based grid and I need to expand the X-Y coordinates to include additional values for determining characteristics of each tile, such as resources (for example, food, water, stone, lumber) within a game context. Conside ...