skip to Main Content

I’m trying to create a button that looks like this using html. I want the button to look like one is on top of the other, not just two rectangles next to each other (so the rounded edges/border-radius is important).

If it helps, I’m looping over a list of documents and displaying them as buttons in this format. It needs to be able to adjust its’ width for different document names/extensions. I don’t want the .pdf/.docx to be covered if the document name is too long.

button design

I started by creating two buttons and having each on a different z-index, but I’m wondering if there’s a better way to do this.

Is there a way to dynamically size two buttons so that they appear overlapping like this, but are able to adjust their location/width so their text is still visible?

I’m sure this is a simple fix – but I’m stuck

<button style="position: absolute; padding: 10px 20px; background-color: darkgray; border-radius: 15px; border: none; z-index: 1;">Document</button>
<button style="position: absolute; padding: 10px 50px; background-color: gray; border-radius: 15px; border: none; z-index: 0;">.pdf</button>

5

Answers


  1. Use a single button but wrap the document name in a span, then you can apply different styling to the document name and the button itself.

    body {
      margin: 20px;
    }
    
    .buttons {
      display: flex;
      flex-wrap: wrap;
      gap: 20px;
    }
    
    button {
      border: 0;
      background: #555;
      color: white;
      font-family: sans-serif;
      font-size: 25px;
      border-radius: 15px;
      padding: 0 20px 0 0;
      white-space: nowrap;
    }
    
    button>span {
      background: #888;
      border-radius: 15px;
      display: inline-block;
      padding: 10px 20px;
      margin-right: 5px;
    }
    <div class="buttons">
    
      <button>
        <span>DocumentName</span> .pdf
      </button>
    
      <button>
        <span>a-very-long-document-name</span> .docx
      </button>
    
    </div>
    Login or Signup to reply.
  2. You can put everything inside 1 element and control the children with display:flex.

    <style>
        .button{
            display: flex;
            background-color: lightgray;
            border-top-left-radius: 1rem;
            border-bottom-left-radius: 1rem;
            max-width: 500px;
        }
        .content{
            color: #000;
            font-weight: bold;
            font-size: 3rem;
            background-color: gray;
            padding: 1rem 1.5rem;
            border-radius: 1rem;
            z-index: 2;
        }
        .secondary{
            background-color: lightgray;
            z-index: 1;
        }
    </style>
    
    <div class="button">
        <div class="content">
            DocumentName
        </div>
        <div class="content secondary">
            .pdf
        </div>
    </div>
    

    I try to make this for you, but only the style. You still need the link and href, etc.

    Login or Signup to reply.
  3. .button{
      background: #444;
      cursor: pointer;
      text-decoration: none;
      display: inline-block;
      border-radius: 10px;
      color: #000;
      font-weight: bold;
      font-family: arial black;
      font-size: 12px;
    }
    .button-document-name{
      background: #666;
        padding: 10px 20px;
        display: inline-block;
        border-radius: 10px;
        -webkit-box-shadow: 11px 0px 13px -2px rgba(0,0,0,0.25);
        box-shadow: 11px 0px 13px -2px rgba(0,0,0,0.25);
    }
    .button-document-ext{
      padding: 10px 20px 10px 5px;
      display: inline-block;
    }
    <a class="button">
       <span class="button-document-name">Document Name</span>
       <span class="button-document-ext">.pdf</span>
    </a>
    Login or Signup to reply.
  4. You definitely don’t want two buttons unless you want a different behavior based on whether a user clicks one side or the other. Many solid ways to do this, here’s my approach:

    button {
      border: 0;
      color: black;
      font-family: sans-serif;
      font-size: 2em;
      background-color: gray; 
      border-radius: 15px; 
      padding: 0;
      display: flex;
      align-content: stretch;
      justify-content: space-between;
      flex-wrap: nowrap;
    }
    button label, button abbr {
      border-radius: 15px; 
      margin: 0;
      background-color: gray;
    }
    button label {
      padding: 10px 15px 10px 20px;
      background-color: darkgray;
    }
    button abbr {
      padding: 10px 20px 10px 15px; 
    }
    <button>
        <label>DocumentName</label>
      <abbr title="Portable Document Format">.pdf</abbr>
    </button>
    Login or Signup to reply.
  5. you can use pseudo :befor element instead of two buttons

    const docs = [
      ["doc1", ".pdf"],
      ["doc2", ".txt"],
      ["doc3", ".csv"],
    ];
    
    const mydiv = document.querySelector(".root");
    docs.forEach((doc) => {
      const docName = document.createTextNode(doc[0]);
      const docExt = document.createTextNode(doc[1]);
      const btn = document.createElement("button");
      btn.appendChild(docName);
      btn.classList.add("btn");
      btn.setAttribute("doc-extention", doc[1]);
      mydiv.appendChild(btn);
    });
    .root {
      display: flex;
      flex-direction: column;
      align-items: baseline;
      gap: 1rem;
    }
    
    .btn {
      border: none;
      position: relative;
    }
    
    .btn,
    .btn::before {
      border-radius: 10px;
      padding: 0.2rem 1rem;
    }
    
    .btn::before {
      position: absolute;
      content: attr(doc-extention);
      left: calc(100% - 1rem);
      top: 0;
      background-color: #00000050;
      z-index: -1;
    }
    <div class='root'></div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search