What is the best way to create a box in the shape of an octagon

Trying to achieve the unique box design shown below using CSS.

I researched various resources, such as https://css-tricks.com/examples/ShapesOfCSS/, but encountered an issue with the purple border cutting edges. Attempted using an octagon shape without success.

Made progress on creating the box. Here is a snippet of my code:

.box-outer {
  width: 300px;
  height: 120px;
  padding: 15px 30px;
  background: rgba(237, 236, 236, 0.72);
  border: 3px solid rgb(89, 67, 128);
  position: relative;
  border-right: 20px solid rgb(89, 67, 128);
}
.box-outer:before {
  content: "";
  position: absolute;
  top: -3px;
  left: -4px;
  border-bottom: 29px solid rgb(255, 252, 252);
  border-right: 29px solid #594380;
  border-top: 28px solid #FFF;
  height: 66%;
  width: 0;
}
.box-outer:after {
  content: "";
  position: absolute;
  top: -3px;
  right: -13%;
  border-top: 29px solid white;
  border-left: 29px solid #594380;
  border-bottom: 28px solid #FFF;
  width: 0;
  height: 66%;
}
.box-outer .right-text {
  position: absolute;
  right: -22%;
  color: white;
  font-size: 20px;
  top: 40%;
  z-index: 10;
  transform: rotate(-90deg);
  -ms-transform: rotate(-90deg);
  -webkit-transform: rotate(-90deg);
}
<div class="box-outer">
  <span class="right-text">
           LEGISLATIVE
        </span>
  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</div>
<!--box outer-->

Screenshot of current progress

Answer №1

After much effort, I have finally achieved the solution.

To make it work, I introduced a new div called box-inner.

You can view the implementation on this fiddle:

`http://jsfiddle.net/maverickabhi/qfthejb2/`

.box-outer {
  width: 300px;
  height: 120px;
  padding: 15px 30px;
  background: rgba(237, 236, 236, 0.72);
  border: 3px solid rgb(89, 67, 128);
  position: relative;
  border-right: 20px solid rgb(89, 67, 128);
}
.box-outer:before {
  content: "";
  position: absolute;
  top: -3px;
  left: -4px;
  border-bottom: 29px solid rgb(255, 252, 252);
  border-right: 29px solid #594380;
  border-top: 28px solid #FFF;
  height: 66%;
  width: 0;
}
.box-outer:after {
  content: "";
  position: absolute;
  top: -3px;
  right: -13%;
  border-top: 29px solid white;
  border-left: 29px solid #594380;
  border-bottom: 28px solid #FFF;
  width: 0;
  height: 66%;
}
.box-outer .right-text {
  position: absolute;
  right: -22%;
  color: white;
  font-size: 20px;
  top: 40%;
  z-index: 10;
  transform: rotate(-90deg);
  -ms-transform: rotate(-90deg);
  -webkit-transform: rotate(-90deg);
}
.box-inner {
  content: "";
  position: absolute;
  top: -2px;
  left: -1px;
  border-bottom: 30px solid transparent;
  border-right: 29px solid #F1F0F0;
  border-top: 29px solid transparent;
  height: 63%;
  width: 0;
}
<div class="box-outer">
  <span class="right-text">
           LEGISLATIVE
        </span>
  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
  <div class="box-inner"></div>
</div>
<!--box outer-->

Answer №2

Here is an innovative approach using CSS3 transformations to create the octagon shape with an added element of transparency inside it. This method allows for a versatile background, such as images or gradients, rather than just a solid color.

The construction of the shape involves:

  • A container featuring top and bottom borders, along with an inset box shadow on one side (depicted in green in the screenshot below).
  • A pseudo-element positioned on the opposite side with equivalent height to the container, rotated with perspective using transforms (shown in blue in the screenshot below).
  • Another pseudo-element on the other side, counter-rotated to the first element (illustrated in red in the screenshot below).
  • The inset box-shadow on the container aligns with the background of the pseudo-element on the right side to give the appearance of skewed halves.
  • Additional shadows around the parent container and second pseudo-element provide a complete shadow effect to the entire shape.

* - Various colors are used for representation purposes only.

.shape {
  position: relative;
  height: 150px;
  width: 300px;
  margin: 40px;
  border-color: #594380;
  border-style: solid;
  border-width: 2px 0px;
  background: rgba(252, 252, 252, 0.5);
  box-shadow: inset -20px 0px 0px #594380, 2px 3px 3px rgba(0,0,0,0.3);
}
.shape:before,
.shape:after {
  position: absolute;
  content: '';
  top: -2px;
  width: 30px;
  height: 100%;
  border: 2px solid #594380;
}
.shape:before {
  left: -32px;
  border-right: none;
  background: rgba(252, 252, 252, 0.5);
  -webkit-transform-origin: right 50%;
  -moz-transform-origin: right 50%;
  transform-origin: right 50%;
  -webkit-transform: perspective(15px) rotateY(-10deg);
  -moz-transform: perspective(15px) rotateY(-10deg);
  transform: perspective(15px) rotateY(-10deg);
  box-shadow: inset 2px 0px 0px #594380, inset 0px -1px 0px #594380, inset 0px 1px 0px #594380;
}
.shape:after {
  right: -34px;
  background: #594380;
  -webkit-transform-origin: left 50%;
  -moz-transform-origin: left 50%;
  transform-origin: left 50%;
  -webkit-transform: perspective(15px) rotateY(10deg);
  -moz-transform: perspective(15px) rotateY(10deg);
  transform: perspective(15px) rotateY(10deg);
  box-shadow: inset -2px 0px 0px #594380, inset 0px -1px 0px #594380, inset 0px 1px 0px #594380, 6px 2px 5px 3px rgba(0,0,0,0.3);
}
span {
  position: absolute;
  right: 0px;
  top: 12px;
  display: block;
  height: 20px;
  width: 100px;
  text-align: center;
  text-transform: uppercase;
  color: white;
  -webkit-transform-origin: right;
  -moz-transform-origin: right;
  transform-origin: right;
  -webkit-transform: rotate(-90deg);
  -moz-transform: rotate(-90deg);
  transform: rotate(-90deg);
  z-index: 2;
}
body {
  background: url(http://lorempixel.com/500/500);
}
<div class="shape">
  Lorem ipsum dolor sit amet...
  <span>legislative</span>
</div>

Note: There may be slight alignment discrepancies on the left borders when closely examined, but they are barely noticeable defects. The purpose of sharing this answer is to provide inspiration for future readers.


Alternative Approaches for Octagonal Shapes:

  • This CodePen example from jbutler483 showcases a different technique. Similar to the previous snippet, it has a minor flaw where the angled borders on the left side appear slightly thinner due to skew transforms.
  • If you require a transparent regular octagon shape, consider utilizing the method demonstrated in the following code snippet. While suitable for fully transparent shapes, it may not be ideal for semi-transparent ones (as observed in the second sample). Keep in mind that positioning text within the shape will necessitate separate handling.

.shape,
.octagon,
.shape:before,
.shape:after {
  border-top: 2px solid steelblue;
  border-bottom: 2px solid steelblue;
}

.shape {
  height: -webkit-calc(141.44px + 100px); /* width * sin(135) * 2 + width */
  height: -moz-calc(141.44px + 100px);
  height: calc(141.44px + 100px);
  width: 100px;
  position: relative;
  margin: 40px 80px;
}

.shape:after,
.shape:before,
.octagon {
  position: absolute;
  height: 100%;
  width: -webkit-calc(100% + 2px);
  width: -moz-calc(100% + 2px);
  width: calc(100% + 2px);
}

.shape:before,
.shape:after {
  content: '';
  top: -2px;
  left: -2px;
}

.octagon {
  top: -2px;
  left: -2px;
  -webkit-transform: rotate(90deg);
  -moz-transform: rotate(90deg);
  transform: rotate(90deg);
}

.shape:before {
  -webkit-transform: rotate(135deg);
  -moz-transform: rotate(135deg);
  transform: rotate(135deg);
}

.shape:after {
  -webkit-transform: rotate(-135deg);
  -moz-transform: rotate(-135deg);
  transform: rotate(-135deg);
}

.semi-transparent, .semi-transparent .octagon, .semi-transparent.shape:after, .semi-transparent.shape:before{
  background: rgba(1, 1, 1, 0.5);  
}

body {
  background: -webkit-linear-gradient(90deg, crimson, indianred, purple);
  background: -moz-linear-gradient(90deg, crimson, indianred, purple);
  background: linear-gradient(90deg, crimson, indianred, purple)
}
body > div{
  display: inline-block;
}
<div class="shape">
    <div class="octagon"></div>
</div>

<div class="shape  semi-transparent">
    <div class="octagon"></div>
</div>

Answer №3

Presented here is a unique svg solution.

Regrettably, it relies on hardcoded values for size.

In my experience, creating vertical text in svg is much simpler as you can easily rotate it by 90deg and achieve the desired effect.

The key component consists of two polygons. While I considered using a gradient for the background elements, I ultimately opted for this method as it provides clearer insight into the shapes being used.

The text element is implemented using a div with absolute positioning and fixed dimensions. I believe there may be room for improvement in this aspect, although I couldn't immediately come up with a better alternative.

.box div{
  position: absolute;
  margin-left: 70px;
  margin-right: 100px;
  margin-top: 5px;
  width: calc(600px - 70px - 100px);
}
.ticket .content {
  stroke: rgb(100, 0, 100);
  stroke-width: 2px;
  fill: #fff;
}
.ticket .end {
  stroke: rgb(100, 0, 100);
  stroke-width: 2px;
  fill: rgb(100, 0, 100);
}
.ticket #vertical {
  fill: #fff;
}
<div class="box">
  <div>lorem ipsum dolar si amet lorem ipsum dolar si ametlorem ipsum dolar si ametlorem ipsum dolar si ametlorem ipsum dolar si ametlorem ipsum dolar si ametlorem ipsum dolar si ametlorem ipsum dolar si ametlorem ipsum dolar si ametlorem ipsum dolar si ametlorem ipsum dolar si ametlorem ipsum dolar si ametlorem ipsum dolar si ametlorem ipsum dolar si ametlorem ipsum dolar si ametlorem ipsum dolar si ametlorem ipsum dolar si ametlorem ipsum dolar si ametlorem ipsum dolar si ametlorem ipsum dolar si ametlorem ipsum dolar si ametlorem ipsum dolar si ametlorem ipsum dolar si ametlorem ipsum dolar si ametlorem ipsum dolar si amet</div>
  <svg class="ticket" height="300px" width="600px" viewbox="-1 -1 202 102">
    <polygon class="content" points=" 0 20, 20 0, 170 0, 170 100, 20 100, 0 80" />
    <polygon class="end" points="170 0, 180 0, 200 20, 200 80, 180 100, 170, 100" />
    <text id="vertical" transform="translate(185 93) rotate(-90)">Golden ticket</text>
  </svg>
</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

Instructions for submitting information from a web form using Python without needing to know the form's ID or name

I am currently attempting to automate the submission of data into the online forms found on this webpage: Unfortunately, I am unable to determine the specific names of these forms by inspecting the source code. I have tried using the requests python modul ...

Display only the spans that contain text or are not empty

I need a solution to hide only those spans that are empty. <div class="img-wrapper"> <div class="showcase-caption" style="display: block; "> <span id="MainContent_ImageCaption_0">This one has caption</span> </div> ...

Troubleshooting: Custom checkbox using CSS ::before does not display properly on Firefox and Edge browsers

Encountering a frustrating CSS challenge while working on a project that needs to be compatible across various browsers. Specifically, I'm having issues with custom styling for checkboxes. Despite following recommendations to use a ::before pseudo-ele ...

Is there a way to continuously cycle through multiple images fading in and out at various locations on a webpage using absolute positioning?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"><head> <title>Harley's Art Gallery</title> <script t ...

Creating a table with multiple rows condensed into a single row (Using Material-UI/CSS)

Here is the array structure I am working with: const sample = [ { name: 'apple', detail: [{'a', 'b'}]}, { name: 'banana', detail: [{'a', 'b'}]}, ]; In order to create a table similar to the ...

Vue component updating its model only upon input element losing focus

I'm a beginner with vue and I'm currently working on incorporating an ajax search feature that triggers when a keyup event occurs. I have noticed that the model only updates when the input element loses focus. Sample HTML Code: <input name=" ...

Decrease in internal width

Seeking assistance to adjust the internal border width for better text alignment. I've been struggling with this issue as a beginner in the web development field and would appreciate some guidance. Link to image Here is a snippet of my HTML code: & ...

CSS style to choose the row in a bootstrap table with a specific class

This snippet is from a table created using Bootstrap: <div class="table-responsive"> <table class="table table-bordered table-striped"> <tbody> <tr> <td align="cent ...

Activating Button within Featherlight Modal

This is a follow up question from Featherlight hide div on Close After successfully resolving the issue with opening the lightbox, I have encountered another problem. I have added a submit button that should trigger an on('submit', function) whe ...

Altering documents post Bower installation

I took the initiative to manually download the css and js files for an angular module (here). In order to make a small adjustment, I modified the css (specifically changing max-width in the media query): Original: @media only screen and (max-width: 800px ...

Slide-out left menu using HTML and CSS

Currently, I am in the process of constructing a website that requires a menu to gracefully slide from the left side of the screen (with a width of 0px) to the right side (expanding to a width of 250px), all with the help of jQuery animations. Here is wha ...

Can you provide guidance on how to successfully transfer an array of JSON objects from the script section of an HTML file to the JavaScript

My webpage contains an array of JSON objects that I need to send to the server. The array, stored in a variable called results, appears normal when checked in the console before trying to POST it. Here is a sample of the data: 0: {id: 02934, uName: "Ben", ...

Create a dynamic feature on a JSP page that allows users to click a button and instantly see changes

How can I create a button on an HTML or JSP page that, when clicked, will dynamically add content to the same page? For example, imagine I have a JSP page called Prescription.jsp with input forms like: ID name select commodity weight tolerance ...

Utilizing CSS-in-JS to eliminate arrow buttons from a TextField

I'm currently developing a webpage using React and Material-UI. One of the components I have is a TextField element, and I need to remove the arrow buttons that typically appear on number input fields. If I were utilizing CSS, I could easily achieve t ...

Is there a white outline on the Cordova Text Font?

Currently working on a Cordova app where I have encountered an issue with the text display. The problem lies in the white outline surrounding the text, which is not visually appealing. In my code, I have a div with the style attribute background-color: ye ...

Adjusting the spacing between characters in SVG text elements

Take a look at this unique SVG: <svg xmlns="http://www.w3.org/2000/svg"> <defs> <style type="text/css"><![CDATA[ .code { font-family: monospace; white-space: pre; tab-size: 4; } ]]></style> </defs> <text class="cod ...

Displaying Angular 4 HTTP GET response in HTML: A Step-by-Step Guide

I am struggling to retrieve data from a table using the HTTP GET method in Angular 4. How can I display this data on an HTML page? getData(){ //return this.data; return this.http.get("http://localhost:8080/SpringRestExample/get/filedata") ...

Is the function failing to generate an input field?

Trying to implement a function that triggers an input field to appear upon clicking an element using the onclick event. Let's take a look at the code below. <!DOCTYPE html> <html> <body> <button onclick="createMessage()">New ...

PHP mail function does not properly align HTML table outputs

After fetching data from the database and inserting it into an HTML table, everything appears fine. However, upon pressing the send button to email the content, sometimes the alignment of the HTML table is disrupted in the email. It seems like specific col ...

To ensure that new tabs are opened directly within jQuery UI tabs, the tab should be created within the jQuery UI tabs interface

I have integrated jquery-UI to create a dynamic Tab panel. When I click on the "Add Tab" button, a new tab is created. However, the new tab does not open automatically. It only opens when clicked on. $(function() { var tabTitle = $( ...