Splitting a square into four triangles using CSS styling

My current challenge involves creating a square comprised of 4 triangles of equal size, each with hover events. Here is the CSS I'm using to create the triangles:

.right, left, .top, .bottom {
    position: relative;
    width: 26px;
}

.right:before{
  position: absolute;
  display: inline-block;
  border-top: 26px solid transparent;
  border-right: 26px solid #eee;
  border-bottom: 26px solid transparent;
  left: 26px;
  top: 0px;
  content: '';
}

The issue I'm facing is that the triangles are stacking on top of each other, making only one triangle hoverable at a time. You can view an example here.

Currently, only the bottom triangle (hover at the bottom of the square) is responsive to hovering. What am I doing wrong? Are there any alternative methods to achieve this effect?

Answer №1

One key factor causing the hover effect to only work on the bottom triangle and not the others is due to the stacking order of the containers. The container of the bottom triangle appears above the containers of the other three, which limits the hover interaction to just that area.

Although utilizing the border trick generates triangle shapes, the underlying form remains a square. The appearance of triangles is achieved by making the adjacent borders transparent. Consequently, hovering over the shape targets the transparent regions of the bottom triangle rather than triggering the other triangles' respective hover events.

A suggestion would be to use SVG for such designs, although creating these shapes with CSS alone is feasible given the simplicity of this shape.

SVG:

In an SVG context, multiple triangles within a square can be created using polygon elements, each being individually hoverable. For distinct target links, enclosing the polygons in an a (anchor) tag is recommended.

The example includes anchor implementation for one triangle only

.square {
  height: 400px;
  width: 400px;
  overflow: hidden;
}
svg {
  height: 100%;
  width: 100%;
}
polygon {
  fill: aliceblue;
  stroke: crimson;
  stroke-linejoin: round;
}
polygon:hover {
  fill: cornflowerblue;
}
<div class='square'>
  <svg viewBox='0 0 100 100'>
    <a xlink:href='http://google.com'>
      <polygon points='5,5 50,50 95,5' />
    </a>
    <polygon points='5,5 50,50 5,95' />
    <polygon points='5,95 50,50 95,95' />
    <polygon points='95,5 50,50 95,95' />
  </svg>
</div>


CSS:

This CSS solution modifies the provided answer from here by web-tiki. A unique response is necessary due to the simplicity of the current shape, requiring less complexity compared to the initial case.

The square is divided into four identical hoverable triangles through the following steps:

  • The parent container, a square, features borders on all sides. This structural choice helps avoid the challenges associated with diagonal line placement in CSS-based triangles.
  • Four child elements are added within the container, each sized using Pythagoras theorem computation. These elements are positioned with their top left corner at the square's center, aiding in rotation effects.
  • All child elements undergo rotations to depict triangular shapes, with transform-origin set to top left for axis alignment with the square’s center when rotating.
  • The parent has overflow: hidden to conceal half of each triangle outside its boundaries.
  • Note that adding text directly to the triangles may pose challenges due to their rotated nature. Text content should ideally be placed in separate child elements counter-rotated appropriately.

Note: The demo script uses prefix-free library to eliminate browser prefixes requirements.

.square {
  position: relative;
  height: 200px;
  width: 200px;
  border: 2px solid crimson;
  overflow: hidden;
  transition: all 1s;
}
.top,
.left,
.right,
.bottom {
  position: absolute;
  height: calc(100% / 1.414);
  width: calc(100% / 1.414);
  top: 50%;
  left: 50%;
  border: 1px solid crimson;
  transform-origin: 0% 0%;
}
.right {
  transform: rotate(-45deg);
}
.bottom {
  transform: rotate(45deg);
}
.top {
  transform: rotate(-135deg);
}
.left {
  transform: rotate(135deg);
}
.square > div:hover {
  background: tomato;
}

/*Just for demo*/

.square:hover{
  height: 300px;
  width: 300px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='square'>
  <div class="top"></div>
  <div class="right"></div>
  <div class="bottom"></div>
  <div class="left"></div>
</div>

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

Issue with PHP/HTML header() function not directing to URL page

Situation: In my member database overview, users can click on an 'update member' link in a table that redirects them to a page displaying the data of the selected member. The URL receives the parameter lid.php?lidnummer=4 (or any other ID). On t ...

A step-by-step guide on uploading files from the frontend and saving them to a local directory using the fs and express modules

I'm considering using fs, but I'm not entirely sure how to go about it. Here's the setup: ejs: <form action="/products" method="POST"> <input type="file" name="image" id="image"> <button class="submit">Submit</but ...

Exploring the World of GiantBomb APIs

I have successfully created an account and obtained my API key. I am looking to implement a basic search functionality on my webpage, where users can enter a search query and click a button to display the game title and image. You can find more informatio ...

Toggle the visibility of an element with a single button click

Below is a snippet of my sample code: SAMPLE HTML CODE: <ul> <li class="item"> item 1 </li> <li class="item"> item 1 </li> <li class="item"> item 1 </li> <li class="item"> item 1 </li> <l ...

I'd love some clarity on the concept of stacking contexts

After encountering a bug with a non-clickable video player inside a jquery ui dialog, I resolved the issue by changing position:relative; to position:inherit; Other solutions included removing position:relative; altogether or adjusting the z-index of the ...

I can't seem to shake off this constant error. Uncaught TypeError: Unable to access property 'classList' of null

I am facing an issue with the "Contact Me" tab as it does not display its content when clicked. Here is the code snippet: <body> <ul class="tabs"> <li data-tab-target="#home" class="active tab">Home< ...

What is the best way to exchange configuration data among Javascript, Python, and CSS within my Django application?

How can I efficiently configure Javascript, Django templates, Python code, and CSS that all rely on the same data? For example, let's say I have a browser-side entry widget written in Javascript that interacts with an embedded Java app. Once the user ...

Preventing a sprite from going beyond the boundaries of a canvas with pure JavaScript - here's how!

I am in the process of developing a game using native JavaScript, HTML, and a touch of CSS. I have two blocks called Sprites that tend to keep moving off the canvas edges when they reach them. Question: How can I utilize native JS to prevent the sprites fr ...

The CSS is not displaying correctly on Safari and Chrome browsers in Mac OS

I'm having trouble with CSS not loading properly on Apple devices for a website I made. Despite maintaining all media query statements and style sheets separately, the display is not correct in MAC OS safari and chrome. However, everything looks fine ...

Calculate the total price using jQuery

I’m a beginner in JavaScript and I’ve hit a roadblock. I have a plus and minus button that adds up product quantities, but I need the total price to reflect this as well. Some products can only be purchased in multiples of 2, 5 or 10. Here is the HTML ...

What is the best way to center these icons vertically in my navigation menu using CSS?

My website has a navigation menu with third-party icon libraries (Material/FontAwesome) in use. I am facing an issue where the icons are not aligning vertically with the anchor text. Adjusting the font size of the icon to match the text results in it appe ...

Ways to designate a tab as active

Having trouble styling the active tab in my tabbed menu created with Bootstrap. The active class seems to only affect the first tab. How can I make it work for all tabs? Check out this screenshot for reference. Below is the code snippet: <script ...

Use flex-grow and flex-wrap to split elements onto separate lines

My parent div, ".tags", contains both links and a title. The parent div is styled with "display: flex;" and "flex-wrap: wrap;". I want the link elements to move onto a new line when they wrap, without being pushed to the right of the screen by the title. ...

Adjust the width of the table's td elements

I am looking to create a table similar to the one shown above. Here is my implementation. Please review my JSFiddle. HTML: <table border="0" id="cssTable"> <tr> <td>eredgb</td> <td><a href="self">0 ...

Challenges in using HAML5 Canvas for mathematical applications

Hey there! I'm currently working on utilizing the canvas element to form various shapes, but I've encountered a few challenges when it comes to the mathematical aspect. Issue 1: I need to calculate an angle that is relative to the preceding line ...

Enliven the transition between grid sizes

I'm currently working on a project using React and Material UI. Seeking assistance on how to implement an animation for changing the size of a grid item. By default, the item is set to sm={3}, but when a user hovers over it, I want it to change to sm ...

What is the proper way to execute a JavaScript function within a JavaScript file from an HTML file?

I have the following content in an HTML file: <!DOCTYPE html> <!-- --> <html> <head> <script src="java_script.js"></script> <link rel="stylesheet" type="text/css" href="carousel.css"> & ...

Canvas Frustratingly Covers Headline

Several months ago, I successfully created my portfolio. However, upon revisiting the code after six months, I encountered issues with its functionality. Previously, text would display above a canvas using scrollmagic.js, and while the inspector shows that ...

Changing the .load function based on user input

Can I replace a .load text with one that can be updated by a user using form input or similar method? My goal is to create a code that retrieves data using unique div IDs (specific to each employee) containing information within tables across various HTML ...

Styling <CardHeader> component with React and Material UI CSS

Incorporating React and Material UI, my goal is to arrange 3 divs within a <Card> <CardHeader/>, positioning them with left, center, and right alignment as illustrated below. The modification required is minor - I simply need to eliminate the ...