Creating a diagonal emboss effect with CSS

Looking to create a 3D diagonal emboss button similar to the image below:

https://i.sstatic.net/43cSd.jpg

My initial idea is to incorporate shadow effects and then use two small triangles with ::before and ::after pseudo-elements to close the gap.

However, I've noticed that there is always a very slight misalignment of less than 1 pixel (as shown in the snippet below). To make coding easier, I've used different colors for distinction.

.button {
  border: 1px solid red;
  box-shadow: -10px 10px red;
  
  display: inline-block; margin: 30px; position: relative; outline: none; font-size: 40px;
  padding: 10px 30px; background-color: #333; font-weight: 700;
  color: white; letter-spacing: 1px;
  line-height: 1; text-transform: uppercase; text-align: center;
}

/* create triangle */

.button::before { content: ""; position: absolute;
  top: -1px;
  left: -11px;
  width: 0; height: 0; font-size: 0; line-height: 0%; border-style: solid; border-color: transparent; border-width: 0 0 11px 11px; border-bottom-color: red; }

.button::after { content: ""; position: absolute;
  right: -1px;
  bottom: -11px;
  width: 0; height: 0; font-size: 0; line-height: 0%; border-style: solid; border-color: transparent; border-width: 11px 11px 0 0; border-top-color: red; }
<a class="button">Gallery</a>

Is there a more efficient way to implement this design without using triangles and absolute positioning?

Answer №1

To create a unique effect, consider using two angled linear-gradient strips on a button element - one on the left and another at the bottom.

Visualize placing a 10px x 10px square at the top left and bottom right of the pseudo-element with one side transparent and the other colored. This technique creates a triangle shape, which is the method utilized here.

A pseudo-element (a square or rectangle) positioned behind the parent creates triangular cuts using the angled linear-gradients set at 135 degrees and 315 degrees. By making one half of the diagonal line transparent and the other hotpink, a triangular cut effect is achieved.

The process involves:

  • Create a pseudo-element that is larger than the parent to extend outside the button element.
  • Add small horizontal and vertical gradient background strips to the pseudo-element.
  • Create angled linear-gradients for the triangular cuts on the sides.
  • Add a 1px border using box-shadow without affecting the positioning.

.button {
  display: inline-block;
  margin: 30px;
  position: relative;
  outline: none;
  font-size: 40px;
  padding: 10px 30px;
  background-color: #333; 
  font-weight: 700;
  color: white;
  letter-spacing: 1px;
  line-height: 1;
  text-transform: uppercase;
  text-align: center;
  box-shadow: inset 0px 0px 0px 1px hotpink; /* mimics the border */
}
.button:after {
  position: absolute;
  content: '';
  top: 0px;
  right: 0px; 
  height: calc(100% + 10px); 
  width: calc(100% + 10px); 
  background: linear-gradient(135deg, transparent 7px, hotpink 7px), linear-gradient(315deg, transparent 7px, hotpink 7px);
  background-size: 10px 100%, 100% 10px;
  background-position: top left, bottom left;
  background-repeat: no-repeat;
}
<a class="button">Gallery</a>

<a class="button">Gallery Button Big</a>

Note: While this effect can be achieved without a pseudo-element, it may lead to increased complexity as shown in this demo. Therefore, sticking to the pseudo-element approach is recommended for simplicity.

Answer №2

If you want to keep it simple, stick to using just box-shadow instead of creating a triangle with more code.

For example:

.button {
  border: 1px solid pink;
  box-shadow: -10px 10px pink,-9px 9px pink,-8px 8px pink,-7px 7px pink,-6px 6px pink,-5px 5px pink,-4px 4px pink,-3px 3px pink,-2px 2px pink;
  
  display: inline-block; margin: 30px; position: relative; outline: none; font-size: 40px;
  padding: 10px 30px; background-color: #333; font-weight: 700;
  color: white; letter-spacing: 1px;
  line-height: 1; text-transform: uppercase; text-align: center;
}
<a class="button">Gallery</a>

If you want to avoid pixelated edges, simply add 1px inside each declaration.

.button{
 border: 1px solid pink;
 box-shadow: -10px 10px 1px pink,-9px 9px 1px pink,-8px 8px 1px pink,-7px 7px 1px pink,-6px 6px 1px pink,-5px 5px 1px pink,-4px 4px 1px pink,-3px 3px 1px pink,-2px 2px 1px pink,-1px 1px 1px pink,0px 0px 1px pink;
  
  display: inline-block; margin: 30px; position: relative; outline: none; font-size: 40px;
  padding: 10px 30px; background-color: #333; font-weight: 700;
  color: white; letter-spacing: 1px;
  line-height: 1; text-transform: uppercase; text-align: center;
  }
<a class="button">Gallery</a>

Answer №3

Try out this CSS code snippet

<style>
  .test {
    display: inline-block;
    padding: 20px;
    margin: 20px;
    background: #000;
    color: white;
    font-weight: bold;
    text-decoration: none;
  }

  .test.shape {
    position: relative;
    box-shadow: -1px 1px #FC2CFF, -2px 2px #FC2CFF, -3px 3px #FC2CFF, -4px 4px #FC2CFF, -5px 5px #FC2CFF;
    transition: all 0.1s ease-in;
  }

</style>

<body>
  <div class="test shape">Box with customized text style</div>
</body>

Answer №4

To achieve this effect, you can simply utilize the box-shadow property without needing to use :after or :before pseudo-elements. Check out the solution below:

.button {
  padding:10px;
  font-size: 30px;
  font-weight: bold;
  color: #FFF;
  display:inline-block;
  text-decoration:none;
  background: #333;
  border: solid 1px pink;
  box-shadow: -1px 0px 0px pink,-0px 1px 0px pink,
    -2px 1px 0px pink,-1px 2px 0px pink,
    -3px 2px 0px pink,-2px 3px 0px pink,
    -4px 3px 0px pink,-3px 4px 0px pink,
    -5px 4px 0px pink,-4px 5px 0px pink,
    -6px 5px 0px pink,-5px 6px 0px pink,
    -7px 6px 0px pink,-6px 7px 0px pink,
    -8px 7px 0px pink,-7px 8px 0px pink,
    -9px 8px 0px pink,-8px 9px 0px pink;
}
<a href="#" class="button">Gallery</a>

Pro Tip: To save time and effort, you can explore a library that provides various pre-designed button styles: . This way, you can easily incorporate stylish buttons into your projects.

Answer №5

One effective approach for your situation would involve implementing the box-shadow property.

Additionally, you may find it helpful to explore this resource:

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

Determine the selected radio button

----EDIT---- I am developing a jQuery mobile application and I need to determine which radio button is selected. This is the JavaScript code I'm using: function filter(){ if(document.getElementById('segment1').checked) { aler ...

A comprehensive guide on creating a package that combines an href link with an <li> element

I am currently using the <li> tag to display href links. The issue I am facing is that when I click on the 'box,' it does not directly link to another page. Instead, I have to click on the href link for it to redirect to another page. Is th ...

Can someone point out the mistakes in my CSS Layout?

I've been struggling to make progress on this task over the past couple of days, encountering roadblocks with no clear solution in sight. The maze of nested divs I'm navigating through might be playing tricks on my mind, so having a fresh pair of ...

Disarray in the form elements

I'm having trouble positioning my form elements as desired. I want the recurrence_interval input field to be below the select (recurrence) input field. My two radio buttons for 'never' and 'on' should be stacked on top of each ot ...

The dropdown login form is malfunctioning on my Wordpress website

After reading various tutorials and guides online, I managed to set up a login screen. You can view the code in my jsfiddle: Jsfiddle. Unfortunately, I am facing issues with making the code function correctly. Being new to Jquery, I might have made a begin ...

jQuery can be used to relocate buttons on a webpage

When the Contact button is clicked, how can I move the Close button below #panel? It's currently fixed in position. Here's my demonstration: https://jsfiddle.net/25u78gff/ https://i.sstatic.net/qDad9.png jQuery('.sub-menu').addClass( ...

Effortlessly move and place items across different browser windows or tabs

Created a code snippet for enabling drag and drop functionality of elements within the same window, which is working smoothly. var currentDragElement = null; var draggableElements = document.querySelectorAll('[draggable="true"]'); [].forEach ...

jQuery - Reveal one div while concealing another

I've been working on a script to toggle between two divs onClick - opening one while closing the other if it's already open. I'm fairly new to jQuery and Javascript, having mainly worked with HTML/CSS. Script I found: http://jsfiddle.net/J ...

Use Chrome developer tools to simulate mobile devices with navigation bars

Hello there! I am a web developer seeking a method to simulate mobile devices while displaying their respective navigation bars, toolbars, and more. In Google Chrome's 'Device toolbar' (v58 on macOS), there is a specific mode available for t ...

What is the best way to pass an array to a child component in React?

I am having an issue where only the first element of inputArrival and inputBurst is being sent to the child component Barchart.js, instead of all elements. My goal is for the data to be instantly reflected as it is entered into Entrytable.js. EntryTable.js ...

The feature for choosing rows is not functioning properly when using materializecss in Tabulator

While working on my project, I encountered an issue with selecting rows. After some debugging, it was revealed that the culprit behind this behavior is the tabulator_materialize.min.css file. Interestingly, when I don't use this CSS, everything functi ...

Exploring the world of jQuery and Ajax to retrieve a full HTML framework

I'm a beginner in jQuery and JavaScript programming. While I've managed to use jQuery for my Ajax calls, I'm facing an issue that has me stumped. When making an Ajax call, I'm trying to return a complete HTML structure, specifically a ...

Issue with setting a background image to a div in Next.js: not functioning as expected

I haven't used Next.js before and I'm having trouble setting a background image for a specific div. I have a folder named public in the root directory where I've placed the file art-thing.jpg. My styles.css is also in the root directory, whi ...

Which element is able to utilize the inline-block style?

Currently, I am delving into the intricacies of the inline-block attribute and have a basic understanding that it allows elements to sit on the same row rather than stack on top of each other as they would in a normal layout. However, my grasp on how exact ...

The height of the input element is greater than the size of the font

I am facing an issue with an input element that has a height 2px higher than what I expected. Here is the relevant CSS: .input { font-size: 16px; padding: 15px; border: 1px solid black; border-radius: 3px; width: 400px; } <input class=" ...

Using the section :export in the SCSS :root declaration

In the file test.module.scss, I store all my variables for colors, typography, and more. I want to be able to use these variables in my react components. However, the file starts with :root to define the variables: :root{ --color-white: #fff; --color-b ...

Conceal the calendar icon from the date-type HTML input field specifically on the Firefox

The situation at hand is quite straightforward. <input type="date /> When viewed on Firefox (both desktop and mobile), it appears as follows: https://i.stack.imgur.com/S2i0s.png While the internet provides a solution specifically for Chrome: ...

Is there a way to transform BASE64 encoded HTML into a GIF format using ColdFusion?

I am getting a BASE64 encoded message from a WebService. This message is an interpretation of an HTML page and I can use pre-existing ColdFusion functions to convert and showcase it. However, my requirement now is to generate a GIF image of the HTML conten ...

Fade in the background of table row clips using jQuery's fadeIn() method

When using the fadeIn() function to change the dimensions of a table, Firefox is clipping the background of the newly shown rows. If I click away from the tab and then return, the background is restored. This issue does not occur in Chrome. I am using Fi ...

Scrolling Horizontally with Bootstrap Cards

I'm trying to implement horizontally scrolling cards using Bootstrap V.5, like this: <div class="container-fluid py-2"> <div class="d-flex flex-row flex-nowrap" style="overflow: auto;"> <div cl ...