Create a speech bubble using only CSS, featuring a partially see-through background and a stylish border

I wish to design a speech bubble using only CSS.

There are specific requirements I need to meet:

  • It should adjust its size based on content with some padding or a set size.
  • The background color must be semi-transparent.
  • You must be able to define a border, including its level of transparency.
  • Setting a border-radius should affect both the border and background.

Here is an example of how I envision two such speech bubbles looking. The first has a preferred width and height, centered content, while the second adjusts its dimensions based on the content with added padding. The key feature here is that in both cases, the triangular pointer remains the same size and stays centered. https://i.stack.imgur.com/363Zq.jpg

I have explored various approaches for creating speech bubbles and tried customizing examples, such as #34 from here:

// Code snippet...

However, when attempting to set a semi-transparent background color (with a border-radius to mask the overflow behind the border), the triangular point at the bottom does not get filled in. I couldn't find a solution for this issue.

I also came across a similar question here, where I adapted the following code:

<div class="background">
  <div class="bubble">
  <p>
    Hello world! I am some content. Who's got time for lorems?
  </p>
</div>
</div>
.background {
  background: pink;
  display: flex;
  // Other styles...
}

// More CSS code...

But issues arise when introducing semi-transparent colors, causing skewed transforms to overlap and create color discrepancies.

https://i.stack.imgur.com/PQzom.png

Additionally, answers in this post show differing opacity levels between the triangle and the background:

<div class="wrapper">
  <p class="infoBubble">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</p>
</div>
.wrapper {
  background: pink;
  // Additional styles...
 }

// More CSS code...

https://i.stack.imgur.com/HkmbM.png https://i.stack.imgur.com/dL8JT.png

So, the final question remains - what is the best approach to achieve the desired results?

Answer №1

Unfortunately, the case you're looking for seems to be missing from my collection. However, we can create it by combining elements #37 and #21. For detailed instructions, visit this link.

To achieve this effect, start by copying the code from element #37. Then, insert an additional span containing the necessary code snippet from element #21 (specifically, the pseudo element part).

.tooltip {
  /* CSS properties here */
}
/* Additional CSS code for the tooltip styling */
<div class="tooltip">
<span></span>
This is a customized tooltip with unique border design and transparent background.</div>

Answer №2

Yes, it can be achieved. Although my code snippet is incomplete, I will provide an explanation of the steps taken so far, allowing you to complete the remaining task.

To create this effect, key properties such as mask, mask-clip, mask-composite, and clip-path were utilized.

The bubble element itself contains a background with its pseudo-element :before expanding 100% in width and height beyond the actual border size. For instance, if the border is 5px, the pseudo-element extends by 10px from all sides (-5px -5px) starting from the top left corner.

The combination of mask, mask-clip, and mask-composite ensures that the background color acts as a border element outside the bubble's boundaries.

Additionally, clip-path is used to carve out space at the bottom for accommodating the arrow placement and also to shape the span:before element into a rectangle mirroring the dimensions of the bubble box.

I hope these insights prove helpful, enabling you to finalize the code yourself. Correcting the clip-path coordinates related to the span:before element should resolve any outstanding issues.

body {padding:0;margin:0;display:grid;min-height:100vh;place-items:center;background:linear-gradient(to bottom right,lightblue,pink);}

.bubble {
  --border: 3px;
  --border-color: rgba(255, 50, 50, .5);
  --background: rgba(0, 0, 0, .5);
  --radius: 1rem;
  --arrow-size: 50px;
  --color: #fff;
  
  position: relative;
  background-color: var(--background);
  max-width: 300px;
  color: var(--color);
  border-radius: calc(var(--radius) - var(--border));
  padding: 1rem;
}
  
.bubble > span {
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translate(-50%, 50%);
  width: var(--arrow-size);
  aspect-ratio: 1 / 1;
  rotate: 135deg;
  background: var(--background);
  clip-path: polygon(
    var(--border) calc(var(--border) * -1),
    calc(100% + var(--border)) calc(var(--border) * -1),
    calc(100% + var(--border)) calc(100% - var(--border)),
    100% 100%,
    0 0
  );
}
    
.bubble > span:before {
  content: '';
  position: absolute;
  inset: calc(var(--border) * -1);
  border: var(--border) solid transparent;
  mask:
    linear-gradient(transparent, transparent),
    linear-gradient(white, white);
  mask-clip: padding-box, border-box;
  mask-composite: intersect;
  background-color: var(--border-color);
}
  
.bubble:before {
  content: '';
  position: absolute;
  inset: calc(var(--border) * -1);
  border-radius: var(--radius);
  border: var(--border) solid transparent;
  mask:
    linear-gradient(transparent, transparent),
    linear-gradient(white, white);
  mask-clip: padding-box, border-box;
  mask-composite: intersect;
  clip-path: polygon(
    0% 0%, 
    100% 0%, 
    100% 100%, 
    calc(50% + (var(--arrow-size) / 2) + var(--border)) 100%, 
    calc(50% + (var(--arrow-size) / 2) + var(--border)) calc(100% - var(--border)),
    calc(50% - (var(--arrow-size) / 2) - var(--border)) calc(100% - var(--border)),
    calc(50% - (var(--arrow-size) / 2) - var(--border)) 100%,
    0% 100%
  );
  background-color: var(--border-color);
}
<div class="bubble">
  <span></span>
  Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eaque fuga totam repellendus nisi in ea sit quaerat cupiditate, nam, eos aliquam perferendis eligendi, reprehenderit impedit ullam deleniti? Sed, sequi accusamus.
</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

Link PayPal payments to the individual making the payment

On my website, I offer in-game features that can be purchased through a miniature store with PayPal buy now buttons. I'm looking for the best and most secure method to automatically deliver these in-game bonuses to users after they have completed thei ...

Switching Tabs When a Button is Clicked

I am currently using a guide from the link provided to learn how to create tabs: http://www.w3schools.com/howto/howto_js_tabs.asp. function openTab(evt, tabName) { var i, tabcontent, tablinks; tabcontent = document.getElementsByClass ...

Trick for adjusting padding on top and bottom for responsive blocks of varying widths

Hello there, I've been working on a project where I need to create a responsive grid of cards, like news articles, that maintain their proportions even when the browser's width changes. To achieve this, I decided to use an aspect-ratio hack by s ...

What are the best ways to create image animations on top of other images using CSS or JavaScript?

Imagine if the first image is in black and white, while the second one is colored. How can we make the black and white image change to color after a timeout period, with an animation similar to loading progress bars? Is this achievable using CSS or JavaScr ...

I'm puzzled as to why my Contact Form is failing to send out emails

Looking to create an email send function in a pop-up on my website that can be accessed via the following link: The issue I'm facing is that while it redirects perfectly to the thank you message, the PHP implementation does not seem to work after the ...

Unable to reach the top while perfectly centered

I am currently struggling to create a perfectly centered popup menu that allows me to scroll all the way to the top. It seems like the transform property only affects visuals, so even though #content is set to top: 50%, I can't see everything at the t ...

Click the link to capture the ID and store it in a variable

Currently working on a project involving HTML and JavaScript. Two HTML pages ("people.html" and "profile.html") are being used along with one JavaScript file ("people.js") that contains an object with a list of names, each assigned a unique ID: var person ...

How can I add text to an HTML5 SVG similar to using the HTML5 <p> tag?

I am currently working on creating dynamic rectangular boxes and I am facing some difficulties with inserting text into the shapes. The SVG text requires setting x and y coordinates in separate text tags, and doesn't have built-in width and height pro ...

Is it possible to modify the CSS of a single class when hovering over a child class of a different and unrelated class?

I am struggling with CSS combinators, especially when dealing with nested div, ul, and li elements. My issue involves changing the CSS of a div with the class "H" when hovering over li elements with the class "G". Since all of this is contained within a s ...

Add color to the cells within the table

I need help with dynamically adding colors to my table based on the results. If the result is 'UnSuccessfull', the color should be 'red'. If the result is 'Successful', the color should be 'green'. The challenge I a ...

PHP does not properly interpret quotation marks when passed from an HTML form

My current setup involves a simple HTML form with a submit button that triggers my PHP script to process the input. However, I've encountered an issue where my PHP code fails to recognize the quotation mark when using str_replace function. Below is a ...

What are some ways to ensure a JQM-created button is clickable in Firefox?

I am working on making a div clickable in a jQuery Mobile powered website. The current code I have functions properly in Chrome and Safari, however, it does not work in Firefox - both on desktop and Android FF. <button data-icon="eye"> <a href ...

Modifying inner content without altering CSS styling

Inside this div, there is a paragraph: This is the HTML code: <div id="header"><p>Header</p></div> This is the CSS code: #header p { color: darkgray; font-size: 15px; Whenever a button is clicked, the innerHTML gets updated: H ...

Applying a unique style to an element using its ID is effective, but using a class does

Incorporating twitter bootstrap tables has been a focus of mine lately, particularly when it comes to custom styling such as setting background colors for table elements. Here's what I've discovered: by assigning id="foo" to each <td> elem ...

Avoid constantly destroying the Bootstrap Popover

I am facing a challenge with retrieving data from two checkbox inputs inside a popover. The issue arises because the popover appears in the DOM when I click a button, but is removed when I click it again. It seems that the problem lies in the fact that Jav ...

What is the best way to retrieve a variable from a .php file that is included in a different .php file?

My question is how can I retrieve a value entered in a text field (with the field name = usn) in my_file.php file, from another file called demo.php without re-entering it every time? I have multiple files and I want to access this value without using tex ...

Prevent vertical scrolling on touch devices when using the Owl Carousel plugin

Is there a way to prevent vertical scrolling on Owl Carousel when dragging it horizontally on touch devices? It currently allows for up and down movement, causing the whole page to jiggle. If anyone has a solution, I can share the JavaScript file. Appreci ...

Is it possible to create separate layouts for mobile devices and tablets using jQuery mobile?

Currently building a jQuery mobile app and looking to implement two distinct designs/layouts, one for mobile devices and another for tablets. Is this achievable? If yes, how can it be done? Any specific code required? Cheers! Noah ...

Canvas - Occasionally, using lineTo() can result in crisp edges in the drawing

I've created a simple Canvas drawing app. However, I've noticed that occasionally the lineTo() command generates a line with fewer coordinates, resulting in many edges: I'm currently using the latest version of Firefox - could this issue be ...

Having trouble getting the CSS animation to work properly with the text

Update: The direct link is working fine, unlike the rocketscript version. <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> I have been attempting to animate word rotati ...