Meek
Meek

Reputation: 3362

How to make ul list items with pseudo elements stay inside the unordered list?

I have a unordered list with a list of items styled as tags. See jsFiddle. But when the tags break into two lines, the arrow of the tags overflows the left side of the ul. How can I avoid this?

.searchtags {
  padding: 0;
  margin: 15px 0 5px 0;
  list-style-type: none;
  font-family: arial;
  border: 1px solid red;
  width:300px;
}

.searchtags li:not(.filterheader) {
  position: relative;
  white-space: nowrap;
  float: left;
  width: auto;
  height: 26px;
  font-size: 12px;
  margin: 5px 15px 0 0;
  padding: 3px 6px 3px 15px;
  background: #fff;
  color: #4a4949;
  border-radius: 2px;
  border: 1px solid #cacaca;
}

.searchtags li:not(.filterheader):before,
.searchtags li:not(.filterheader):after {
  position: absolute;
  content: '';
}

.searchtags li:not(.filterheader):before {
  /* the circle on the left */
  height: 6px;
  width: 6px;
  border-radius: 50%;
  background-color: #fff;
  border: 1px solid #aaa;
  left: 2px;
<ul class="searchtags clearfix">
  <li class="filterheader">
    <strong>Tags:</strong></li>
  <li><a href="#">Tag</a><span aria-hidden="true" class="right" title="Delete">×</span></li>
  <li><a href="#">Long tag</a><span aria-hidden="true" class="right" title="Delete">×</span></li>
  <li><a href="#">Tag</a><span aria-hidden="true" class="right" title="Delete">×</span></li>
  <li><a href="#">Tag</a><span aria-hidden="true" class="right" title="Delete">×</span></li>
  <li><a href="#">Long tag</a><span aria-hidden="true" class="right" title="Delete">×</span></li>
</ul>

Thanks for your help in advance.

Upvotes: 2

Views: 851

Answers (4)

zer00ne
zer00ne

Reputation: 43990

  • Add padding to .searchtags,
  • changed <ul> to <dl>,
  • changed .filterheader to a <dt>,
  • and changed <li> to <dd>. With those changes in place :not(.filterheader) is no longer needed.
  • All <dd> and <dt> are display:inline-block

SNIPPET

.searchtags {
  /* Changed */
  padding: 0 0 5px 20px;
  margin: 15px 0 5px 0;
  list-style-type: none;
  font-family: arial;
  border: 1px solid red;
  width: 300px;
}
dt.filterheader {
  /* float:left removed */
  /* Added */
  display: inline-block;
  margin-right: 15px;
  position: relative;
}
.clearfix:before,
.clearfix:after {
  content: "";
  display: table;
  clear: both;
}
* {
  box-sizing: border-box;
}
dd {
  position: relative;
  white-space: nowrap;
  height: 26px;
  font-size: 12px;
  margin: 5px 15px 0 0;
  padding: 3px 6px 3px 15px;
  background: #fff;
  color: #4a4949;
  border-radius: 2px;
  border: 1px solid #cacaca;
  /* Added */
  display: inline-block;
}
dd:before,
dd:after {
  position: absolute;
  content: '';
}
dd:before {
  /* the circle on the left */
  height: 6px;
  width: 6px;
  border-radius: 50%;
  background-color: #fff;
  border: 1px solid #aaa;
  left: 2px;
  top: 9px;
  z-index: 2;
}
dd:after {
  /* the arrow on left side positioned using left property */
  height: 18px;
  width: 18px;
  -webkit-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  -o-transform: rotate(45deg);
  transform: rotate(45deg);
  background: #fff;
  border-color: transparent transparent #cacaca #cacaca;
  border-width: 1px;
  border-style: solid;
  left: -9px;
  top: 3px;
}
dd a,
dd a:hover {
  color: #4a4949;
  font-weight: normal;
}
dd.right {
  /* the x mark at the right */
  text-align: right;
  margin: 0px 2px 0 4px;
  font-size: 15px;
  cursor: pointer;
}
<dl class="searchtags clearfix">
  <dt class="filterheader">
    <strong>Tags:</strong></dt>
  <dd><a href="#">Tag</a><span aria-hidden="true" class="right" title="Delete">×</span>
  </dd>
  <dd><a href="#">Long tag</a><span aria-hidden="true" class="right" title="Delete">×</span>
  </dd>
  <dd><a href="#">Tag</a><span aria-hidden="true" class="right" title="Delete">×</span>
  </dd>
  <dd><a href="#">Tag</a><span aria-hidden="true" class="right" title="Delete">×</span>
  </dd>
  <dd><a href="#">Long tag</a><span aria-hidden="true" class="right" title="Delete">×</span>
  </dd>
</dl>

Upvotes: 0

Sanzhar Kozhay
Sanzhar Kozhay

Reputation: 11

You are using position:absolute, so those arrows don't interact with anything outside of the position:relative positioned element.
The first line doesn't have that problem because the first <li> has a non-zero margin-right. So just add margin-left.
If you want it to look exactly the same but the first of the line not overflowing then set the <li> to margin-right: 0; margin-left: whatever. Also set .filterheader {margin-right:0}.

Upvotes: 0

user3771102
user3771102

Reputation: 558

You can achieve that by adding padding-left to the .searchtags and then a negative margin for the .filterheader so that only the 2nd row will be affected. Its like indenting a paragraph.

.searchtags {
  padding: 0;
  margin: 15px 0 5px 0px;
  list-style-type: none;
  font-family: arial;
  border: 1px solid red;
  width:300px;
  padding-left:15px;
}

.searchtags li:not(.filterheader) {
  position: relative;
  white-space: nowrap;
  float: left;
  width: auto;
  height: 26px;
  font-size: 12px;
  margin: 5px 15px 0 0;
  padding: 3px 6px 3px 15px;
  background: #fff;
  color: #4a4949;
  border-radius: 2px;
  border: 1px solid #cacaca;
}

.searchtags li:not(.filterheader):before,
.searchtags li:not(.filterheader):after {
  position: absolute;
  content: '';
}

.searchtags li:not(.filterheader):before {
  /* the circle on the left */
  height: 6px;
  width: 6px;
  border-radius: 50%;
  background-color: #fff;
  border: 1px solid #aaa;
  left: 2px;
  top: 9px;
  z-index: 2;
}

.searchtags li:not(.clearfilters):not(.filterheader):after {
  /* the arrow on left side positioned using left property */
  height: 18px;
  width: 18px;
  -webkit-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  -o-transform: rotate(45deg);
  transform: rotate(45deg);
  background: #fff;
  border-color: transparent transparent #cacaca #cacaca;
  border-width: 1px;
  border-style: solid;
  left: -9px;
  top: 3px;
}

.searchtags li:not(.clearfilters):not(.filterheader) a,
.searchtags li:not(.clearfilters):not(.filterheader) a:hover {
  color: #4a4949;
  font-weight: normal;
}

.searchtags li:not(.clearfilters):not(.filterheader) .right {
  /* the x mark at the right */
  text-align: right;
  margin: 0px 2px 0 4px;
  font-size: 15px;
  cursor: pointer;
}

.searchtags .filterheader {
  float: left;
  margin-right: 15px;
  padding-left:-15px;
}

.clearfix:before,
.clearfix:after {
  content: "";
  display: table;
  clear: both;
}

* {
  box-sizing: border-box;
}
<ul class="searchtags clearfix">
  <li class="filterheader">
    <strong>Tags:</strong></li>
  <li><a href="#">Tag</a><span aria-hidden="true" class="right" title="Delete">×</span></li>
  <li><a href="#">Long tag</a><span aria-hidden="true" class="right" title="Delete">×</span></li>
  <li><a href="#">Tag</a><span aria-hidden="true" class="right" title="Delete">×</span></li>
  <li><a href="#">Tag</a><span aria-hidden="true" class="right" title="Delete">×</span></li>
  <li><a href="#">Long tag</a><span aria-hidden="true" class="right" title="Delete">×</span></li>
</ul>

Upvotes: 0

dommmm
dommmm

Reputation: 908

Add enough margin so that the psuedo element is wrapped within the elements boundaries:

margin-left

.searchtags li:not(.filterheader) {
    margin-left: 12px;
}

Upvotes: 1

Related Questions