Issue styling multi date event in a calendar with

2019-07-26 16:26发布

问题:

I'm trying to build a calendar in SCSS and HTML, similar to this:

I'm trying to make a nice representation for events that span multiple days. You can see that I am using the class .long-event on dates that are part of a multi date event. The problem is, I can't seem to round off the ends properly. In my example dates 1st - 3rd and 14th - 18th are selected as long events, but the 1st doesn't have the rounded end, nor does the 3rd (but the 4th does) and the 14th does (which is correct) but the 18th doesn't (and again the next day does which is wrong) Below is an example of what I've done:

HTML:

<div id="calendar">
  <div class="date long-event">
    <p>01</p>
  </div>
  <div class="date long-event">
    <p>02</p>
  </div>
  <div class="date long-event">
    <p>03</p>
  </div>
  <div class="date">
    <p>04</p>
  </div>
  <div class="date">
    <p>05</p>
  </div>
  <div class="date">
    <p>06</p>
  </div>
  <div class="date">
    <p>07</p>
  </div>
  <div class="date">
    <p>08</p>
  </div>
  <div class="date">
    <p>09</p>
  </div>
  <div class="date">
    <p>10</p>
  </div>
  <div class="date">
    <p>11</p>
  </div>
  <div class="date">
    <p>12</p>
  </div>
  <div class="date">
    <p>13</p>
  </div>
  <div class="date long-event">
    <p>14</p>
  </div>
  <div class="date long-event">
    <p>15</p>
  </div>
  <div class="date long-event">
    <p>16</p>
  </div>
  <div class="date long-event">
    <p>17</p>
  </div>
  <div class="date long-event">
    <p>18</p>
  </div>
  <div class="date">
    <p>19</p>
  </div>
  <div class="date">
    <p>20</p>
  </div>
  <div class="date">
    <p>21</p>
  </div>
  <div class="date">
    <p>22</p>
  </div>
  <div class="date">
    <p>23</p>
  </div>
  <div class="date">
    <p>24</p>
  </div>
  <div class="date">
    <p>25</p>
  </div>
  <div class="date">
    <p>26</p>
  </div>
  <div class="date">
    <p>27</p>
  </div>
  <div class="date">
    <p>28</p>
  </div>
  <div class="date">
    <p>29</p>
  </div>
  <div class="date">
    <p>30</p>
  </div>
</div>

SCSS:

* {
  box-sizing: border-box;
}

#calendar {
  width: 300px;
  display: table;

  .date {
    display: inline-block;
    /* background: wheat; */
    padding: 10px;
    margin: 0;

    p {
      margin: 0;
      padding: 0;
    }
  }

  .long-event {
    background: orange;
  }

  // First date in range
  :not(.long-event) + .long-event {
    background: orange;
    border-radius: 50% 0 0 50%;
  }

  // Last date in range
  .long-event + :not(.long-event) {
    background: red;
    border-radius: 0 50% 50% 0;
  }
}

And a jsFiddle of what I've done:

https://jsfiddle.net/k0112tbd/6/

Any help would be appreciated, especially if you know a better way of doing this. Using the plugin that I plan to use, I cannot add any additional classes to the beginning of the event or the end, so I need something clever :)

Andy

回答1:

Unfortunately until previous sibling selectors are introduced in CSS this won't be possible. For now your most reliable option is jQuery.

Using jQuery you can add a class to each of the last days in the .long-event series.

The following will add a class of .last to the last day in each .long-event series:

$('.long-event + .date:not(.long-event)').prev().addClass('last');

which can then be styled using the CSS you already had (with a new selector):

.last {
  background: red;
  border-radius: 0 50% 50% 0;
}

For the second issue, targeting the first .long-event, you can add an additional selector:

:not(.long-event) + .long-event,
.long-event:first-child {
  background: orange;
  border-radius: 50% 0 0 50%;
}

The important part there is the .long-event:first-child, which will always apply the rounded corners to the first .long-event in the calendar.

If you wanted to stick with jQuery for the first day in each .long_event:

$(':not(.long-event) + .long-event, .long-event:first-child').addClass('first');

then:

.first {
  background: orange;
  border-radius: 50% 0 0 50%;
}

Here's a jsFiddle.