Use a rotate transformation to correctly adjust the hover effect on a right-angled triangle

I am looking to design a triangle that resembles the red triangle in the image below:

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

My attempt at creating this triangle using CSS is as follows:

HTML:

<div class="div-1"></div>
<div class="div-2"></div>
<div class="div-3"></div>                    

CSS:

.div-1 {
    position: absolute;
    bottom: 0; left: 0;
    border-bottom: 385px solid #222;
    border-right: 175px solid transparent;
    width: 0;
    z-index: 5;
    pointer-events:none;
}

.div-2 {
    position: absolute;
    bottom: 0; left: 45px;
    border-bottom: 285px solid #ED3237; 
    border-right: 130px solid transparent;
    width: 0;
    z-index: 5;    
}

.div-3 {
    position: absolute;
    bottom: 0; left: 45px;
    border-bottom: 286px solid #222;
    border-right: 105px solid transparent; 
    width: 0;
    z-index: 5;
    pointer-events:none;        
}

I successfully created the triangle. You can view it on JSFiddle

Now, I want to change the color of the triangle to blue when hovered over.

To achieve this effect, I added the following CSS:

.div-2:hover{
    border-bottom: 285px solid blue; 
}

Although it initially appeared to work well, upon closer inspection, there was an issue. The color of the triangle changed even when hovering over the transparent area of .div-2, which is not desired. I only want the color to change when hovering over the visible (red) part of .div-2.

After researching online, I learned that using rotate transform instead of borders for the div might be a better approach. However, I could not find a suitable tutorial on creating right angled triangles with different widths and heights like the one mentioned above. Hence, I decided to ask for help. My question is: How can I create a triangle similar to the one shown in the image using rotate transform and CSS3 properties?

Update:

Though SVG is a simple solution, I prefer achieving this with CSS as I also plan to conceal the bottom part of the carousel, as depicted here: https://i.sstatic.net/JUm6e.jpg

Answer №1

Respectfully, the request you've made seems a bit confusing. In my opinion, it's not necessary to ask for instructions on how to achieve a specific outcome using a particular technique.

Coding is all about following conventions.
It ultimately comes down to choosing which conventions to follow in order to achieve the desired display result in different browsers. The actual technique or language used doesn't matter as long as it produces the intended result without affecting other functionalities.

In response to your question, controlling the hover state of an element while hovering over one border but not the other can be tricky.

One approach could involve adding a mask to the element to limit pointer events. However, why not use the mask for display purposes from the start?

Here's a suggestion on how to address this layout:

.image-container {
  background-color: #222;
  position: relative;
}

.image-container img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  -webkit-clip-path:  polygon(0 0, 73% 0, 100% 50%, 100% 100%, 27% 100%);
  clip-path:  polygon(0 0, 73% 0, 100% 50%, 100% 100%, 27% 100%);
}

l-border,
r-border {
  position: absolute;
  height: 100%;
  width: 100%;
  background-color: #600;
  top: 0;
  transition: background-color .5s cubic-bezier(.5, 0, .3, 1);
}

l-border:hover,
r-border:hover {
  background-color: red;
}

l-border {
  -webkit-clip-path: polygon(0 0, 24% 100%, 27% 100%);
  clip-path: polygon(0 0, 24% 100%, 27% 100%);
}

r-border {
  -webkit-clip-path: polygon(73% 0, 100% 50%, 76% 0);
  clip-path: polygon(73% 0, 100% 50%, 76% 0);
}

body {
  margin: 0;
}
/* changing both borders when hovering image 
  just showing you it's possible */
.image-container img:hover ~ * {
  background-color: #f50;
}
<div class="image-container">
  <img src="https://unsplash.it/1200/450" />
  <l-border></l-border>
  <r-border></r-border>
</div>

Depending on image ratio or responsiveness, using px instead of % might be preferable:

.image-container img {
  -webkit-clip-path: polygon(0 0, calc(100% - 150px) 0, 100% 50%, 100% 100%, 150px 100%);
  clip-path: polygon(0 0, calc(100% - 150px) 0, 100% 50%, 100% 100%, 150px 100%);
}

l-border {
  -webkit-clip-path: polygon(0 0, 130px 100%, 150px 100%);
  clip-path: polygon(0 0, 130px 100%, 150px 100%);
}

r-border {
  -webkit-clip-path: polygon(calc(100% - 130px) 0, 100% 50%, calc(100% - 150px) 0);
  clip-path: polygon(calc(100% - 130px) 0, 100% 50%, calc(100% - 150px) 0);
}

Personally, I find that using tools like Clippy to quickly generate basic shape polygons and then fine-tuning them in-browser is an efficient strategy for achieving the desired visual effect.


It's worth mentioning that clip-path currently has around 88.42% support. At present, the clip-path property isn't fully supported by all browsers, so it's important to keep compatibility in mind.

Answer №2

I did my utmost https://codepen.io/CrUsH20/pen/owWeNo

If you want to switch the stylus preprocessor in the settings, you can view it as pure CSS. Just click on the down arrow in the middle block and choose View compiled CSS.

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

Expanding Div Heights that Adjust to the Browser's Width

Looking to set up a responsive height for a div, almost there but facing some distortion when resizing the browser. Here is the fiddle file for reference: https://jsfiddle.net/td5n8ky9/10/ The issue lies in the bottom 2 divs - aiming for a grey bar the wi ...

What could be causing my JavaScript calculator to malfunction?

I can't seem to figure out why my calculator is malfunctioning and I'm at a loss as to what the issue might be. I even searched on forums like stackoverflow but couldn't find a solution. It seems like there could be an error in the JavaScrip ...

Navigating pages in tinymce editor

Currently, I have implemented TinyMCE as the editor for my PHP-based website. However, I am facing a challenge in integrating pagination within the editor. My goal is to allow users to input long content that will be displayed across multiple pages inste ...

Error encountered when transitioning to TypeScript: Unable to resolve '@/styles/globals.css'

While experimenting with the boilerplate template, I encountered an unusual issue when attempting to use TypeScript with the default NextJS configuration. The problem arose when changing the file extension from .js to .tsx / .tsx. Various versions of NextJ ...

Set the title attribute according to the content of the <p> tag

Recently, I encountered a situation where I had numerous p tags with a specific class (let's call it .text). My task was to include the title attribute containing the text of each tag. For example: <p> Hello, world </p> This would resul ...

What is the best way to align text in the center of a button?

When creating custom buttons in CSS using <button>, I noticed that the text appears to be centered both horizontally and vertically across all browsers without the need for padding, text-align, or other properties. Simply adjusting the width and heig ...

Switch between various div elements

Looking for a way to toggle between different divs? Here's the scenario: You have a sidebar with a set of buttons. Upon entering the page, you only want the div containing the button group to be visible. However, when a specific button (e.g. Info) is ...

What is the method for creating a checkbox in CSS that includes a minus symbol inside of it?

Can you create a checkbox with a minus "-" symbol inside using just html and css? I attempted to achieve this with JavaScript by using: document.getElementsByTagName("input")[0].indeterminate = true; However, the requirement is to accomplish this using ...

Is there a way to prevent on-click errors in ReactJS that someone can share with me?

The onclick listener was expected to be a function, but instead received a value of string type. getListener@http://localhost:3000/static/js/bundle.js:18256:15 accumulateSinglePhaseListeners@http://localhost:3000/static/js/bundle.js:22846:39 <button on ...

Tips for utilizing PrependTo dynamically on every element

I am facing a requirement that involves prepending an element with a specific class to its sibling with another class. While I have managed to accomplish this for the first occurrence, it seems to fail for all other elements within the same div. Below is t ...

The hover and active effects are malfunctioning

I can't understand why the default color for the "a" element is set to #2bb673 instead of #222. What mistake did I make? I am also using Bootstrap. <div class="our-work"> <a href="#our-work" class="our-work">Our Work</a> ...

Integrates an interactive feature within the select tag (<select>)

I'm struggling with creating a drop-down menu using the <select> element. My goal is to have a question mark (?) displayed next to each option in the menu, which will provide a brief explanation when hovered over. You can see an example of what ...

Position a div element after another using the :after pseudo-element

My goal is simple to explain, but I have exhausted all my efforts trying to achieve it. I am hoping for the ★ symbol to appear immediately after the number 06 using jQuery. Any assistance would be greatly appreciated. The numbers are generated by a s ...

Presenting tabular information using Python's Flask framework

I'm trying to display data from a database in a table on my webpage, but it's not formatting correctly. Here's what I want it to look like: Name John Mark Faculty CS University XXX But instead, it appears like this on the webpa ...

When hovering the mouse over, the text fails to appear

Is there something wrong with my overlay on this image? It darkens when I mouse over, but the text I want to display does not show up. Any ideas? http://jsfiddle.net/cryycw3n/ HTML <div class="square"> <div class="info"> <h2&g ...

The offspring departing from the guardian's left side

I have a canvas element inside a container and I want to prevent the canvas from extending beyond the left side of its container. Despite trying various solutions, I have not been successful. The legend is hidden within the container but when the chart rea ...

What is the best way to dynamically update styleUrls or style properties in Angular?

One of my goals is to give users the ability to customize colors and certain styles within my Angular application. I am thinking about creating a structure like this: Structure: component-one   folder-with-css-files     style-for-component-1-fo ...

Matching whole words in parsley.js using Regex

Is there a way to match two complete words using the or(|) operator in parsley.js' data-parsley-pattern attribute? I am looking to match the words user and moderator. My attempt was: data-parsley-pattern="/(user|moderator)/" which follows normal reg ...

Angular can be used to compare two arrays and display the matching values in a table

Having two arrays of objects, I attempted to compare them and display the matching values in a table. While looping through both arrays and comparing them by Id, I was able to find three matches. However, when trying to display these values in a table, onl ...

How can C#/MVC loop through multiple files from separate file inputs within a form that contains multiple file inputs?

The HTML provided is as follows: <input id="openbox_actual" class="btn btn-lg btn-warning" type="file" name="videoFile" style="display: none;" /> <input id="openbox_actual2" class="btn btn-lg btn-warning" type="file" accept="image/*" name="screen ...