The best way I can think of is to suppress the padding of default arrow and include a custom one. The reason is you are trying to change the default layout of the MenuButton which is out of control to handle it through CSS changes.
So the general idea is as follows:
- Set the padding of default arrow pane and arrow to 0.
- Build the custom MenuButton that has a custom graphic to mimic the required layout.
Please check the below demo:

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Label;
import javafx.scene.control.MenuButton;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class MenuButtonArrowDemo extends Application {
@Override
public void start(Stage stage) {
MenuButton button1 = new MenuButton("First");
Circle graphic = new Circle(5);
graphic.setStyle("-fx-fill:red");
button1.setGraphic(graphic);
button1.setContentDisplay(ContentDisplay.TOP);
MenuItem f1 = new MenuItem("First Sub Item");
button1.getItems().add(f1);
Circle dot = new Circle(5);
dot.setStyle("-fx-fill:red");
MenuButton button2 = new CustomMenuButton("First", dot);
MenuItem f2 = new MenuItem("First Sub Item");
button2.getItems().add(f2);
HBox hbox = new HBox(button1, button2);
hbox.setPadding(new Insets(10));
hbox.setSpacing(10);
BorderPane root = new BorderPane();
root.setTop(hbox);
Scene scene = new Scene(root, 350, 200);
stage.setScene(scene);
stage.setTitle("MenuButton Arrow");
stage.show();
}
class CustomMenuButton extends MenuButton {
StackPane graphicContainer = new StackPane();
Label label = new Label();
public CustomMenuButton(String text) {
label.setText(text);
init();
}
public CustomMenuButton(String text, Node graphic) {
label.setText(text);
graphicContainer.getChildren().add(graphic);
init();
}
private void init() {
getStyleClass().add("custom-menu-button"); // to control the styling from css file
StackPane myArrow = new StackPane();
// You can set this styling in css file
myArrow.setStyle("-fx-background-color: -fx-mark-highlight-color, -fx-mark-color;-fx-background-insets: 0 0 -1 0, 0;-fx-padding: 2px 4px 2px 4px;-fx-shape: \"M 0 0 h 7 l -3.5 4 z\"");
StackPane arrowPane = new StackPane(new Group(myArrow));
arrowPane.setPadding(new Insets(0, 6, 4, 6));
VBox buttonGraphic = new VBox(graphicContainer, label, arrowPane);
buttonGraphic.setAlignment(Pos.CENTER);
buttonGraphic.setSpacing(5);
setGraphic(buttonGraphic);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
@Override
protected void layoutChildren() {
super.layoutChildren();
// You can set this styling in css file
lookup(".arrow-button").setStyle("-fx-padding:0px;");
lookup(".arrow").setStyle("-fx-padding:0px;");
}
}
}