Positioning an element absolutely within a CSS grid item: CHALLENGING

I'm facing a challenge with my CSS Grid, where I need to add a ribbon or another div in some items. It seems impossible! How can I achieve this?

 grid-item {
  background-color: lightgreen;
  display: flex;
  justify-content: center;
  align-items: center;
}

.ribbon-wrapper {
  width: 85px; // the length should not be in px
  height: 88px; // the length should not be in px
  overflow: hidden;
  position: relative;
  top: -3px;
  left: -3px;
  .ribbon {
    font: bold 15px sans-serif;
    color: #333;
    text-align: center;
    -webkit-transform: rotate(-45deg);
    -moz-transform: rotate(-45deg);
    -ms-transform: rotate(-45deg);
    -o-transform: rotate(-45deg);
    position: relative;
    padding: 7px 0;
    top: 15px;
    left: -30px;
    width: 120px;
    background-color: #ebb134;
    color: #fff;
  }
}

Answer №1

You have the option to utilize a pseudo element along with a data attribute:

HTML5 is crafted with flexibility in mind for data that needs to be linked with a specific element but doesn't require a defined meaning. Using data-* attributes enables us to store additional information on standard, semantic HTML elements without resorting to other workarounds like non-standard attributes or extra DOM properties.

An overflow can come in handy and utilizing background-clip can mimic a ribbon appearing slightly outside.

The background-clip CSS property specifies whether an element's background, either color or image, extends under its border.

vmin or vmax units could be used to adjust font size and resize the ribbon via em on padding and coordinates.

The viewport-percentage lengths are relative to the size of the initial containing block. When the height or width of the initial containing block changes, they scale accordingly.

If needed, you can add a shadow and use linear-gradient to create slanted shadow parts.

Here is a demo:

body {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  grid-auto-rows: 1fr;
  grid-gap: 2px;
  height: 100vh;
  padding: 5px;
  margin: 0;
  box-sizing: border-box;
}

grid-item {
  background-color: lightgreen;
  background-clip: content-box;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
  overflow: hidden;
  padding: 3px;
}

grid-item[data-class="new"]:before {
  content: attr(data-class);
  position: absolute;
  font-size: 2vmax; /* update font-size */
  top: 0.4em;
  left: -1.3em;
  padding: 0em 1.5em;
  transform: rotate(315deg);
  background-color:gold;
  /* eventually add some shadow effects */
  background-image: 
  linear-gradient(135deg, black 0.9em, transparent 1.15em), 
  linear-gradient(-135deg, black 0.9em, transparent 1.15em);
  box-shadow: 0 0 3px;
}
<grid-item>see</grid-item>
<grid-item>full</grid-item>
<grid-item>page</grid-item>
<grid-item>then</grid-item>
<grid-item data-class="new">RESIZE</grid-item>
<grid-item>window</grid-item>
<grid-item>to</grid-item>
<grid-item>see</grid-item>
<grid-item>ribbon</grid-item>
<grid-item data-class="new">font&size</grid-item>
<grid-item>updates</grid-item>
<grid-item>F</grid-item>
<grid-item data-class="new">PRO</grid-item>
<grid-item>B</grid-item>
<grid-item>C</grid-item>
<grid-item>D</grid-item>
<grid-item>E</grid-item>
<grid-item>F</grid-item>
<grid-item>A</grid-item>
<grid-item>B</grid-item>

Answer №2

To achieve the desired effect, make sure to include the position: relative; property on the grid-item class. This will allow you to then utilize absolute positioning for the .ribbon-wrapper element.

grid-item {
  background-color: lightgreen;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
}

.ribbon-wrapper {
  width: 85px; // consider not using px units
  height: 88px; // consider not using px units
  overflow: hidden;
  position: absolute;
  top: -3px;
  left: -3px;

  .ribbon {
    font: bold 15px sans-serif;
    color: #333;
    text-align: center;
    -webkit-transform: rotate(-45deg);
    -moz-transform:    rotate(-45deg);
    -ms-transform:     rotate(-45deg);
    -o-transform:      rotate(-45deg);
    position: relative;
    padding: 7px 0;
    top: 15px;
    left: -30px;
    width: 120px;
    background-color: #ebb134;
    color: #fff;
  }
}

Check out this demo on JSFiddle!

Answer №3

If you want to achieve this effect and also make it resizeable, it can be done but the process is a bit convoluted.

The spacer div elements are necessary to maintain the height of the layout. You will need one on each side in order to center the "PRO" text. By sacrificing 1px on each side, we are able to ensure that the ribbon-wrapper element can be absolutely positioned.

You can view an example of this implementation here: https://jsfiddle.net/rozkvsdh/9/

HTML

<grid-item>

    <div class="ribbon-wrapper"><div class="ribbon">NEW</div></div>    
    <div class="spacer"></div>
    <div>PRO</div>
    <div class="spacer"></div>

</grid-item>

CSS

// this is new
.spacer {
  height: 88px;
  width: 1px;
}

grid-item {
  background-color: lightgreen;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative; // added
}
.ribbon-wrapper {
  width: 85px; // consider using relative units instead of px
  height: 88px; // consider using relative units instead of px
  overflow: hidden;
  position: absolute;
  top: 0; // edited
  left: 0; // edited
}

Answer №4

The alignment of the ribbon to the left is affected by being a child element within a flex container that has justify-content: center applied. This causes both the ribbon and content to be centered next to each other.

To adjust this, you can use the margin-right: auto property to align the ribbon to the left, but it will also right-align the content.

Another method involves adding an invisible spacer item to maintain equal balance in the container while keeping the content centered, although this approach may be more complex than necessary.

Instead, it's recommended to utilize CSS positioning properties for positioning the ribbon. Resizing the ribbon is a separate consideration:


grid-item {
    background-color: lightgreen;
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative; /* establish nearest positioned ancestor for abspos containment */
}

.ribbon-wrapper {
    overflow: hidden;
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
}

.ribbon-wrapper .ribbon {
    font: bold 15px sans-serif;
    color: #333;
    text-align: center;
    transform: rotate(-45deg);
    position: relative;
    padding: 7px 0;
    top: 15px;
    left: -30px;
    width: 15vw;
    background-color: #ebb134;
    color: #fff;
}

updated fiddle link

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

Achieving compatibility with IE8 Filters for Matrix operations

Currently, I am working on a project that involves creating arrow ends on a navigation bar. The issue at hand is that transforms do not function properly on older versions of Internet Explorer (IE8 or below). My attempt to resolve this problem involved imp ...

How can I incorporate a dropdown menu into my website's navigation using Bootstrap 4 alpha?

This content is based on the Bootstrap v4 Alpha blog theme. I integrated it into a project but encountered issues when trying to add a dropdown menu to the navigation bar. Despite my attempts, the dropdowns did not appear as expected. I included the code ...

Obtaining Sass using Node.js and the Git Bash terminal

I'm having difficulties with installing Sass via the command line. I prefer to use Visual Studio Code as my text editor. I am seeking guidance on how to download and integrate Sass into a web project. These are the steps I've taken in the comman ...

In search of a plugin that adds comment bubbles to my website

I currently have a small image on my site that users can click to view all the comments for a post. I'd like to make this more dynamic by displaying the number of comments directly in the bubble so users don't need to click to see if there are an ...

Is it possible to manipulate an image tag's image using only CSS?

Is it possible to hide an image from the src attribute of an <img> tag and instead set a background image on the tag using CSS? One idea could be adjusting the positioning or text-indent of the actual image to move it out of view, and then applying ...

I'm curious about the specific purpose of /1 in font styling at 16px

Can anyone explain the purpose of /1 in the font: 16px/1 style declaration? I removed the /1 from the code and noticed increased spacing between lines. What is the specific role of /1 in this situation? body { font: 16px/1 'Open Sans', sans ...

What was the inspiration behind Spotify's section design?

Spotify has cleverly hidden the overflowing content without showing a scrollbar, allowing users to swipe through the list. How did they achieve this? I am currently using tailwindcss if that makes a difference. https://i.stack.imgur.com/z59yv.png ...

Mobile-first Bootstrap view (with three lines)

I need some help with Bootstrap. How can I configure it to display only the mobile view toggle (the three lines) at all screen sizes on my website? ...

Disable the spinning animation of the Bootstrap spinner to keep it still and static

I am currently utilizing bootstrap 4 for my project. When a particular event starts, I have successfully managed to make the spinner spin with the code snippet below: <span class='spinner-border spinner-border-sm text-primary' role='statu ...

The Google Map is not showing all the details

Our app is developed using ReactJS on Rails API, with a Google map integrated. However, when visiting this link and clicking "Map View", some grey space appears under the Google Map. An example image can be found here: example We are having trouble findi ...

Images in a horizontal dropdown selection menu

Currently, I have a traditional select dropdown that is data-bound with Angular. <select class="form-control" ng-model="category"> <option value="work">Work</option> <option value="home">Home</option> <option valu ...

Incorporating JQuery UI sortable functionality with the CSS grid display property to create a

I'm currently working on creating a sortable CSS grid using jQuery UI. $( function() { $( "#sortable" ).sortable({ handle: "handle" }); }); gridHolder{ display:grid; background:tan; grid-template-columns: ...

Adjustable slider height in WordPress

Struggling with the height of the slider on my website. I've tried various CSS adjustments and even tweaked the Jquery, but it still doesn't display properly on mobile devices. For instance, setting a height of 300px looks perfect on desktop brow ...

`Modified regions determined by cursor location`

I am working with a split layout featuring two columns, and I need the ability to make each column separately scrollable. Due to using a specialized scroll-to function, I cannot use overflow-y: scroll; or overflow: auto;. I am looking for alternative solut ...

Is there a discrepancy in height between Chrome's mobile emulator and the iPhone simulator?

Currently, I am conducting a layout test for a PhoneGap application using the Framework7 framework across the Chrome mobile emulator (iPhone 6) and Xcode iOS simulator. However, I am facing difficulties with aligning the vertical layout on both simulators. ...

Sliding jQuery form borders

After successfully implementing the sliding form using jquery, I encountered a challenge. When clicking on the link, I wanted the form to have a border like this: However, when I tried adding a border for both elements, it ended up looking like two separa ...

Using Bootstrap 4 to create a light color overlay on top of an image for enhanced text visibility and emphasis

Trying to apply a light color on top of an image or its parent div to ensure that the text remains visible regardless of the image's darkness. Using the Bootstrap card class for overlaying text over the image but facing issues with opacity dimming bot ...

Words placed in the middle of the picture

<div> <img style="vertical-align:middle" src="https://placehold.it/60x60"> <span style="">New Product</span> </div> I require this specific layout to be responsive. Could you please provide instructions on achieving this? ...

What steps can be taken to eliminate the 1-pixel line between the background and gradient?

https://i.sstatic.net/nbtkK.png How can I remove the line that appears between the block and the gradient background when zooming in, especially noticeable in Safari (After zooming a couple times, Cmd +) For more details, please refer to this jsfiddle li ...

How to create a hyperlink that only functions when JavaScript is turned off?

Exploring the realms of HTML 5, jQuery, CSS3, and the concept of manipulating elements based on JavaScript's state (<noscript> tags). In my quest for knowledge, I have two burning questions: How can I ensure a hyperlink functions ONLY when Jav ...