tatsu
tatsu

Reputation: 2536

Material 2 Buttons Css styling Angular 5

enter image description here

I've got a pretty satisfactory use of material2's buttons in my Angular 5 project.

I'm having trouble with styling a button which is meant to be with 90° rotated text.

to do things cleanly I'm rotating the inner div containing the text rather than the whole outer one.

My issue is that the hover and ripple of material2's buttons rather take the original text's width than that of the outer button div.

I'm fine with having to "hack" it into submission, I've already done this for the text but I can't manage to select or influence mat-button-focus-overlay or mat-button-ripple.

plus this starts to get more hacky if I want that button on the right-side screen edge :

enter image description here

am I approaching this the wrong way?

html :

<button class="my-button with-round-borders" mat-button>
  <div class="inner-text">
    Valider
  </div>
</button>
<button class="curvy-button-left absolute-postition" mat-button>
  <div class="inner-text rotate-left rectify-inner-text">
    Filtres
  </div>
</button>

css :

  .my-button{
    margin: 2px 0 0 18px;
    width: 160px;
    line-height: 38px;
    border: 1px solid $transparent;
    background-color: $col;
    color: white;
    &:focus{
      outline: none;
    }
  }
.absolute-postition{
  position: absolute;
  top: 70px;
  height: 160px;
}
.rectify-inner-text{
  margin-left: -61px;
}
  .inner-text{
    @extend %ellipsis;
    color: white;
  }
  .with-round-borders{
    border-radius: 50px;
  }
  .rotate-left {
    display:inline-block;
    filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
    -webkit-transform: rotate(270deg);
    -ms-transform: rotate(270deg);
    transform: rotate(270deg);
  }
  .curvy-button-left{
    background-image:
      radial-gradient(circle at bottom right,transparent 50%, $col 55%),
      radial-gradient(circle at bottom left,$col 50%,transparent 55%),
      radial-gradient(circle at top left,$col 50%,transparent 55%),
      radial-gradient(circle at top right,transparent 50%,$col 55%),
      linear-gradient($col,$col),
      linear-gradient($col,$col);
    background-position:0 150px,20px 10px,20px 140px,0 0,0px 10px,20px 20px;
    background-size:16px 10px,16px 10px,16px 10px,16px 10px,20px 140px,10px 120px;
    background-repeat:no-repeat;
  }

Upvotes: 0

Views: 3277

Answers (1)

tatsu
tatsu

Reputation: 2536

I managed to solve this riddle within the confines of my satisfaction with unscoped styling.

Unscoped Styling is where you access a component that isn't your own's style (https://angular.io/guide/component-styles) :

.special{
  ::ng-deep .mat-button-ripple, ::ng-deep .mat-button-focus-overlay{
    width: 36px !important;
    height: 160px !important;
  }
}

thicker than 36px led to overflow onto the "other side" or "other page" as these two buttons are back to back. thinner than 36px led to offset from viewport border.

::ng-deep is what allows unscoping.

🚨 Careful with this 🚨

Notice I wrapped this within my own class name so as to only unscope within the context of that perticular div barring that classname and nothing other (no higher, for example) :

  <button class="curvy-button-left absolute-postition special" mat-button>
    <div class="inner-text rotate-left rectify-inner-text">Filtres</div>
  </button>

Notice the special class added there. this is how I use ::ng-deep in a controlled manner.

for the button that must allign with the right screen edge the hacks are more numerous :

.rectify-inner-text{
  height: 48px;
  margin-right: 12px;
  color: white;
}

.absolute-postition{
  position: absolute;
  top: 70px;
  height: 160px;
  right: -52px;
}

don't forget :

outline: 0 !important;

which deals with removing the added selection border once clicked. this must be placed at the same level as the button element.

The result is as follows :

enter image description hereenter image description here

I tried setting the background shape as I had done with the button but that was simply ignored.

I expected as much I'm guessing the ripple and color we see are filled via js not via css. which is why it will be overridden.

Upvotes: 1

Related Questions