Horrie
Horrie

Reputation: 13

Can I create a shape in CSS (a pencil) without it acting weirdly when I try to rotate it?

I'm trying to create an image that looks like a pencil in CSS, which I think I've done OK, but it acts weirdly when I try to rotate it with "transform: rotate(-45deg);". I thought it would just rotate on an axis somewhere inside the original image, but it not only rotates the pencil, it also moves it a long way from its original position in a huge arc, which makes me think that the axis point is no longer inside the original image. (Just uncomment the "transform" rule at the end of the block of CSS included here to see what I mean.) And if you use a positive value – like 45deg – it rotates entirely off the page and you can't see the pencil.

I also tried to create various parts of the pencil using ::before and ::after pseudo elements, but then it rotated the main element but left the pseudo elements behind.

You can see it at enter code herehttps://codepen.io/HorrieGrump/pen/GRmvJbV

This is my first-ever post, so pls forgive me if I've breached any rule (and reprimand politely). Thanks

<section class="pencil">
  <div class="cap"></div>
  <div class="tube"></div>
  <div class="space"></div>
  <div class="triangle"></div>
</section>



body {
  background: antiquewhite;
}

/**********************   FIRST PENCIL         *********************/

/* This is the ROUNDED SEMICIRCLE on top of the body of the pencil*/

.cap {
  height: 20px;
  width: 40px;
  border-top-left-radius: 40px;
  border-top-right-radius: 40px;
  background-color: gray;
}

/* This is the BODY of the pencil*/

.tube {
  height: 100px;
  width: 40px;
  background-color: gray;
  margin-top: -1px;
}

/* This is the "empty" SPACE between body of the pencil and the tip of the pencil*/
.space {
  height: 20px;
  width: 40px;
  border-top-left-radius: 40px;
  border-top-right-radius: 40px;
  background-color: antiquewhite;
  margin-top: -8px;
}


/* This is the TIP of the pencil*/
.triangle {
  width: 0;
  height: 0;
  border-left: 25px solid transparent;
  border-right: 25px solid transparent;
  border-top: 40px solid gray;
  border-radius: 50%;
  margin-left: -6px;
}

/* This is a container to group all the parts of the pencil*/
section.pencil {
  margin-top: 8rem;
  margin-bottom: 17rem;
/*  transform: rotate(-45deg);*/
}

Upvotes: 1

Views: 237

Answers (2)

UModeL
UModeL

Reputation: 1227

Since <section> is a block element by default, it stretches to the full available width of the parent (see the yellow background in the example).

To make the container fit the content, you need to: make it inline-block (property display: inline-block) or add the property width: min-content.

I think you also want the pen to revolve not around the center, but around its tip. Just add transform-origin: center bottom.

body { background: antiquewhite; }

/**********************   FIRST PENCIL         *********************/

/* This is the ROUNDED SEMICIRCLE on top of the body of the pencil*/
.cap {
  height: 20px;
  width: 40px;
  border-top-left-radius: 40px;
  border-top-right-radius: 40px;
  background-color: gray;
}

/* This is the BODY of the pencil*/
.tube {
  height: 100px;
  width: 40px;
  background-color: gray;
  margin-top: -1px;
}

/* This is the "empty" SPACE between body of the pencil and the tip of the pencil*/
.space {
  height: 20px;
  width: 40px;
  border-top-left-radius: 40px;
  border-top-right-radius: 40px;
  background-color: antiquewhite;
  margin-top: -8px;
}

/* This is the TIP of the pencil*/
.triangle {
  width: 0;
  height: 0;
  border-left: 25px solid transparent;
  border-right: 25px solid transparent;
  border-top: 40px solid gray;
  border-radius: 50%;
  margin-left: -6px;
}

/* This is a container to group all the parts of the pencil*/
section.pencil {
  margin-top: 8rem;
  margin-bottom: 17rem;
  
  background-color: #fa08;
  transition: 1s ease;
}
section.pencil:hover { transform: rotate(45deg); }

/* Only for example */ input,label{position:fixed}label:nth-of-type(1){top:10px;left:10px}label:nth-of-type(2){top:10px;left:200px}label:nth-of-type(3){top:30px;left:35px}label:nth-of-type(4){top:30px;left:225px}input:nth-of-type(1){top:10px;left:160px}input:nth-of-type(2){top:10px;left:280px}input:nth-of-type(3){top:30px;left:10px}input:nth-of-type(4){top:30px;left:200px}#d-ib:checked~section.pencil{display:inline-block}#w-mc:checked~section.pencil{width:min-content}#to:checked~section.pencil{transform-origin:50% 100%}
<label for="d-b">display: block (default)</label><input type="radio" name="display" id="d-b" checked><label for="d-ib">inline-block</label><input type="radio" name="display" id="d-ib"><input type="checkbox" id="w-mc"><label for="w-mc">width: min-content</label><input type="checkbox" id="to"><label for="to">transform-origin: 50% 100% (default = 50% 50%)</label>

<section class="pencil">
  <div class="cap"></div>
  <div class="tube"></div>
  <div class="space"></div>
  <div class="triangle"></div>
</section>

Upvotes: 0

A Haworth
A Haworth

Reputation: 36426

Try looking at your section element - it groups the bits of the pencil together fine, but give it a background color and you'll see something like this:

enter image description here

However, give it for example display: inline-block and it will have the width you expect (i.e. defined by the pencil). Now when you rotate it it does what you expect (the transform-origin defaults to center).

body {
  background: antiquewhite;
}

/**********************   FIRST PENCIL         *********************/

/* This is the ROUNDED SEMICIRCLE on top of the body of the pencil*/

.cap {
  height: 20px;
  width: 40px;
  border-top-left-radius: 40px;
  border-top-right-radius: 40px;
  background-color: gray;
}

/* This is the BODY of the pencil*/

.tube {
  height: 100px;
  width: 40px;
  background-color: gray;
  margin-top: -1px;
}

/* This is the "empty" SPACE between body of the pencil and the tip of the pencil*/
.space {
  height: 20px;
  width: 40px;
  border-top-left-radius: 40px;
  border-top-right-radius: 40px;
  background-color: antiquewhite;
  margin-top: -8px;
}


/* This is the TIP of the pencil*/
.triangle {
  width: 0;
  height: 0;
  border-left: 25px solid transparent;
  border-right: 25px solid transparent;
  border-top: 40px solid gray;
  border-radius: 50%;
  margin-left: -6px;
}

/* This is a container to group all the parts of the pencil*/
section.pencil {
  background-color: pink;
  margin-top: 8rem;
  margin-bottom: 17rem;
  display: inline-block;
  transform: rotate(-45deg);
}
<section class="pencil">
  <div class="cap"></div>
  <div class="tube"></div>
  <div class="space"></div>
  <div class="triangle"></div>
</section>

<!-- <section class="pencil-2">
  <div class="cap-2"></div>
  <div class="tube-2"></div>
  <div class="space-2"></div>
  <div class="triangle-2"></div>
</section> -->

Upvotes: 1

Related Questions