Styling Buttons with Overlapping Effects using Styled Components

Having trouble with button overlapping in my project. I'm trying to achieve the layout shown in the attached image https://i.sstatic.net/aXIdh.png

Check out the Codesandbox demo HERE

const MainButton = styled.button`
  border-radius: 50%;
  border: 2px solid red;
  position: relative;
  background-color: #fff;
  display: block;
  width: 40px;
  height: 40px;
  position: relative;
  margin-bottom: 0.5rem;
  overflow: hidden;
  & > img {
    width: 100%;
    height: 100%;
    object-fit: contain;
  }
`;

const IconButton = styled.button`
  border-radius: 50%;
  border: 2px solid red;
  position: absolute;
  background-color: #fff;
  display: block;
  width: 22px;
  height: 22px;
  position: relative;
  margin-bottom: 0.5rem;
  overflow: hidden;
  & > img {
    width: 100%;
    height: 100%;
    object-fit: contain;
  }
`;

Answer №1

To position IconButton relative to MainButton, you must ensure that it is nested within MainButton.

<MainButton type="button">
  <img
    src="https://4.img-dpreview.com/files/p/E~TS590x0~articles/3925134721/0266554465.jpeg"
    alt="test"
  />
  <IconButton>+</IconButton>
</MainButton>

Then adjust the positioning of IconButton.

const IconButton = styled.span`     // <-- using span for nesting button is not valid
  background-color: #fff;
  border-radius: 50%;
  border: 2px solid red;
  cursor: pointer;
  position: absolute;
  display: block;
  width: 22px;
  height: 22px;
  line-height: 22px;                // <-- vertically center text
  position: relative;
  margin-bottom: 0.5rem;
  overflow: hidden;
  left: 50%;                        // <-- position at parent's center
  bottom: 0;                        // <-- align with parent's bottom
  transform: translate(-50%, -50%); // <-- center the button

  & > img {
    width: 100%;
    height: 100%;
    object-fit: contain;
  }
`;

Remove the overflow: hidden; rule from the parent MainButton.

https://i.sstatic.net/DCCEF.png

https://codesandbox.io/s/buttons-changing-forked-n4bw3?fontsize=14&hidenavigation=1&module=%2Fsrc%2FTable%2Findex.js&theme=dark

Update

Moved the image to be a background image and adjusted the positioning.

const MainButton = styled.button`
  border-radius: 50%;
  border: 2px solid red;
  position: relative;
  background-color: #fff;
  background-image: ${({ src }) => `url(${src});`}
  background-position: center center;
  background-size: contain;
  display: block;
  width: 40px;
  height: 40px;
  position: relative;
  margin-bottom: 0.5rem;
  cursor: pointer;
  & > img {
    width: 100%;
    height: 100%;
    object-fit: contain;
  }
`;

const IconButton = styled.div`
  background-color: #fff;
  border-radius: 50%;
  border: 2px solid red;
  cursor: pointer;
  position: absolute;
  display: block;
  width: 22px;
  height: 22px;
  line-height: 22px;
  position: relative;
  margin-bottom: 0.5rem;
  overflow: hidden;
  text-align: center;
  user-select: none;
  left: 50%;
  top: 100%;
  transform: translate(-50%, -50%);

  & > img {
    width: 100%;
    height: 100%;
    object-fit: contain;
  }
`;

https://i.sstatic.net/k9zNG.png

https://codesandbox.io/s/overlap-button-on-buttons-using-styled-components-forked-swo6t?fontsize=14&hidenavigation=1&module=%2Fsrc%2FTable%2Findex.js&theme=dark

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

Is it better to utilize a singular action type or multiple action types to signify this asynchronous action?

Currently, I am in the process of creating a user interface for a search system. In this system, almost every action taken by the user triggers an asynchronous event to refresh the search results. For instance, if a user inputs a keyword, we must retrieve ...

OrbitControls in THREE.JS fail to function properly when a DOM Element is layered on top of the scene

I am attempting to position labels as elements with position:absolute; over a THREEJS scene. The issue arises when the mouse hovers over one of the labels (the red box in the example below), causing the events that trigger OrbitControls to be "halted" by t ...

Experiencing an Error Message of "Undefined" in React.js Console

After making a request for the JSON file, the console is showing 'Undefined' and I'm unsure of the reason. When the button is clicked, it should pass the results from the request to the Info component via the Google Place API, including the ...

React and Typescript: Executing a function on one element by clicking on another element

I've been working on a fun mini-game where two adorable hamster pictures battle it out to determine the cutest one. After each round, when the user clicks on the winning picture, I need to update my database with the number of wins and defeats for ea ...

In Bootstrap 4, the Form-Inline module experiences alignment issues on extra small (XS) view

Boostrap 4 has been used to create a .form-inline at the bottom of the page. It appears correctly when the viewport is larger than the XS breakpoint... https://i.sstatic.net/UYaG7.png ...but encounters issues when switching to XS view... https://i.sstat ...

Ensure that the default boolean value is set to false rather than being left as undefined

I have a specific type definition in my code: export type ItemResponse = { .... addedManually: boolean; .... } Whenever I parse a JSON response into this type, I encounter an issue: const response = await fetch( `https://api.com` ); con ...

How can I display different data values on each individual circle counter, rather than all circles showing the same data?

Hey there! I'm trying to get my circular counters to display the counter value that I specify in their class and data-percent. However, currently all four counters are only showing the data from the first counter, even though I've set different d ...

Creating a simulated float:top effect in JavaScript

Is there a way to achieve a css float:top attribute in javascript, either using native code or jQuery? I have a large list of items that I want floated, stacking them top to bottom and left to right. Currently, floating them left stacks them left to right ...

Tips for simplifying and improving the readability of props and conditions in React/JavaScript during the refactoring

Today, I want to address a challenge that I am currently facing. Within an element, I have set up two conditions based on props. When I reuse the component, I either call the props socialSupervisor or socialOperator. It functions flawlessly. However, I ...

How can I modify the container to prevent the Bootstrap dropdown from being clipped by overflow:hidden settings?

With bootstrap, I encountered a situation where dropdown menus are being clipped by my <div> with overflow: hidden. How can I address this issue without incurring high costs? One potential solution might be to change the container of all dropdowns wi ...

Vertically aligning text in separate div containers

Currently, part of my dashboard page is styled using the Bulma CSS framework. One feature is a 'Widgets' feature with three large containers displaying key facts such as the number of sales, new customers, etc. The issue I'm facing is that ...

Troubleshooting tip: Dealing with a blank screen when deploying a Node.js app on Heroku

After successfully working on localhost, I utilized webpack and babel before deploying the application. However, upon clicking the Heroku URL, the page appeared blank and index.html showed nothing. Here is a collection of Build Logs and Logs --tail: ----- ...

The multiline feature of tooltip on mat-table cell is malfunctioning

I adjusted the mat-tooltip to be displayed as multiline using the following style in the global CSS: .mat-tooltip-class-here { white-space: pre-line !important; } Interestingly, this formatting works on span and button elements but not on mat cells. ...

I am looking to integrate a custom button that, when clicked, will launch the file explorer for me to choose a file. Once selected, the file name should automatically populate in the input field

In the code below, when the button is clicked, Windows Explorer should open and allow the user to select a file. The selected file should then be displayed in the input field. The file type should not be 'File'. <Grid.Column width={8}> ...

Click on a button external to the component to reset the pagination back to the first page

I've successfully implemented a custom pagination component using the material UI usePagination hook. The functionality is working perfectly, but I'm looking for a way to reset the pagination back to the first page by triggering a button that is ...

How to position a centered div with a background image on a webpage

I am trying to achieve a centered layout for a div and its content on a webpage. The div includes a background image. Here is my approach using Flexbox: <head> <style> .flex_container { display: flex; flex-d ...

Tips for modifying the default settings of a CSS framework like Material UI

Exploring the realm of CSS for the first time and feeling a bit lost. I am working with material ui alongside react and redux. My goal is to customize certain properties of a specific component, such as TextField with the disabled attribute. Upon inspectin ...

Can you tell me the data type of IconButtons in Material UI when using TypeScript?

Currently, I am in the process of creating a sidebar using Material UI in Next JS with typescript. My plan is to create a helper function that will help display items within the sidebar. // LeftSidebar.tsx import {List,ListItem,ListItemButton,ListItemIcon ...

How can I place an inline element on the same row?

Here is a code snippet that I am working on: <div id="header"> <p>Home</p> <p>Home</p> <p>Home</p> <p>Home</p> </div> I'm trying to display this element centered and inlin ...

Error: Trying to access the 'name' property of an undefined value is not possible

The issue arises with the undefined value of currentPackage. render() { const { hasAccounts, asideClassesFromConfig, disableScroll, htmlClassService, currentPackage, user, } = this.props; const isActive = checkStatus(user?.status); const packageLogo = curr ...