CSS: Permit child margin to overlap parent padding, but force child siblings to respect child margin

Viewed 22

I have a parent div with some hefty padding. My first child element is an image, which requires a minimum margin for licensing purposes. If I add margin all around the image, it pushes away the padding of the parent (moving the image to the right and growing the parent vertically to accommodate), which isn't right

The padding of the parent is more than the necessary margin for the image, so it sounds like a simple fix - make the image height the same as a row of text (to get it as large as possible without expanding the parent) and just apply margin to the right side.

However, sometimes the text wraps around to a new line, and then there's no bottom margin to protect the image from encroachment by the text. The second example below has no bottom margin. The third example has bottom margin - it moves the text down 3/4 the margin (6px) and moves the image up 1/4 of the margin (2px). I'm not sure why the image is 2 pixels low in the first 2, but I can't make it any larger without growing the parent.

How can I add margin to the image, and tell it that the child margin and parent padding can overlap, but the child margin can't overlap with its siblings?

  • The parent is defined by Bootstrap, so I don't want to alter the parent class much.
  • Besides, most items won't have images, and so it makes more sense to just use CSS to tweak the image parent (if needed).
    • I could also use jQuery, but would perfer a CSS only solution. (Part of the point of the question is for me to learn CSS better.)
  • The question is independent of Bootstrap though - I could have produced a vanilla example, but I was already familiar with the dimensions/elements I was working with and it was faster to produce an example with Bootstraps.

enter image description here

.accordion {
  width: 300px;
}

.accordion-button {
  font-weight: 500;
}

a.accordion-button {
  text-decoration: initial;
  display: block;
}

.my-img {
  height: 1.5em;
}

#margin1,
#margin2,
#margin3{
  position: fixed;
  left: 13px;
  z-index: 10;
}

#margin1 {
  top: 11px;
}

#margin2 {
  top: 70px;
}

#margin3 {
  top: 151px;
}

#button-padding1,
#button-padding2,
#button-padding3 {
  position: fixed;
  left: 1px;
  z-index: 15;
}

#button-padding1 {
  top: 1px;
}

#button-padding2 {
  top: 60px;
}

#button-padding3 {
  top: 143px;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js"></script>


<div class="accordion" id="MiddleAccordion">
  <div class="accordion-item">
    <span class="accordion-header" id="heading-01">
      <a class="accordion-button collapsed" type="button" href="#">
          <svg class="my-img me-2" viewBox="0 0 27 24" fill="black">
            <polygon points="0,0 27,0 27,24 0,24"/>
          </svg>
        Some short text
      </a>
    </span>
  </div>
  <div class="accordion-item">
    <span class="accordion-header" id="heading-02">
      <a class="accordion-button collapsed" type="button" href="#">
          <svg class="my-img me-2" viewBox="0 0 27 24" fill="black">
            <polygon points="0,0 27,0 27,24 0,24"/>
          </svg>
        Some longer text that wraps AROUND
      </a>
    </span>
  </div>
  <div class="accordion-item">
    <span class="accordion-header" id="heading-02">
      <a class="accordion-button collapsed" type="button" href="#">
          <svg class="my-img me-2 mb-2" viewBox="0 0 27 24" fill="black">
            <polygon points="0,0 27,0 27,24 0,24"/>
          </svg>
        Some longer text that wraps AROUND
      </a>
    </span>
  </div>
</div>


<svg id="margin1" viewBox="-8 -8 43 40" width="43">
  <polygon fill="none" stroke="black" stroke-dasharray="3,3" points="-8,-8 35,-8 35,32 -8,32"/>
  <!-- For alignment
  <polygon fill="white" points="0,0 27,0 27,24 0,24"/> -->
</svg>
<svg id="margin2" viewBox="-8 -8 43 40" width="43">
  <polygon fill="none" stroke="black"  stroke-dasharray="3,3" points="-8,-8 35,-8 35,32 -8,32"/>
  <!-- For alignment
  <polygon fill="white" points="0,0 27,0 27,24 0,24"/> -->
</svg>
<svg id="margin3" viewBox="-8 -8 43 40" width="43">
  <polygon fill="none" stroke="black"  stroke-dasharray="3,3" points="-8,-8 35,-8 35,32 -8,32"/>
  <!-- For alignment
  <polygon fill="white" points="0,0 27,0 27,24 0,24"/> -->
</svg>
<svg id="button-padding1" viewBox="0 0 298 58" width="298">
  <path fill="rgba(120,173,223,.7)" d="M 20 16 l 258 0 l 0 26 l -258 0 z" />
  <path fill="rgba(170,208,153,.7)" d="M 20 0 l 278 0 l 0 58 l -298 0 l 0 -58 l 20 0 l 0 42 l 258 0 l 0 -26 l -258 0 z" />
</svg>
<svg id="button-padding2" viewBox="0 0 298 82" width="298">
  <path fill="rgba(120,173,223,.7)" d="M 20 16 l 258 0 l 0 50 l -258 0 z" />
  <path fill="rgba(170,208,153,.7)" d="M 20 0 l 278 0 l 0 82 l -298 0 l 0 -82 l 20 0 l 0 66 l 258 0 l 0 -50 l -258 0 z" />
</svg>
<svg id="button-padding3" viewBox="0 0 298 88" width="298">
  <path fill="rgba(120,173,223,.7)" d="M 20 16 l 258 0 l 0 56 l -258 0 z" />
  <path fill="rgba(170,208,153,.7)" d="M 20 0 l 278 0 l 0 88 l -298 0 l 0 -88 l 20 0 l 0 72 l 258 0 l 0 -56 l -258 0 z" />
</svg>

0 Answers
Related